diff --git a/app/(components)/colors/page.tsx b/app/(components)/colors/page.tsx index 2763fdf..1933383 100644 --- a/app/(components)/colors/page.tsx +++ b/app/(components)/colors/page.tsx @@ -1,9 +1,8 @@ -import ColorScaleViewer from '@/components/colorsystem/color-scale-viewer' +import ColorSystemEditor from '@/components/colorsystem/color-system-editor' import PandaPresetRenderer from '@/components/colorsystem/panda-preset-renderer' import ContentSection from '@/components/layout/content-section' import Heading from '@/components/layout/heading' import Subtitle from '@/components/layout/subtitle' -import { geistColorsConfig } from '@/lib/colorsystem/config' export default async function () { const solidColors = ['shade', 'gray', 'blue', 'red', 'yellow', 'green', 'teal', 'purple', 'pink'] as const @@ -24,9 +23,7 @@ export default async function () { supported browsers and displays. Default color is at the 600 level.
- {Object.entries(geistColorsConfig).map(([name, colorConfig], i) => { - return - })} + Preset diff --git a/components/colorsystem/color-scale-viewer.tsx b/components/colorsystem/color-scale-viewer.tsx index 9207d69..d35a19b 100644 --- a/components/colorsystem/color-scale-viewer.tsx +++ b/components/colorsystem/color-scale-viewer.tsx @@ -2,16 +2,72 @@ import { monoFontClass } from '@/app/fonts' import { bfgColorLevelToAlias, colorLevelToAlias, colorLevels } from '@/lib/colorsystem/constants' +import { parseColor } from '@/lib/colorsystem/create-color' import type { ColorConfig, ColorLevel, ColorLevelAlias, ColorLevelBfg } from '@/lib/colorsystem/types' +import useDarkMode from '@/lib/hooks/use-darkmode' import { cn } from '@/lib/utils' import { css } from '@/styled-system/css' +import { Box, Stack, VStack } from '@/styled-system/jsx' +import { Popover } from '@ark-ui/react' import { useState } from 'react' import { useCopyToClipboard } from 'usehooks-ts' import Heading from '../layout/heading' +import { InlineTextButton } from '../ui/button' type ColorScaleViewerProps = { withLegend?: boolean colorConfig: ColorConfig + onHueChange?: (newHue: number, level: string, color: ColorConfig, isDarkMode: boolean) => void +} + +export const popoverCss = { + positioner: css({ + position: 'relative', + }), + content: css({ + minWidth: '360px', + borderWidth: '1px', + borderStyle: 'solid', + borderColor: 'gray.border1', + background: 'bg.base', + borderRadius: 'sm', + boxShadow: 'lg', + display: 'flex', + flexDirection: 'column', + maxWidth: 'sm', + zIndex: 'popover', + p: '4', + _open: { + animation: 'fadeIn 0.25s ease-out', + }, + _closed: { + animation: 'fadeOut 0.2s ease-out', + }, + _hidden: { + display: 'none', + }, + }), + title: css({ + fontWeight: 'medium', + textStyle: 'sm', + }), + description: css({ + color: 'fg.muted', + textStyle: 'sm', + }), + closeTrigger: css({ + color: 'fg.muted', + }), + arrow: css({ + '--arrow-size': 'var(--sizes-3)', + '--arrow-background': 'var(--colors-bg)', + zIndex: 'z1', + }), + arrowTip: css({ + borderTopWidth: '1px', + borderLeftWidth: '1px', + borderColor: 'gray.border1', + }), } const gridCss = css({ @@ -37,18 +93,95 @@ const gridCss = css({ fontSize: 'xxs', textAlign: 'center', }, - '& [data-level="600"], & [data-level="border3"]': { + '& [data-is-default], & [data-level="600"], & [data-level="border3"]': { fontWeight: 'black', fontSize: 'lg', borderRadius: 'sm', - borderWidth: '2px', + borderWidth: '1.5px', borderColor: 'fg.200', }, }) -function ColorCell({ level, colorConfig }: { colorConfig: ColorConfig; level?: ColorLevel | ColorLevelAlias }) { +type ColorEditorProps = { + isOpen: boolean + hue: number + onHueChange?: (newHue: number) => void + children: React.ReactNode + onClose?: () => void +} + +function ColorEditor({ onHueChange, onClose, isOpen, children, hue }: ColorEditorProps) { + if (!isOpen) { + return children + } + + return ( + { + if (!details.open) { + onClose?.() + } + }} + closeOnEscape={true} + closeOnInteractOutside={true} + > + {children} + + + + + + + OKCLH Color Editor + + + Hue + { + onHueChange?.(Number.parseFloat(e.target.value)) + }} + type="range" + min="0" + max="360" + defaultValue={hue ?? 0} + step="0.01" + /> + + + + + { + // console.log('close....') + onClose?.() + }} + > + + X + + + + + + + ) +} + +type ColorCellProps = { + colorConfig: ColorConfig + level?: ColorLevel | ColorLevelAlias + onHueChange?: (newHue: number, level: string, color: ColorConfig, isDarkMode: boolean) => void +} +function ColorCell({ level, colorConfig, onHueChange }: ColorCellProps) { const [copiedText, copyToClipboard] = useCopyToClipboard() + const [isEditorOpen, setIsEditorOpen] = useState(false) const [copied, setCopied] = useState(false) + const { isDarkMode } = useDarkMode() const isBgFg = ['bg', 'fg'].includes(colorConfig.type) const colorName = colorConfig.name @@ -57,16 +190,18 @@ function ColorCell({ level, colorConfig }: { colorConfig: ColorConfig; level?: C const levelAlias = (isBgFg ? bfgColorLevelToAlias[levelValue as ColorLevelBfg] : colorLevelToAlias[levelValue as ColorLevel]) ?? levelValue - const token = level ? `${colorName}.${levelAlias}` : colorName + const firstAlias = colorConfig.aliases.length > 0 ? colorConfig.aliases[0] : colorName + const token = level ? `${firstAlias}.${levelAlias}` : colorName const colorPreviewCssVars = { '--bg': colorConfig.light[levelValue]?.srgb, '--bg-p3': colorConfig.light[levelValue]?.oklch ?? colorConfig.light[levelValue]?.srgb, '--bg-dark': colorConfig.dark[levelValue]?.srgb, '--bg-dark-p3': colorConfig.dark[levelValue]?.oklch ?? colorConfig.dark[levelValue]?.srgb, - } as React.CSSProperties + } const showCopiedText = copied && copiedText === token - const handleCopy = (text: string) => () => { + const handleBtnClick = (text: string) => () => { + setIsEditorOpen(!isEditorOpen) copyToClipboard(text) .then(() => { setCopied(true) @@ -137,26 +272,64 @@ function ColorCell({ level, colorConfig }: { colorConfig: ColorConfig; level?: C monoFontClass, ) + const lightColorObj = parseColor( + colorConfig.light[levelValue]?.oklch ?? colorConfig.light[levelValue]?.srgb ?? 'transparent', + ) + + if (!lightColorObj) { + console.error('lightColorObj is undefined', { colorConfig }) + throw new Error('lightColorObj is undefined') + } + + const darkColorObj = parseColor( + colorConfig.dark[levelValue]?.oklch ?? colorConfig.dark[levelValue]?.srgb ?? 'transparent', + ) + + if (!darkColorObj) { + console.error('darkColorObj is undefined', { colorConfig }) + throw new Error('darkColorObj is undefined') + } + + const currentHue = isDarkMode ? darkColorObj.h : lightColorObj.h + return ( - + + ) } -export default function ColorScaleViewer({ colorConfig, withLegend }: ColorScaleViewerProps) { +export default function ColorScaleViewer({ colorConfig, onHueChange, withLegend }: ColorScaleViewerProps) { const aliasesLegend = withLegend ? (
{colorLevels.map((level) => ( -
+
{level}
))} @@ -178,7 +351,7 @@ export default function ColorScaleViewer({ colorConfig, withLegend }: ColorScale {/* */} {levelsSlice.map((level) => ( - + ))}
diff --git a/components/colorsystem/color-system-editor.tsx b/components/colorsystem/color-system-editor.tsx new file mode 100644 index 0000000..967acbd --- /dev/null +++ b/components/colorsystem/color-system-editor.tsx @@ -0,0 +1,39 @@ +'use client' + +import ColorScaleViewer from '@/components/colorsystem/color-scale-viewer' +import { generateColorSystemPresetCode } from '@/lib/colorsystem/generate-panda-preset' +import modifyPaletteHue from '@/lib/colorsystem/modify-palette-hue' +import { useAppState } from '@/lib/colorsystem/state' + +export default function ColorSystemEditor() { + const [appState, setAppState] = useAppState() + + return ( + <> + {Object.entries(appState.colorSystemConfig).map(([name, colorConfig], i) => { + if (colorConfig.name === 'blue') { + // console.log(colorConfig.modifiedAt) + } + return ( + { + // console.log({ newHue }) + const newColorSystemConfig = { + ...appState.colorSystemConfig, + [name]: modifyPaletteHue(newHue, colorConfig), + } + setAppState({ + ...appState, + colorSystemConfig: newColorSystemConfig, + colorSystemPresetCode: generateColorSystemPresetCode(newColorSystemConfig), + }) + }} + withLegend={i === 0} + key={name} + colorConfig={colorConfig} + /> + ) + })} + + ) +} diff --git a/components/colorsystem/panda-preset-renderer.tsx b/components/colorsystem/panda-preset-renderer.tsx index e58fc52..a307e47 100644 --- a/components/colorsystem/panda-preset-renderer.tsx +++ b/components/colorsystem/panda-preset-renderer.tsx @@ -1,10 +1,8 @@ 'use client' import { monoFontClass } from '@/app/fonts' -import { geistColorsConfig } from '@/lib/colorsystem/config' -import generatePandaPreset from '@/lib/colorsystem/generate-panda-preset' +import { useAppState } from '@/lib/colorsystem/state' import { css } from '@/styled-system/css' -import { outdent } from 'outdent' import { useState } from 'react' import { useCopyToClipboard } from 'usehooks-ts' import { PrimaryButtonSm } from '../ui/button' @@ -12,6 +10,7 @@ import { PrimaryButtonSm } from '../ui/button' export default function PandaPresetRenderer() { const [_, copyToClipboard] = useCopyToClipboard() const [copied, setCopied] = useState(false) + const [appState] = useAppState() const handleCopy = (text: string) => () => { copyToClipboard(text) @@ -26,27 +25,18 @@ export default function PandaPresetRenderer() { }) } - // TODO: pass colors from global state - const configSubset = generatePandaPreset(geistColorsConfig) - - const jsCode = outdent` - import { definePreset } from "@pandacss/dev"; - - export const colorSystemPreset = definePreset( - ${JSON.stringify(configSubset, null, 2)} - ); - ` - return ( <> - {copied ? 'Copied!' : 'Copy to clipboard'} + + {copied ? 'Copied!' : 'Copy to clipboard'} +
-
{jsCode}
+
{appState.colorSystemPresetCode}
) diff --git a/components/views/dark-mode-toggle.tsx b/components/views/dark-mode-toggle.tsx index 091253d..774047f 100644 --- a/components/views/dark-mode-toggle.tsx +++ b/components/views/dark-mode-toggle.tsx @@ -2,7 +2,7 @@ import useDarkMode from '@/lib/hooks/use-darkmode' import { css } from '@/styled-system/css' import { MoonStarIcon, SunIcon } from 'lucide-react' -import { InlineTextButton, type ButtonProps } from '../ui/button' +import { type ButtonProps, InlineTextButton } from '../ui/button' type DarkModeToggleProps = { defaultMode?: 'dark' | 'light' diff --git a/lib/colorsystem/create-color.ts b/lib/colorsystem/create-color.ts new file mode 100644 index 0000000..2dde2bc --- /dev/null +++ b/lib/colorsystem/create-color.ts @@ -0,0 +1,63 @@ +'use client' +import { type Color, converter, formatCss, formatRgb } from 'culori' + +// type ColorValues = [number, number, number] +// class ColorManipulator { +// public space: string +// public values: ColorValues +// public alpha: number + +// constructor (space: string, values: ColorValues, alpha: number) { +// this.space = space +// this.values = values +// this.alpha = alpha +// } + +// public toString () { +// switch (this.space) { +// case 'rgb': +// return `rgba(${this.values.join(', ')}, ${this.alpha})` +// case 'hsl': +// return `hsla(${this.values.join(', ')}, ${this.alpha})` +// case 'oklch': +// return `oklch(${this.values.join(', ')}, ${this.alpha})` +// case 'lch': +// return `lch(${this.values.join(', ')}, ${this.alpha})` +// default: +// throw new Error(`Cannot convert this color space: ${this.space}`) +// } +// } + +// public toOkString () { +// return this.space === 'rgb' ? this.toRgb().toOkString() : this.toHsl().toOkString() +// } +// } + +const oklchConverter = converter('oklch') + +export function parseColor(color: string) { + try { + const parsed = oklchConverter(color) + return parsed //new Color(parsed.space, parsed.values as [number, number, number], parsed.alpha) + } catch (error) { + throw new Error(`Color parsing failed for: ${color}, error: ${error}`) + } +} + +export function formatColor(color: Color): string { + try { + const parsed = formatCss(color) + return parsed + } catch (error) { + throw new Error(`Color formatting failed for: ${JSON.stringify(color)}, error: ${error}`) + } +} + +export function formatColorAsRgb(color: Color): string { + try { + const parsed = formatRgb(color) + return parsed + } catch (error) { + throw new Error(`Color formatting failed for: ${JSON.stringify(color)}, error: ${error}`) + } +} diff --git a/lib/colorsystem/geist-colors.json b/lib/colorsystem/geist-colors.json index f307bc0..12bf815 100644 --- a/lib/colorsystem/geist-colors.json +++ b/lib/colorsystem/geist-colors.json @@ -56,7 +56,7 @@ "gray": { "name": "gray", "type": "gray", - "aliases": ["neutral"], + "aliases": [], "light": { "100": { "srgb": "hsl(0, 0%, 95%)" @@ -639,7 +639,7 @@ "purple": { "name": "purple", "type": "accent", - "aliases": [], + "aliases": ["secondary"], "light": { "100": { "srgb": "hsl(276, 100%, 97%)", @@ -728,7 +728,7 @@ "pink": { "name": "pink", "type": "accent", - "aliases": ["secondary"], + "aliases": ["tertiary"], "light": { "100": { "srgb": "hsl(330, 100%, 96%)", diff --git a/lib/colorsystem/generate-panda-preset.ts b/lib/colorsystem/generate-panda-preset.ts index 75877e9..cfcd842 100644 --- a/lib/colorsystem/generate-panda-preset.ts +++ b/lib/colorsystem/generate-panda-preset.ts @@ -1,4 +1,5 @@ import type { Preset } from '@pandacss/types' +import { outdent } from 'outdent' import generateColorTokens from './generate-color-tokens' import type { ColorSystemConfig } from './types' @@ -26,3 +27,17 @@ export default function generatePandaPreset(colorSystem: ColorSystemConfig): Pre return configSubset } + +export function generateColorSystemPresetCode(colorSystem: ColorSystemConfig): string { + const configSubset = generatePandaPreset(colorSystem) + + const jsCode = outdent` + import { definePreset } from "@pandacss/dev"; + + export const colorSystemPreset = definePreset( + ${JSON.stringify(configSubset, null, 2)} + ); + ` + + return jsCode +} diff --git a/lib/colorsystem/modify-palette-hue.ts b/lib/colorsystem/modify-palette-hue.ts new file mode 100644 index 0000000..8a407db --- /dev/null +++ b/lib/colorsystem/modify-palette-hue.ts @@ -0,0 +1,36 @@ +import _ from 'lodash' +import { formatColor, formatColorAsRgb, parseColor } from './create-color' +import type { ColorConfig } from './types' + +export default function modifyPaletteHue(newHue: number, palette: ColorConfig): ColorConfig { + const newPalette = _.cloneDeep(palette) + // newPalette.modifiedAt = new Date().toISOString() + + for (const scheme of ['light', 'dark'] as const) { + const schemePalette = newPalette[scheme] + + for (const [level, value] of Object.entries(schemePalette)) { + const srgbAsOklch = value?.srgb ? parseColor(value?.srgb) : undefined + const oklch = value?.oklch ? parseColor(value?.oklch) : undefined + + if (srgbAsOklch) { + srgbAsOklch.h = newHue + } + + if (oklch) { + oklch.h = newHue + } + + newPalette[scheme][level] = { + srgb: srgbAsOklch ? formatColorAsRgb(srgbAsOklch) : undefined, + oklch: oklch ? formatColor(oklch) : undefined, + } + + // if(level==='600') { + // console.log(newPalette[scheme][level]) + // } + } + } + // console.log(newPalette) + return newPalette +} diff --git a/lib/colorsystem/state.tsx b/lib/colorsystem/state.tsx index 7f94dd3..9725b73 100644 --- a/lib/colorsystem/state.tsx +++ b/lib/colorsystem/state.tsx @@ -2,17 +2,22 @@ // import { outdent } from 'outdent' import { type ReactNode, createContext, useContext, useState } from 'react' +import { geistColorsConfig } from './config' +import { generateColorSystemPresetCode } from './generate-panda-preset' +import type { ColorSystemConfig } from './types' export interface AppState { cssCode: string - jsCode: string + colorSystemConfig: ColorSystemConfig + colorSystemPresetCode: string } export const initialCss = '@layer reset, base, tokens, recipes, utilities;' + '\n' export const defaultAppState: AppState = { - jsCode: '', //('theme: { extend: {} },'), cssCode: initialCss, + colorSystemConfig: geistColorsConfig, + colorSystemPresetCode: generateColorSystemPresetCode(geistColorsConfig), } interface AppStateProviderProps { @@ -25,9 +30,14 @@ const AppStateUpdateContext = createContext { const [appState, setAppState] = useState({ ...defaultAppState }) + const wrappedSetAppState: React.Dispatch> = (newAppState) => { + // const colorSystemPresetCode = prevAppState.colorSystemConfig + setAppState((prevAppState) => ({ ...prevAppState, ...newAppState })) + } + return ( - {children} + {children} ) } @@ -39,5 +49,33 @@ export const useAppState = (): [AppState, React.Dispatch( + // (newAppState) => + // setContext((prevAppState) => { + // const colorSystemPresetCode = + // prevAppState.colorSystemConfig === newAppState.colorSystemConfig + // ? prevAppState.colorSystemPresetCode + // : generateColorSystemPresetCode(newAppState.colorSystemConfig) + // return { ...prevAppState, ...newAppState, colorSystemPresetCode } + // }), + // [setContext], + // ) + return [context, setContext] as const } + +// export const useColorSystem = (): [AppState, (newColorSystem: ColorSystemConfig) => void] => { +// const [state, setState] = useAppState() + +// const setContext = (newColorSystem: ColorSystemConfig) => { +// setState((prevState): AppState => { +// return { +// ...prevState, +// colorSystemConfig: newColorSystem, +// colorSystemPresetCode: generateColorSystemPresetCode(newColorSystem), +// } +// }) +// } + +// return [state, setContext] as const +// } diff --git a/lib/hooks/use-darkmode.ts b/lib/hooks/use-darkmode.ts index 7b699b1..79a879b 100644 --- a/lib/hooks/use-darkmode.ts +++ b/lib/hooks/use-darkmode.ts @@ -7,5 +7,5 @@ export default function useDarkMode() { const isDarkMode = actualTheme === 'dark' const toggleDarkMode = () => setTheme(isDarkMode ? 'light' : 'dark') - return {isDarkMode, toggleDarkMode} + return { isDarkMode, toggleDarkMode } } diff --git a/package.json b/package.json index b602dd7..c011561 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,9 @@ "@pandacss/preset-panda": "^0.40.0", "@vercel/analytics": "^1.3.1", "clsx": "^2.1.1", - "colorjs.io": "^0.5.0", + "culori": "^4.0.1", "geist": "^1.3.0", + "lodash": "^4.17.21", "lucide-react": "^0.381.0", "next": "^14.2.3", "next-themes": "^0.3.0", @@ -46,6 +47,8 @@ "@biomejs/biome": "^1.7.3", "@pandacss/dev": "^0.40.0", "@pandacss/types": "^0.40.0", + "@types/culori": "^2.1.0", + "@types/lodash": "^4.17.4", "@types/node": "^20.12.13", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", diff --git a/panda.preset-colors.ts b/panda.preset-colors.ts index bc4e7af..0c36d1a 100644 --- a/panda.preset-colors.ts +++ b/panda.preset-colors.ts @@ -1402,101 +1402,6 @@ export const colorSystemPreset = definePreset({ value: '{colors.gray}', }, }, - neutral: { - '100': { - value: { - base: '{colors.gray.light.100}', - _dark: '{colors.gray.dark.100}', - }, - }, - '200': { - value: { - base: '{colors.gray.light.200}', - _dark: '{colors.gray.dark.200}', - }, - }, - '300': { - value: { - base: '{colors.gray.light.300}', - _dark: '{colors.gray.dark.300}', - }, - }, - '400': { - value: { - base: '{colors.gray.light.400}', - _dark: '{colors.gray.dark.400}', - }, - }, - '500': { - value: { - base: '{colors.gray.light.500}', - _dark: '{colors.gray.dark.500}', - }, - }, - '600': { - value: { - base: '{colors.gray.light.600}', - _dark: '{colors.gray.dark.600}', - }, - }, - '700': { - value: { - base: '{colors.gray.light.700}', - _dark: '{colors.gray.dark.700}', - }, - }, - '800': { - value: { - base: '{colors.gray.light.800}', - _dark: '{colors.gray.dark.800}', - }, - }, - '900': { - value: { - base: '{colors.gray.light.900}', - _dark: '{colors.gray.dark.900}', - }, - }, - '950': { - value: { - base: '{colors.gray.light.950}', - _dark: '{colors.gray.dark.950}', - }, - }, - bg1: { - value: '{colors.gray.100}', - }, - bg2: { - value: '{colors.gray.200}', - }, - bg3: { - value: '{colors.gray.300}', - }, - border1: { - value: '{colors.gray.400}', - }, - border2: { - value: '{colors.gray.500}', - }, - border3: { - value: '{colors.gray.600}', - }, - solid1: { - value: '{colors.gray.700}', - }, - solid2: { - value: '{colors.gray.800}', - }, - fg1: { - value: '{colors.gray.900}', - }, - fg2: { - value: '{colors.gray.950}', - }, - DEFAULT: { - value: '{colors.gray}', - }, - }, alpha: { '100': { value: { @@ -3297,6 +3202,161 @@ export const colorSystemPreset = definePreset({ value: '{colors.purple}', }, }, + secondary: { + '100': { + value: { + base: '{colors.purple.light.100}', + _dark: '{colors.purple.dark.100}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.100}', + _dark: '{colors.purpleP3.dark.100}', + }, + }, + }, + }, + '200': { + value: { + base: '{colors.purple.light.200}', + _dark: '{colors.purple.dark.200}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.200}', + _dark: '{colors.purpleP3.dark.200}', + }, + }, + }, + }, + '300': { + value: { + base: '{colors.purple.light.300}', + _dark: '{colors.purple.dark.300}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.300}', + _dark: '{colors.purpleP3.dark.300}', + }, + }, + }, + }, + '400': { + value: { + base: '{colors.purple.light.400}', + _dark: '{colors.purple.dark.400}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.400}', + _dark: '{colors.purpleP3.dark.400}', + }, + }, + }, + }, + '500': { + value: { + base: '{colors.purple.light.500}', + _dark: '{colors.purple.dark.500}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.500}', + _dark: '{colors.purpleP3.dark.500}', + }, + }, + }, + }, + '600': { + value: { + base: '{colors.purple.light.600}', + _dark: '{colors.purple.dark.600}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.600}', + _dark: '{colors.purpleP3.dark.600}', + }, + }, + }, + }, + '700': { + value: { + base: '{colors.purple.light.700}', + _dark: '{colors.purple.dark.700}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.700}', + _dark: '{colors.purpleP3.dark.700}', + }, + }, + }, + }, + '800': { + value: { + base: '{colors.purple.light.800}', + _dark: '{colors.purple.dark.800}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.800}', + _dark: '{colors.purpleP3.dark.800}', + }, + }, + }, + }, + '900': { + value: { + base: '{colors.purple.light.900}', + _dark: '{colors.purple.dark.900}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.900}', + _dark: '{colors.purpleP3.dark.900}', + }, + }, + }, + }, + '950': { + value: { + base: '{colors.purple.light.950}', + _dark: '{colors.purple.dark.950}', + _mediaP3: { + _supportsP3: { + base: '{colors.purpleP3.light.950}', + _dark: '{colors.purpleP3.dark.950}', + }, + }, + }, + }, + bg1: { + value: '{colors.purple.100}', + }, + bg2: { + value: '{colors.purple.200}', + }, + bg3: { + value: '{colors.purple.300}', + }, + border1: { + value: '{colors.purple.400}', + }, + border2: { + value: '{colors.purple.500}', + }, + border3: { + value: '{colors.purple.600}', + }, + solid1: { + value: '{colors.purple.700}', + }, + solid2: { + value: '{colors.purple.800}', + }, + fg1: { + value: '{colors.purple.900}', + }, + fg2: { + value: '{colors.purple.950}', + }, + DEFAULT: { + value: '{colors.purple}', + }, + }, pink: { '100': { value: { @@ -3452,7 +3512,7 @@ export const colorSystemPreset = definePreset({ value: '{colors.pink}', }, }, - secondary: { + tertiary: { '100': { value: { base: '{colors.pink.light.100}', diff --git a/panda.preset.ts b/panda.preset.ts index bc75f1c..3324433 100644 --- a/panda.preset.ts +++ b/panda.preset.ts @@ -138,7 +138,15 @@ const spacing = defineTokens.spacing({ export default definePreset({ conditions: { extend: { - // hidden: '&:is([hidden])', + collapsed: '&:is([aria-collapsed=true], [data-collapsed], [data-state="collapsed"])', + current: '&:is([data-current])', + hidden: '&:is([hidden])', + hover: ['@media (hover: hover) and (pointer: fine)', '&:is(:hover, [data-hover])'], + indeterminate: '&:is(:indeterminate, [data-indeterminate], [aria-checked=mixed], [data-state=indeterminate])', + off: '&:is([data-state="off"])', + on: '&:is([data-state="on"])', + today: '&:is([data-today])', + underValue: '&:is([data-state="under-value"])', // inert: '&:is([inert])', // hover: ['@media (hover: hover) and (pointer: fine)', '&:is(:hover, [data-hover])'], // standalone: '@media (display-mode: standalone)', diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 48e52db..fb2ba8a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,12 +38,15 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 - colorjs.io: - specifier: ^0.5.0 - version: 0.5.0 + culori: + specifier: ^4.0.1 + version: 4.0.1 geist: specifier: ^1.3.0 version: 1.3.0(next@14.2.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + lodash: + specifier: ^4.17.21 + version: 4.17.21 lucide-react: specifier: ^0.381.0 version: 0.381.0(react@18.3.1) @@ -84,6 +87,12 @@ importers: '@pandacss/types': specifier: ^0.40.0 version: 0.40.0 + '@types/culori': + specifier: ^2.1.0 + version: 2.1.0 + '@types/lodash': + specifier: ^4.17.4 + version: 4.17.4 '@types/node': specifier: ^20.12.13 version: 20.12.13 @@ -496,6 +505,12 @@ packages: '@ts-morph/common@0.22.0': resolution: {integrity: sha512-HqNBuV/oIlMKdkLshXd1zKBqNQCsuPEsgQOkfFQ/eUKjRlwndXW1AjN9LVkBEIukm00gGXSRmfkl0Wv5VXLnlw==} + '@types/culori@2.1.0': + resolution: {integrity: sha512-4uJT5CcC9Mi8mACkWShsPHqILMWL0OqoTsfoLJUGzN1mcipcepmmEdzU8b9L1KwyRNN3rnQO39ylI/2VR850zw==} + + '@types/lodash@4.17.4': + resolution: {integrity: sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==} + '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} @@ -968,9 +983,6 @@ packages: code-block-writer@12.0.0: resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} - colorjs.io@0.5.0: - resolution: {integrity: sha512-qekjTiBLM3F/sXKks/ih5aWaHIGu+Ftel0yKEvmpbKvmxpNOhojKgha5uiWEUOqEpRjC1Tq3nJRT7WgdBOxIGg==} - confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} @@ -992,6 +1004,10 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + culori@4.0.1: + resolution: {integrity: sha512-LSnjA6HuIUOlkfKVbzi2OlToZE8OjFi667JWN9qNymXVXzGDmvuP60SSgC+e92sd7B7158f7Fy3Mb6rXS5EDPw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + detect-indent@7.0.1: resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} engines: {node: '>=12.20'} @@ -1253,6 +1269,9 @@ packages: lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + look-it-up@2.1.0: resolution: {integrity: sha512-nMoGWW2HurtuJf6XAL56FWTDCWLOTSsanrgwOyaR5Y4e3zfG5N/0cU5xWZSEU3tBxhQugRbV1xL9jb+ug7yZww==} @@ -2138,6 +2157,10 @@ snapshots: mkdirp: 3.0.1 path-browserify: 1.0.1 + '@types/culori@2.1.0': {} + + '@types/lodash@4.17.4': {} + '@types/node@17.0.45': {} '@types/node@20.12.13': @@ -3133,8 +3156,6 @@ snapshots: code-block-writer@12.0.0: {} - colorjs.io@0.5.0: {} - confbox@0.1.7: {} crosspath@2.0.0: @@ -3149,6 +3170,8 @@ snapshots: csstype@3.1.3: {} + culori@4.0.1: {} + detect-indent@7.0.1: {} detect-libc@1.0.3: {} @@ -3382,6 +3405,8 @@ snapshots: lodash.uniq@4.5.0: {} + lodash@4.17.21: {} + look-it-up@2.1.0: {} loose-envify@1.4.0: