Skip to content

Commit

Permalink
fix(color): add portal to color picker
Browse files Browse the repository at this point in the history
  • Loading branch information
WilliamTraoreee committed Sep 10, 2022
1 parent 4057459 commit f53efca
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,49 +5,62 @@ import { HsvaColor } from '@uiw/color-convert';
import { Tabs } from './tabs';
import { Pointer } from './pointer';
import { rgbaStringToHsva, color as colorResult } from '@uiw/color-convert';
import * as Portal from '@radix-ui/react-portal';

export interface ColorPickerProps {
color?: HsvaColor;
onChange: (value: string) => void;
className?: string;
top: number;
left: number;
}


export const ColorPicker = (props: ColorPickerProps) => {
const { color = rgbaStringToHsva('rgba(255,0,0,1)'), onChange, className } = props;
const {
color = rgbaStringToHsva('rgba(255,0,0,1)'),
onChange,
className,
top,
left,
} = props;
const [hsva, setHsva] = React.useState<HsvaColor>(color);

React.useEffect(() => {
React.useEffect(() => {
onChange(colorResult(hsva).hexa);
}, [hsva, onChange]);

//TODO: fix pointer position
}, [hsva, onChange]);

return (
<div className={`color-picker flex w-56 rounded-md bg-dark-500 border-dark-300 border-2 box-border ${className}`}>
<Hue
hue={hsva.h}
onChange={(newHue) => {
setHsva({ ...hsva, ...newHue });
}}
pointer={Pointer}
radius="4px 0 0 4px"
direction="vertical"
width="6px"
height="320px"
/>
<div className="flex flex-col gap-4" style={{ width: '214px' }}>
<Saturation
hsva={hsva}
onChange={(newColor) => setHsva({ ...hsva, ...newColor, a: hsva.a })}
radius="0 4px 0 0"
style={{ height: '240px', width: '100%' }}
<Portal.Root
className="absolute z-50"
style={{ top: `${top + 70}px`, left }}
>
<div
className={`color-picker flex w-56 rounded-md bg-dark-500 border-dark-300 border-2 box-border ${className}`}
>
<Hue
hue={hsva.h}
onChange={(newHue) => {
setHsva({ ...hsva, ...newHue });
}}
pointer={Pointer}
radius="4px 0 0 4px"
direction="vertical"
width="6px"
height="320px"
/>
<Tabs color={hsva} onChange={(newColor) => setHsva(newColor)} />
<div className="flex flex-col gap-4" style={{ width: '214px' }}>
<Saturation
hsva={hsva}
onChange={(newColor) =>
setHsva({ ...hsva, ...newColor, a: hsva.a })
}
radius="0 4px 0 0"
style={{ height: '240px', width: '100%' }}
pointer={Pointer}
/>
<Tabs color={hsva} onChange={(newColor) => setHsva(newColor)} />
</div>
</div>
</div>
</Portal.Root>
);
};


21 changes: 16 additions & 5 deletions libs/shared/ui/src/lib/components/forms/color/color.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as React from 'react';
import { ColorResult, hexToHsva } from '@uiw/color-convert';
import { useState } from 'react';
import { hexToHsva } from '@uiw/color-convert';
import { useRef, useState } from 'react';
import Icon from '../../icon/icon';
import { InputState } from '../input/input';
import Label from '../label/label';
import { ColorPicker } from '../color-picker/color-picker';
import { useEffect } from 'react';

export interface ColorProps extends React.ComponentPropsWithoutRef<'input'> {
label?: string;
Expand All @@ -30,6 +31,9 @@ export function Color(props: ColorProps) {

const [val, setVal] = useState<string>(value || '#000000');
const [showPicker, setShowPicker] = useState<boolean>(false);
const input = useRef<HTMLLabelElement>(null);
const [top, setTop] = useState<number>(0);
const [left, setLeft] = useState<number>(0);

const stateClassName = {
[InputState.Normal]: '',
Expand Down Expand Up @@ -66,17 +70,24 @@ export function Color(props: ColorProps) {
};
};

useEffect(() => {
setTop(input.current?.offsetTop || 0);
setLeft(input.current?.offsetLeft || 0);
}, [input]);

return (
<label className={`relative block ${containerClassName}`}>
<label className={`relative block ${containerClassName}`} ref={input}>
{label && <Label className={labelClassName}>{label}</Label>}
<div
className={`h-10 w-full border-2 border-dark-300 text-sm text-white flex items-center gap-2 bg-dark-500 rounded-md px-4 outline-none focus:border-primary-300 transition ${stateClassName[state]} ${haveValueClassName} ${disabledClassName} ${inputProps.className}`}
{...inputProps}
>
{showPicker && (
{showPicker && input.current && (
<>
<ColorPicker
className="absolute z-10 top-[110%] left-0"
top={top}
left={left}
className=""
color={hexaToHsva(val)}
onChange={(e) => onChangePickerValue(e)}
/>
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@radix-ui/react-accordion": "^1.0.0",
"@radix-ui/react-dialog": "^1.0.0",
"@radix-ui/react-popover": "^1.0.0",
"@radix-ui/react-portal": "^1.0.0",
"@radix-ui/react-slider": "^1.0.0",
"@radix-ui/react-tabs": "^1.0.0",
"@radix-ui/react-tooltip": "^1.0.0",
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2523,7 +2523,7 @@
"@radix-ui/react-use-size" "1.0.0"
"@radix-ui/rect" "1.0.0"

"@radix-ui/react-portal@1.0.0":
"@radix-ui/react-portal@1.0.0", "@radix-ui/react-portal@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.0.tgz#7220b66743394fabb50c55cb32381395cc4a276b"
integrity sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==
Expand Down

0 comments on commit f53efca

Please sign in to comment.