Skip to content

Commit

Permalink
enhance(ColorPicker): include label and styling for color picker comp…
Browse files Browse the repository at this point in the history
…onent and formik wrapper (#130)
  • Loading branch information
sjschlapbach authored Aug 29, 2024
1 parent 27c8870 commit 222e58b
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 145 deletions.
18 changes: 18 additions & 0 deletions packages/design-system/src/ColorPicker.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ export const Default = () => {
)
}

export const Label = () => {
const [color, setColor] = useState('#0028A5')
return (
<ColorPicker
color={color}
onSubmit={(newColor) => {
setColor(newColor)
alert('Color set to ' + newColor)
}}
label="Color Picker"
tooltip="This is a tooltip"
colorLabel="Color"
submitText="Save"
required
/>
)
}

export const Disabled = () => {
const [color, setColor] = useState('#0028A5')
return (
Expand Down
218 changes: 133 additions & 85 deletions packages/design-system/src/ColorPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import { faPalette, IconDefinition } from '@fortawesome/free-solid-svg-icons'
import {
faCircleExclamation,
faPalette,
IconDefinition,
} from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { useEffect, useRef, useState } from 'react'
import { HexColorInput, HexColorPicker } from 'react-colorful'
import { twMerge } from 'tailwind-merge'
import Button from './Button'
import FormLabel from './FormLabel'
import Label from './forms/Label'
import { Tooltip } from './Tooltip'

export interface ColorPickerClassName {
root?: string
pickerRoot?: string
label?: string
tooltip?: string
trigger?: string
popover?: string
presetButtons?: string
Expand All @@ -20,14 +29,20 @@ export interface ColorPickerClassName {

export interface ColorPickerProps {
color: string
label?: string
labelType?: 'small' | 'large'
required?: boolean
onSubmit: (newColor: string) => void
disabled?: boolean
triggerIcon?: IconDefinition
presetColors?: string[]
position?: 'bottom' | 'top'
submitText: string
colorLabel: string
tooltip?: string
tooltip?: string | React.ReactNode
colorTooltip?: string
error?: string
isTouched?: boolean
dataTrigger?: {
cy?: string
test?: string
Expand Down Expand Up @@ -63,6 +78,9 @@ function useOutsideAlerter(elementRef: any, callback: () => void) {

export function ColorPicker({
color,
label,
labelType = 'small',
required = false,
onSubmit,
disabled,
triggerIcon,
Expand All @@ -71,6 +89,9 @@ export function ColorPicker({
submitText,
colorLabel,
tooltip,
colorTooltip,
error,
isTouched,
dataTrigger,
dataHexInput,
dataSubmit,
Expand All @@ -92,101 +113,128 @@ export function ColorPicker({
return (
<div
className={twMerge(
'align-center relative flex w-20 justify-end rounded-lg',
'flex w-full flex-row',
labelType === 'small' && 'flex-col',
className?.root
)}
style={{ backgroundColor: color ?? '#0028A5' }}
>
<Button
onClick={() => setColorPickerOpen(true)}
disabled={disabled}
data={dataTrigger}
className={{ root: className?.trigger }}
>
<FontAwesomeIcon icon={triggerIcon || faPalette} />
</Button>
{colorPickerOpen && (
{label && (
<FormLabel
required={required}
label={label}
labelType={labelType}
tooltip={tooltip}
className={className}
/>
)}
<div className="flex flex-row items-center gap-2">
<div
className={twMerge(
'absolute flex h-[10rem] w-[23rem] flex-row rounded-md bg-white p-1 shadow-md outline outline-2 outline-uzh-grey-40',
position === 'bottom' && 'left-10 top-8',
position === 'top' && 'bottom-8 left-10',
className?.popover
'align-center relative flex w-20 justify-end rounded-lg',
className?.pickerRoot
)}
ref={overlayRef}
style={{ backgroundColor: color ?? '#0028A5' }}
>
<HexColorPicker
style={{ width: '300px', height: '150px' }}
color={newColor}
onChange={setNewColor}
/>
<div className="grid grid-cols-1 justify-items-center gap-0.5 pl-2">
{PRESET_COURSE_COLORS.map((presetColor, index) => (
<Button
key={index}
className={{
root: twMerge(
'h-7 w-7 rounded-2xl border-none',
className?.presetButtons
),
}}
style={{ backgroundColor: presetColor }}
onClick={() => setNewColor(presetColor)}
/>
))}
</div>

<div className="ml-4 flex flex-col justify-between">
<div className="flex flex-col">
<Label
label={colorLabel}
className={{
root: twMerge(
'my-auto -mb-0.5 min-w-max text-base font-bold leading-6 text-gray-600',
className?.inputLabel
),
tooltip: twMerge(
'text-sm font-normal',
className?.inputTooltip
),
tooltipSymbol: 'h-2 w-2',
}}
tooltip={tooltip}
showTooltipSymbol={typeof tooltip !== 'undefined'}
/>
<HexColorInput
className={twMerge(
'focus:border-uzh-blue-50 h-9 w-24 rounded border border-uzh-grey-60 pl-2 placeholder-slate-400',
className?.input
)}
<Button
onClick={() => setColorPickerOpen(true)}
disabled={disabled}
data={dataTrigger}
className={{ root: className?.trigger }}
>
<FontAwesomeIcon icon={triggerIcon || faPalette} />
</Button>
{colorPickerOpen && (
<div
className={twMerge(
'absolute flex h-[10rem] w-[23rem] flex-row rounded-md bg-white p-1 shadow-md outline outline-2 outline-uzh-grey-40',
position === 'bottom' && 'left-10 top-8',
position === 'top' && 'bottom-8 left-10',
className?.popover
)}
ref={overlayRef}
>
<HexColorPicker
style={{ width: '300px', height: '150px' }}
color={newColor}
onChange={setNewColor}
data-cy={dataHexInput?.cy}
data-text={dataHexInput?.test}
/>
<div className="grid grid-cols-1 justify-items-center gap-0.5 pl-2">
{PRESET_COURSE_COLORS.map((presetColor, index) => (
<Button
key={index}
className={{
root: twMerge(
'h-7 w-7 rounded-2xl border-none',
className?.presetButtons
),
}}
style={{ backgroundColor: presetColor }}
onClick={() => setNewColor(presetColor)}
/>
))}
</div>

<div className="ml-4 flex flex-col justify-between">
<div className="flex flex-col">
<Label
label={colorLabel}
className={{
root: twMerge(
'my-auto -mb-0.5 min-w-max text-base font-bold leading-6 text-gray-600',
className?.inputLabel
),
tooltip: twMerge(
'text-sm font-normal',
className?.inputTooltip
),
tooltipSymbol: 'h-2 w-2',
}}
tooltip={colorTooltip}
showTooltipSymbol={typeof colorTooltip !== 'undefined'}
/>
<HexColorInput
className={twMerge(
'focus:border-uzh-blue-50 h-9 w-24 rounded border border-uzh-grey-60 pl-2 placeholder-slate-400',
className?.input
)}
color={newColor}
onChange={setNewColor}
data-cy={dataHexInput?.cy}
data-text={dataHexInput?.test}
/>
</div>
<Button
className={{
root: twMerge(
`float-right h-max w-full justify-center self-end bg-primary-80 text-white disabled:opacity-60`,
className?.submit
),
}}
type="submit"
onClick={(e) => {
e?.preventDefault()
e?.stopPropagation()
onSubmit(newColor)
setColorPickerOpen(false)
}}
disabled={color === newColor}
data={dataSubmit}
>
{submitText}
</Button>
</div>
</div>
<Button
className={{
root: twMerge(
`float-right h-max w-full justify-center self-end bg-primary-80 text-white disabled:opacity-60`,
className?.submit
),
}}
type="submit"
onClick={(e) => {
e?.preventDefault()
e?.stopPropagation()
onSubmit(newColor)
setColorPickerOpen(false)
}}
disabled={color === newColor}
data={dataSubmit}
>
{submitText}
</Button>
</div>
)}
</div>
)}
{error && isTouched && (
<Tooltip tooltip={error} delay={0} className={{ tooltip: 'text-sm' }}>
<FontAwesomeIcon
icon={faCircleExclamation}
className="mr-1 text-red-600"
/>
</Tooltip>
)}
</div>
</div>
)
}
Expand Down
Loading

0 comments on commit 222e58b

Please sign in to comment.