Skip to content

Commit

Permalink
📦 NEW: color picker enhancment
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedrowaihi committed Jul 18, 2024
1 parent 62fe0c7 commit a78ee79
Show file tree
Hide file tree
Showing 4 changed files with 425 additions and 37 deletions.
2 changes: 2 additions & 0 deletions packages/tohuhono/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@
"@tailwindcss/typography": "^0.5.13",
"@tohuhono/dev": "workspace:*",
"@tohuhono/utils": "workspace:*",
"@uiw/react-color": "^2.3.0",
"@uiw/react-color-chrome": "^2.3.0",
"class-variance-authority": "^0.7.0",
"cmdk": "^1.0.0",
"date-fns": "^3.6.0",
Expand Down
42 changes: 42 additions & 0 deletions packages/tohuhono/ui/src/theme/color-picker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"use client"

import { PopoverContent } from "@radix-ui/react-popover"
import {
hslaToHsva,
hsvaToHex,
type ColorResult,
type HslColor,
} from "@uiw/react-color"
import ChromeColorPicker from "@uiw/react-color-chrome"
import { Popover, PopoverTrigger } from "../popover"

export const ColorPicker = ({
disabled,
color,
onColorChange,
}: {
disabled?: boolean
color: HslColor
onColorChange: (color: ColorResult) => void
}) => {
const hsva = hslaToHsva({ ...color, a: 1 })

return (
<Popover>
<PopoverTrigger disabled={disabled} asChild>
<button
className="my-1 size-6 flex-shrink-0 rounded border"
style={{ backgroundColor: hsvaToHex(hsva) }}
/>
</PopoverTrigger>
<PopoverContent className="isolate z-50">
<ChromeColorPicker
color={hsva}
onChange={onColorChange}
showHue={true}
showColorPreview={true}
/>
</PopoverContent>
</Popover>
)
}
74 changes: 37 additions & 37 deletions packages/tohuhono/ui/src/theme/theme-editor-menu.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
"use client"

import { ClipboardCopyIcon, MoonIcon, SunIcon } from "@radix-ui/react-icons"
import { useState, ChangeEvent, Fragment } from "react"
import { cn } from "@tohuhono/utils"
import { Input } from "../input"
import { Label } from "../label"
import { hslStringToHsla, type ColorResult } from "@uiw/react-color"
import { Fragment, useCallback, useState } from "react"
import { Button } from "../button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from "../dropdown-menu"
import { Button } from "../button"
import { ApplyTheme, copyToClipboard } from "./theme-editor"
import { Label } from "../label"
import { ColorPicker } from "./color-picker"
import { defaultTheme } from "./default-theme"
import { getMode, setMode } from "./mode-toggle"

import { ApplyTheme, copyToClipboard } from "./theme-editor"
export const ThemeEditorMenu = ({ className }: { className?: string }) => {
const [theme, setTheme] = useState(defaultTheme)

Expand All @@ -25,17 +25,22 @@ export const ThemeEditorMenu = ({ className }: { className?: string }) => {
setMode(mode)
}

const onInputChange =
(id: string, mode: "light" | "dark") =>
(event: ChangeEvent<HTMLInputElement>) =>
setTheme(
theme.map((t) => ({
...t,
...(t.id === id && {
[mode]: event.currentTarget.value,
}),
})),
const onInputChange = useCallback(
(id: string, mode: "light" | "dark") => (color: ColorResult) => {
setTheme((prev) =>
prev.map((item) => {
if (item.id === id) {
return {
...item,
[mode]: `${Math.round(color.hsl.h)} ${Math.round(color.hsl.s)}% ${Math.round(color.hsl.l)}%`,
}
}
return item
}),
)
},
[],
)

return (
<DropdownMenu>
Expand Down Expand Up @@ -83,27 +88,22 @@ export const ThemeEditorMenu = ({ className }: { className?: string }) => {
dark
</Button>

{theme.map(({ id, light, dark }) => {
return (
<Fragment key={id}>
<Label>{id}</Label>
<Input
className="border-0 px-2 py-0"
id={`${id}-light`}
size={15}
value={light || ""}
onChange={onInputChange(id, "light")}
/>
<Input
className="border-0 px-2 py-0"
id={`${id}-dark`}
value={dark || ""}
size={15}
onChange={onInputChange(id, "dark")}
/>
</Fragment>
)
})}
{theme.map(({ id, light, dark }) => (
<Fragment key={id}>
<Label>{id}</Label>

<ColorPicker
disabled={selectedMode === "system"}
color={hslStringToHsla(light)}
onColorChange={onInputChange(id, "light")}
/>
<ColorPicker
disabled={selectedMode === "system"}
color={hslStringToHsla(dark)}
onColorChange={onInputChange(id, "dark")}
/>
</Fragment>
))}
<Button
variant={"secondary"}
className="col-span-3 justify-self-center"
Expand Down
Loading

0 comments on commit a78ee79

Please sign in to comment.