@devalok/shilp-sutra 0.51.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/MIGRATION.md +12 -0
- package/dist/_chunks/motion-provider.js +7 -6
- package/dist/_chunks/motion-provider.js.map +1 -1
- package/dist/_chunks/success.js +53 -53
- package/dist/ai/command-bar.js +158 -158
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.js +5 -5
- package/dist/composed/command-palette.js +17 -17
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/priority-indicator.d.ts +15 -6
- package/dist/composed/priority-indicator.d.ts.map +1 -1
- package/dist/composed/priority-indicator.js +37 -88
- package/dist/composed/priority-indicator.js.map +1 -1
- package/dist/composed/schedule-view.d.ts +17 -2
- package/dist/composed/schedule-view.d.ts.map +1 -1
- package/dist/composed/schedule-view.js +163 -64
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/motion/motion-provider.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.d.ts +32 -6
- package/dist/shell/bottom-navbar.d.ts.map +1 -1
- package/dist/shell/bottom-navbar.js +156 -129
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/tokens/primitives.css +6 -2
- package/dist/tokens/semantic.css +20 -1
- package/dist/tokens/utilities.css +6 -0
- package/dist/ui/autocomplete.d.ts +34 -32
- package/dist/ui/autocomplete.d.ts.map +1 -1
- package/dist/ui/autocomplete.js +115 -110
- package/dist/ui/autocomplete.js.map +1 -1
- package/dist/ui/button-group.js +2 -0
- package/dist/ui/button-group.js.map +1 -1
- package/dist/ui/button-processing.d.ts.map +1 -1
- package/dist/ui/button-processing.js +1 -0
- package/dist/ui/button-processing.js.map +1 -1
- package/dist/ui/button.d.ts +3 -3
- package/dist/ui/button.d.ts.map +1 -1
- package/dist/ui/button.js +26 -0
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/color-input.d.ts.map +1 -1
- package/dist/ui/color-input.js +82 -82
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/combobox.js +4 -4
- package/dist/ui/icon.d.ts +2 -0
- package/dist/ui/icon.d.ts.map +1 -1
- package/dist/ui/icon.js +31 -26
- package/dist/ui/icon.js.map +1 -1
- package/dist/ui/index.js +30 -30
- package/dist/ui/search-input.d.ts.map +1 -1
- package/dist/ui/search-input.js +5 -4
- package/dist/ui/search-input.js.map +1 -1
- package/dist/ui/segmented-control.d.ts +28 -6
- package/dist/ui/segmented-control.d.ts.map +1 -1
- package/dist/ui/segmented-control.js +61 -43
- package/dist/ui/segmented-control.js.map +1 -1
- package/dist/ui/sidebar.js +7 -7
- package/dist/ui/split-button.d.ts.map +1 -1
- package/dist/ui/split-button.js +7 -0
- package/dist/ui/split-button.js.map +1 -1
- package/docs/components/composed/priority-indicator.md +22 -11
- package/docs/components/composed/schedule-view.md +20 -5
- package/docs/components/shell/bottom-navbar.md +24 -5
- package/docs/components/ui/autocomplete.md +26 -10
- package/docs/components/ui/button.md +2 -2
- package/docs/components/ui/segmented-control.md +31 -11
- package/docs/recipes/install-remix.md +3 -3
- package/docs/recipes/install-vite.md +3 -3
- package/docs/recipes/server-components.md +2 -2
- package/llms.txt +1 -1
- package/make-kit/foundations/color.md +20 -0
- package/make-kit/foundations/dark-mode.md +6 -9
- package/make-kit/foundations/icons.md +3 -3
- package/make-kit/setup.md +4 -4
- package/mcp-manifest.json +239 -35
- package/package.json +1 -1
- package/scripts/welcome.mjs +59 -1
- package/skill/SKILL.md +1 -1
- package/skill/references/components.md +1 -1
- package/skill/references/server-components.md +2 -2
- package/skill/references/setup-remix.md +3 -3
- package/skill/references/setup-vite.md +3 -3
package/dist/ui/button.js
CHANGED
|
@@ -28,6 +28,7 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
|
|
|
28
28
|
error: "",
|
|
29
29
|
success: "",
|
|
30
30
|
warning: "",
|
|
31
|
+
info: "",
|
|
31
32
|
neutral: ""
|
|
32
33
|
},
|
|
33
34
|
weight: {
|
|
@@ -70,6 +71,11 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
|
|
|
70
71
|
color: "warning",
|
|
71
72
|
className: "bg-warning-9 text-warning-fg hover:bg-warning-10 shadow-raised"
|
|
72
73
|
},
|
|
74
|
+
{
|
|
75
|
+
variant: "solid",
|
|
76
|
+
color: "info",
|
|
77
|
+
className: "bg-info-9 text-info-fg hover:bg-info-10 shadow-raised"
|
|
78
|
+
},
|
|
73
79
|
{
|
|
74
80
|
variant: "solid",
|
|
75
81
|
color: "neutral",
|
|
@@ -95,6 +101,11 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
|
|
|
95
101
|
color: "warning",
|
|
96
102
|
className: "bg-warning-3 text-warning-11 hover:bg-warning-4 active:bg-warning-5"
|
|
97
103
|
},
|
|
104
|
+
{
|
|
105
|
+
variant: "soft",
|
|
106
|
+
color: "info",
|
|
107
|
+
className: "bg-info-3 text-info-11 hover:bg-info-4 active:bg-info-5"
|
|
108
|
+
},
|
|
98
109
|
{
|
|
99
110
|
variant: "soft",
|
|
100
111
|
color: "neutral",
|
|
@@ -120,6 +131,11 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
|
|
|
120
131
|
color: "warning",
|
|
121
132
|
className: "bg-transparent text-warning-11 border-warning-7 hover:bg-warning-3 active:bg-warning-4"
|
|
122
133
|
},
|
|
134
|
+
{
|
|
135
|
+
variant: "outline",
|
|
136
|
+
color: "info",
|
|
137
|
+
className: "bg-transparent text-info-11 border-info-7 hover:bg-info-3 active:bg-info-4"
|
|
138
|
+
},
|
|
123
139
|
{
|
|
124
140
|
variant: "outline",
|
|
125
141
|
color: "neutral",
|
|
@@ -145,6 +161,11 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
|
|
|
145
161
|
color: "warning",
|
|
146
162
|
className: "bg-transparent text-warning-11 hover:bg-warning-3 active:bg-warning-4"
|
|
147
163
|
},
|
|
164
|
+
{
|
|
165
|
+
variant: "ghost",
|
|
166
|
+
color: "info",
|
|
167
|
+
className: "bg-transparent text-info-11 hover:bg-info-3 active:bg-info-4"
|
|
168
|
+
},
|
|
148
169
|
{
|
|
149
170
|
variant: "ghost",
|
|
150
171
|
color: "neutral",
|
|
@@ -170,6 +191,11 @@ var u = r("relative inline-flex items-center justify-center whitespace-nowrap fo
|
|
|
170
191
|
color: "warning",
|
|
171
192
|
className: "text-warning-11"
|
|
172
193
|
},
|
|
194
|
+
{
|
|
195
|
+
variant: "link",
|
|
196
|
+
color: "info",
|
|
197
|
+
className: "text-info-11"
|
|
198
|
+
},
|
|
173
199
|
{
|
|
174
200
|
variant: "link",
|
|
175
201
|
color: "neutral",
|
package/dist/ui/button.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","names":[],"sources":["../../src/ui/button.tsx"],"sourcesContent":["'use client'\n\nimport { Slot, Slottable } from '@primitives/react-slot'\nimport { IconCheck, IconX } from '@tabler/icons-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { getGroupPositionStyle,useButtonGroup, useButtonGroupItem } from './button-group'\nimport type { ProcessingSpeed } from './button-processing'\nimport { ProcessingOverlay } from './button-processing'\nimport { Icon } from './icon'\nimport type { IconSize } from './icon-context'\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { motionProps,springs, tweens } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\nimport { Spinner } from './spinner'\n\nexport const buttonVariants = cva(\n 'relative inline-flex items-center justify-center whitespace-nowrap font-sans select-none overflow-hidden isolate focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled disabled:cursor-not-allowed disabled:saturate-[0.3] [&>span:not([data-grain])]:relative [&>span:not([data-grain])]:z-[2]',\n {\n variants: {\n variant: {\n solid: '',\n soft: '',\n outline: 'border',\n ghost: '',\n link: 'underline-offset-4 hover:underline active:opacity-80',\n },\n color: {\n accent: '',\n error: '',\n success: '',\n warning: '',\n neutral: '',\n },\n weight: {\n semibold: 'font-semibold',\n normal: 'font-normal',\n },\n size: {\n xs: 'h-ds-xs-plus rounded-control px-ds-03 text-body-sm gap-ds-02',\n sm: 'h-ds-sm rounded-control px-ds-04 text-body-sm gap-ds-02b',\n md: 'h-ds-md rounded-control px-ds-05 text-body-md gap-ds-03',\n lg: 'h-ds-lg rounded-control px-ds-06 text-body-lg gap-2.5',\n 'compact-xs': 'rounded-control px-ds-02 py-[3px] text-body-sm gap-ds-02',\n 'compact-sm': 'rounded-control px-ds-03 py-[5px] text-body-sm gap-ds-02b',\n 'compact-md': 'rounded-control px-ds-04 py-ds-03 text-body-md gap-ds-03',\n icon: 'h-ds-md w-ds-md rounded-control',\n 'icon-xs': 'h-ds-xs-plus w-ds-xs-plus rounded-control',\n 'icon-sm': 'h-ds-sm w-ds-sm rounded-control',\n 'icon-md': 'h-ds-md w-ds-md rounded-control',\n 'icon-lg': 'h-ds-lg w-ds-lg rounded-control',\n },\n },\n compoundVariants: [\n // ============ SOLID ============ (tonal raised shadow; fill deepens on hover — no coloured bloom)\n { variant: 'solid', color: 'accent', className: 'bg-accent-9 text-accent-fg hover:bg-accent-10 shadow-raised' },\n { variant: 'solid', color: 'error', className: 'bg-error-9 text-error-fg hover:bg-error-10 shadow-raised' },\n { variant: 'solid', color: 'success', className: 'bg-success-9 text-success-fg hover:bg-success-10 shadow-raised' },\n { variant: 'solid', color: 'warning', className: 'bg-warning-9 text-warning-fg hover:bg-warning-10 shadow-raised' },\n { variant: 'solid', color: 'neutral', className: 'bg-neutral-5 text-surface-fg hover:bg-neutral-7 shadow-raised' },\n\n // ============ SOFT ============\n { variant: 'soft', color: 'accent', className: 'bg-accent-3 text-accent-11 hover:bg-accent-4 active:bg-accent-5' },\n { variant: 'soft', color: 'error', className: 'bg-error-3 text-error-11 hover:bg-error-4 active:bg-error-5' },\n { variant: 'soft', color: 'success', className: 'bg-success-3 text-success-11 hover:bg-success-4 active:bg-success-5' },\n { variant: 'soft', color: 'warning', className: 'bg-warning-3 text-warning-11 hover:bg-warning-4 active:bg-warning-5' },\n { variant: 'soft', color: 'neutral', className: 'bg-surface-raised-hover text-surface-fg-muted hover:bg-surface-raised-active active:bg-neutral-5' },\n\n // ============ OUTLINE ============\n { variant: 'outline', color: 'accent', className: 'bg-transparent text-accent-11 border-accent-7 hover:bg-accent-3 active:bg-accent-4' },\n { variant: 'outline', color: 'error', className: 'bg-transparent text-error-11 border-error-7 hover:bg-error-3 active:bg-error-4' },\n { variant: 'outline', color: 'success', className: 'bg-transparent text-success-11 border-success-7 hover:bg-success-3 active:bg-success-4' },\n { variant: 'outline', color: 'warning', className: 'bg-transparent text-warning-11 border-warning-7 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'outline', color: 'neutral', className: 'bg-transparent text-surface-fg border-surface-border-strong hover:bg-surface-raised-hover active:bg-surface-raised-active' },\n\n // ============ GHOST ============\n // ghost+accent uses neutral look for backward compat (most common ghost is toolbar/icon ghost)\n { variant: 'ghost', color: 'accent', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n { variant: 'ghost', color: 'error', className: 'bg-transparent text-error-11 hover:bg-error-3 active:bg-error-4' },\n { variant: 'ghost', color: 'success', className: 'bg-transparent text-success-11 hover:bg-success-3 active:bg-success-4' },\n { variant: 'ghost', color: 'warning', className: 'bg-transparent text-warning-11 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'ghost', color: 'neutral', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n\n // ============ LINK ============\n { variant: 'link', color: 'accent', className: 'text-accent-11' },\n { variant: 'link', color: 'error', className: 'text-error-11' },\n { variant: 'link', color: 'success', className: 'text-success-11' },\n { variant: 'link', color: 'warning', className: 'text-warning-11' },\n { variant: 'link', color: 'neutral', className: 'text-surface-fg-muted' },\n ],\n defaultVariants: {\n variant: 'solid',\n color: 'accent',\n weight: 'semibold',\n size: 'md',\n },\n },\n)\n\n/** Extra horizontal padding for pill shape — rounded ends eat into visual space */\nconst pillPaddingClass: Record<string, string> = {\n xs: 'px-ds-04',\n sm: 'px-ds-05',\n md: 'px-ds-06',\n lg: 'px-ds-07',\n 'compact-xs': 'px-ds-03',\n 'compact-sm': 'px-ds-04',\n 'compact-md': 'px-ds-05',\n}\n\n/** Negative margin to tighten icon side padding — pulls icon closer to button edge */\nconst iconInsetClass: Record<string, { start: string; end: string }> = {\n xs: { start: '-ml-0.5', end: '-mr-0.5' },\n sm: { start: '-ml-1', end: '-mr-1' },\n md: { start: '-ml-1.5', end: '-mr-1.5' },\n lg: { start: '-ml-2', end: '-mr-2' },\n 'compact-xs': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-sm': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-md': { start: '-ml-1', end: '-mr-1' },\n icon: { start: '', end: '' },\n 'icon-xs': { start: '', end: '' },\n 'icon-sm': { start: '', end: '' },\n 'icon-md': { start: '', end: '' },\n 'icon-lg': { start: '', end: '' },\n}\n\n/** Map button size to spinner size */\nconst BUTTON_TO_SPINNER_SIZE: Record<string, 'sm' | 'md'> = {\n xs: 'sm',\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n 'compact-xs': 'sm',\n 'compact-sm': 'sm',\n 'compact-md': 'sm',\n icon: 'sm',\n 'icon-xs': 'sm',\n 'icon-sm': 'sm',\n 'icon-md': 'sm',\n 'icon-lg': 'md',\n}\n\n/** Map button size to Icon context size */\nconst BUTTON_TO_ICON_SIZE: Record<string, IconSize> = {\n xs: 'xs', sm: 'sm', md: 'md', lg: 'lg',\n 'compact-xs': 'xs', 'compact-sm': 'sm', 'compact-md': 'md',\n icon: 'md', 'icon-xs': 'xs', 'icon-sm': 'sm', 'icon-md': 'md', 'icon-lg': 'lg',\n}\n\n/**\n * Props for Button — the primary action component with a two-axis variant system,\n * multiple size options, icon slots, and a built-in loading state.\n *\n * **Two axes:**\n * - `variant` controls **visual style**: `\"solid\"` (default, filled) | `\"soft\"` (tinted bg) |\n * `\"outline\"` (bordered) | `\"ghost\"` (transparent, for toolbars) | `\"link\"` (underline, inline)\n * - `color` controls **semantic intent**: `\"accent\"` (default, brand) | `\"error\"` (destructive) |\n * `\"success\"` | `\"warning\"` | `\"neutral\"` (subdued)\n *\n * **Sizes:** `xs` | `sm` | `md` (default) | `lg` for text buttons;\n * `compact-xs` | `compact-sm` | `compact-md` for height-less inline buttons;\n * `icon` | `icon-xs` | `icon-sm` | `icon-md` | `icon-lg` for square icon-only buttons.\n *\n * **Shape:** `\"default\"` uses the `--radius-control` token; `\"pill\"` applies `rounded-pill` (fully-rounded).\n *\n * **Weight:** `\"semibold\"` (default) | `\"normal\"` for lighter labels.\n *\n * **Note:** `ghost` + `accent` renders with neutral styling for backward compat —\n * most ghost buttons are toolbar/icon actions where neutral is expected.\n *\n * **Loading:** When `loading={true}` the button is disabled and aria-busy is set.\n * Use `loadingPosition` to control where the spinner appears.\n *\n * @example\n * // Primary save action (default variant + color):\n * <Button onClick={handleSave}>Save changes</Button>\n *\n * @example\n * // Soft success feedback:\n * <Button variant=\"soft\" color=\"success\" startIcon={<Icon icon={IconCheck} />}>\n * Approved\n * </Button>\n *\n * @example\n * // Destructive delete with loading state:\n * <Button variant=\"solid\" color=\"error\" startIcon={<Icon icon={IconTrash} />} loading={isDeleting}>\n * Delete project\n * </Button>\n *\n * @example\n * // Compact pill tag:\n * <Button variant=\"soft\" color=\"warning\" size=\"compact-sm\" shape=\"pill\">\n * Overdue\n * </Button>\n *\n * @example\n * // Ghost toolbar action:\n * <Button variant=\"ghost\" size=\"sm\" startIcon={<Icon icon={IconEdit} />}>\n * Edit\n * </Button>\n */\nexport interface ButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'color'>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n /** Button shape — 'pill' applies rounded-pill for chip/tag-like buttons */\n shape?: 'default' | 'pill'\n /** Icon element rendered before children — use <Icon icon={...} /> */\n startIcon?: IconInput\n /** Icon element rendered after children — use <Icon icon={...} /> */\n endIcon?: IconInput\n /** Show loading spinner and disable button */\n loading?: boolean\n /** Where to render the spinner: replaces startIcon, endIcon, or centers over children */\n loadingPosition?: 'start' | 'end' | 'center'\n /** Stretch to full width of parent */\n fullWidth?: boolean\n /**\n * Async click handler — auto-manages loading → success/error states.\n * When provided, the button shows a spinner while the promise is pending,\n * then briefly flashes green (success) or red (error) before reverting.\n * Overrides `onClick` and `loading` when active.\n */\n onClickAsync?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void>\n /** How long (ms) to show the success/error state before reverting. Default: 1500 */\n asyncFeedbackDuration?: number\n\n /**\n * Show processing animation — animated border/glow while content stays visible.\n * `true` = \"working\" speed. Semantic speeds:\n * - `\"ambient\"` (3s) — background sync, file upload\n * - `\"working\"` (2s) — standard API call, generation\n * - `\"urgent\"` (1s) — retry, nearly done\n */\n processing?: boolean | 'ambient' | 'working' | 'urgent'\n\n /** Override processing animation color. Defaults to button's own color. */\n processingColor?: 'accent' | 'error' | 'success' | 'warning' | 'neutral'\n\n /** Disable button during processing. Default: true. Set false for cancel-by-click patterns. */\n processingDisabled?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant,\n color,\n weight,\n size,\n asChild = false,\n shape,\n startIcon,\n endIcon,\n loading: loadingProp = false,\n loadingPosition = 'start',\n fullWidth = false,\n disabled,\n onClick,\n onClickAsync,\n asyncFeedbackDuration = 1500,\n processing: processingProp,\n processingColor,\n processingDisabled = true,\n children,\n ...props\n },\n ref,\n ) => {\n const group = useButtonGroup()\n const groupItem = useButtonGroupItem()\n const resolvedVariant = variant ?? group.variant\n const resolvedColor = color ?? group.color\n const resolvedWeight = weight ?? group.weight ?? 'semibold'\n const resolvedShape = shape ?? group.shape ?? 'default'\n const resolvedSize = size ?? group.size ?? 'md'\n // ButtonGroup can propagate disabled to all children\n const resolvedDisabled = disabled ?? group.disabled\n\n // When inside an attached ButtonGroup, adjust border-radius based on position\n const groupRadiusStyle = groupItem && group.attached !== false\n ? getGroupPositionStyle(groupItem.position, group.orientation ?? 'horizontal')\n : undefined\n // Stretch to fill when inside a vertical or fullWidth ButtonGroup\n const groupStretch = group._stretch ?? false\n\n const prefersReduced = useReducedMotion()\n\n // Refs + effect for smooth width transitions (must be before any early returns)\n const wrapperRef = React.useRef<HTMLSpanElement>(null)\n const btnRef = React.useRef<HTMLButtonElement | null>(null)\n const rafRef = React.useRef<number | undefined>(undefined)\n\n \n React.useEffect(() => {\n const btn = btnRef.current\n const wrapper = wrapperRef.current\n if (!btn || !wrapper || fullWidth || groupStretch || prefersReduced) return\n\n rafRef.current = requestAnimationFrame(() => {\n wrapper.style.width = 'auto'\n const w = btn.offsetWidth\n if (w > 0) {\n wrapper.getBoundingClientRect()\n wrapper.style.width = `${w}px`\n }\n })\n return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current) }\n }) // run on every render to catch content changes\n\n // Async state machine: idle → loading → success | error → idle\n type AsyncState = 'idle' | 'loading' | 'success' | 'error'\n const [asyncState, setAsyncState] = React.useState<AsyncState>('idle')\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const isMountedRef = React.useRef(true)\n\n React.useEffect(() => () => {\n isMountedRef.current = false\n clearTimeout(timeoutRef.current)\n }, [])\n\n const handleAsyncClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onClickAsync || asyncState !== 'idle') return\n setAsyncState('loading')\n onClickAsync(e)\n .then(() => { if (isMountedRef.current) setAsyncState('success') })\n .catch(() => { if (isMountedRef.current) setAsyncState('error') })\n .finally(() => {\n if (isMountedRef.current) {\n timeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) setAsyncState('idle')\n }, asyncFeedbackDuration)\n }\n })\n }\n\n const isAsync = !!onClickAsync\n const loading = isAsync ? asyncState === 'loading' : loadingProp\n const isAsyncFeedback = asyncState === 'success' || asyncState === 'error'\n\n // Processing: explicit prop takes priority, otherwise auto-processing during onClickAsync.\n // Processing is always OFF during async feedback (success/error) so the feedback colors show.\n const autoProcessing = isAsync && asyncState === 'loading' && !processingProp\n const processingSpeed: ProcessingSpeed | undefined = isAsyncFeedback ? undefined\n : processingProp === true ? 'working'\n : processingProp === false || !processingProp\n ? (autoProcessing ? 'working' : undefined)\n : processingProp\n const isProcessing = !!processingSpeed\n const resolvedProcessingColor = processingColor ?? resolvedColor ?? 'accent'\n\n if (asChild) {\n // Slot merges all props into the child element via cloneElement at runtime.\n // We cast here because SlotProps only types React.HTMLAttributes<HTMLElement>,\n // which excludes button-specific attrs like `disabled`.\n const slotProps = {\n className: cn(\n buttonVariants({ variant: resolvedVariant, color: resolvedColor, weight: resolvedWeight, size: resolvedSize }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n className,\n ),\n ref,\n disabled: resolvedDisabled || loading,\n 'aria-busy': loading || undefined,\n ...props,\n } as React.ComponentPropsWithRef<typeof Slot>\n return (\n <Slot {...slotProps}>\n <Slottable>{children}</Slottable>\n </Slot>\n )\n }\n\n const inset = iconInsetClass[resolvedSize] ?? { start: '', end: '' }\n // Dim icons on filled variants (Radix pattern — icon is decorative, text is primary)\n const dimIcon = resolvedVariant === 'solid' || resolvedVariant === 'soft' || resolvedVariant === 'outline'\n\n const renderStartSlot = () => {\n if (loading && loadingPosition === 'start') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', startIcon && inset.start)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (startIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.start, dimIcon && 'opacity-90')}>\n {normalizeIcon(startIcon)}\n </span>\n )\n }\n return null\n }\n\n const renderEndSlot = () => {\n if (loading && loadingPosition === 'end') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', endIcon && inset.end)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (endIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.end, dimIcon && 'opacity-90')}>\n {normalizeIcon(endIcon)}\n </span>\n )\n }\n return null\n }\n\n // Separate DevalokGrain elements (need to be direct button children for absolute positioning)\n // from text/other content (needs z-elevation above grain)\n const childArray = React.Children.toArray(children)\n const grainElements: React.ReactNode[] = []\n const contentElements: React.ReactNode[] = []\n childArray.forEach((child) => {\n if (React.isValidElement(child) && (child.type as { displayName?: string })?.displayName === 'DevalokGrain') {\n grainElements.push(child)\n } else {\n contentElements.push(child)\n }\n })\n\n const renderChildren = () => {\n if (loading && loadingPosition === 'center') {\n return (\n <span className=\"relative inline-flex items-center justify-center\">\n <span className=\"invisible\">{contentElements}</span>\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n </span>\n )\n }\n // Only wrap in z-elevated span when grain is present (to sit above grain layers).\n // Without grain, render children directly to preserve flex layout.\n if (grainElements.length > 0) {\n return <span>{contentElements}</span>\n }\n return <>{contentElements}</>\n }\n\n // Async feedback: override color to show green/red\n const feedbackColorClass = isAsyncFeedback\n ? asyncState === 'success'\n ? 'bg-success-9 text-success-fg border-transparent hover:bg-success-9'\n : 'bg-error-9 text-error-fg border-transparent hover:bg-error-9'\n : undefined\n\n // Async feedback icon — uses Icon's draw animation for pen-stroke effect\n const asyncFeedbackIcon = isAsyncFeedback ? (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', startIcon && inset.start)}>\n <Icon icon={asyncState === 'success' ? IconCheck : IconX} animate=\"draw\" />\n </span>\n ) : null\n\n const iconSize = BUTTON_TO_ICON_SIZE[resolvedSize] ?? 'md'\n\n const buttonEl = (\n <motion.button\n {...motionProps(props)}\n style={{ ...props.style, ...groupRadiusStyle }}\n className={cn(\n buttonVariants({\n // When processing (and not showing async feedback), force soft variant so ants pop\n variant: isProcessing && !isAsyncFeedback && resolvedVariant !== 'ghost' && resolvedVariant !== 'outline' && resolvedVariant !== 'link' ? 'soft' : resolvedVariant,\n color: resolvedColor,\n weight: resolvedWeight,\n size: resolvedSize,\n }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n // Asymmetric timing: hover-out is slow+relaxed, hover-in is fast+snappy (applied via hover: override)\n !loading && !isAsyncFeedback && 'transition-[color,background-color,border-color,box-shadow,transform,filter] duration-moderate-01 ease-productive-exit',\n !loading && !isAsyncFeedback && 'hover:duration-fast-02 hover:ease-productive-entrance',\n !loading && !isAsyncFeedback && 'active:scale-[0.95] active:brightness-[0.92] active:saturate-[1.1] active:duration-[0ms]',\n feedbackColorClass,\n isAsyncFeedback && 'transition-colors duration-moderate-01 ease-productive-standard',\n isProcessing && processingDisabled && 'pointer-events-none cursor-default',\n className,\n )}\n ref={(el: HTMLButtonElement | null) => {\n btnRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLButtonElement | null>).current = el\n }}\n disabled={resolvedDisabled || (loading && !isProcessing)}\n aria-busy={loading || isProcessing || undefined}\n aria-disabled={isProcessing && processingDisabled || undefined}\n onClick={isAsync ? handleAsyncClick : (isProcessing && processingDisabled ? undefined : onClick)}\n >\n {/* Grain layers render as direct children (need absolute positioning) */}\n {grainElements}\n {/* Content renders above grain via z-[2] span wrapper */}\n {isAsyncFeedback ? asyncFeedbackIcon : renderStartSlot()}\n {isAsyncFeedback ? contentElements : renderChildren()}\n {isAsyncFeedback ? null : renderEndSlot()}\n </motion.button>\n )\n\n // Always wrap in a positioned container so the overlay can render\n // as a sibling OUTSIDE the button (not affected by disabled opacity).\n // Keeping the wrapper always-on prevents React unmount/remount on\n // processing toggle, enabling smooth CSS transitions between states.\n return (\n <IconProvider size={iconSize}>\n <span\n ref={wrapperRef}\n className={cn('relative inline-flex', fullWidth && 'w-full')}\n style={{\n ...(fullWidth || groupStretch || prefersReduced ? undefined : { transition: 'width 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)' }),\n ...groupRadiusStyle,\n }}\n >\n {buttonEl}\n <ProcessingOverlay\n active={isProcessing}\n speed={processingSpeed ?? 'working'}\n color={resolvedProcessingColor}\n />\n </span>\n </IconProvider>\n )\n },\n)\nButton.displayName = 'Button'\n\nexport { Button }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"button.js","names":[],"sources":["../../src/ui/button.tsx"],"sourcesContent":["'use client'\n\nimport { Slot, Slottable } from '@primitives/react-slot'\nimport { IconCheck, IconX } from '@tabler/icons-react'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { AnimatePresence, motion, useReducedMotion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { getGroupPositionStyle,useButtonGroup, useButtonGroupItem } from './button-group'\nimport type { ProcessingSpeed } from './button-processing'\nimport { ProcessingOverlay } from './button-processing'\nimport { Icon } from './icon'\nimport type { IconSize } from './icon-context'\nimport { IconProvider } from './icon-context'\nimport type { IconInput } from './lib/icon-input'\nimport { motionProps,springs, tweens } from './lib/motion'\nimport { normalizeIcon } from './lib/normalize-icon'\nimport { cn } from './lib/utils'\nimport { Spinner } from './spinner'\n\nexport const buttonVariants = cva(\n 'relative inline-flex items-center justify-center whitespace-nowrap font-sans select-none overflow-hidden isolate focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-action-disabled disabled:cursor-not-allowed disabled:saturate-[0.3] [&>span:not([data-grain])]:relative [&>span:not([data-grain])]:z-[2]',\n {\n variants: {\n variant: {\n solid: '',\n soft: '',\n outline: 'border',\n ghost: '',\n link: 'underline-offset-4 hover:underline active:opacity-80',\n },\n color: {\n accent: '',\n error: '',\n success: '',\n warning: '',\n info: '',\n neutral: '',\n },\n weight: {\n semibold: 'font-semibold',\n normal: 'font-normal',\n },\n size: {\n xs: 'h-ds-xs-plus rounded-control px-ds-03 text-body-sm gap-ds-02',\n sm: 'h-ds-sm rounded-control px-ds-04 text-body-sm gap-ds-02b',\n md: 'h-ds-md rounded-control px-ds-05 text-body-md gap-ds-03',\n lg: 'h-ds-lg rounded-control px-ds-06 text-body-lg gap-2.5',\n 'compact-xs': 'rounded-control px-ds-02 py-[3px] text-body-sm gap-ds-02',\n 'compact-sm': 'rounded-control px-ds-03 py-[5px] text-body-sm gap-ds-02b',\n 'compact-md': 'rounded-control px-ds-04 py-ds-03 text-body-md gap-ds-03',\n icon: 'h-ds-md w-ds-md rounded-control',\n 'icon-xs': 'h-ds-xs-plus w-ds-xs-plus rounded-control',\n 'icon-sm': 'h-ds-sm w-ds-sm rounded-control',\n 'icon-md': 'h-ds-md w-ds-md rounded-control',\n 'icon-lg': 'h-ds-lg w-ds-lg rounded-control',\n },\n },\n compoundVariants: [\n // ============ SOLID ============ (tonal raised shadow; fill deepens on hover — no coloured bloom)\n { variant: 'solid', color: 'accent', className: 'bg-accent-9 text-accent-fg hover:bg-accent-10 shadow-raised' },\n { variant: 'solid', color: 'error', className: 'bg-error-9 text-error-fg hover:bg-error-10 shadow-raised' },\n { variant: 'solid', color: 'success', className: 'bg-success-9 text-success-fg hover:bg-success-10 shadow-raised' },\n { variant: 'solid', color: 'warning', className: 'bg-warning-9 text-warning-fg hover:bg-warning-10 shadow-raised' },\n { variant: 'solid', color: 'info', className: 'bg-info-9 text-info-fg hover:bg-info-10 shadow-raised' },\n { variant: 'solid', color: 'neutral', className: 'bg-neutral-5 text-surface-fg hover:bg-neutral-7 shadow-raised' },\n\n // ============ SOFT ============\n { variant: 'soft', color: 'accent', className: 'bg-accent-3 text-accent-11 hover:bg-accent-4 active:bg-accent-5' },\n { variant: 'soft', color: 'error', className: 'bg-error-3 text-error-11 hover:bg-error-4 active:bg-error-5' },\n { variant: 'soft', color: 'success', className: 'bg-success-3 text-success-11 hover:bg-success-4 active:bg-success-5' },\n { variant: 'soft', color: 'warning', className: 'bg-warning-3 text-warning-11 hover:bg-warning-4 active:bg-warning-5' },\n { variant: 'soft', color: 'info', className: 'bg-info-3 text-info-11 hover:bg-info-4 active:bg-info-5' },\n { variant: 'soft', color: 'neutral', className: 'bg-surface-raised-hover text-surface-fg-muted hover:bg-surface-raised-active active:bg-neutral-5' },\n\n // ============ OUTLINE ============\n { variant: 'outline', color: 'accent', className: 'bg-transparent text-accent-11 border-accent-7 hover:bg-accent-3 active:bg-accent-4' },\n { variant: 'outline', color: 'error', className: 'bg-transparent text-error-11 border-error-7 hover:bg-error-3 active:bg-error-4' },\n { variant: 'outline', color: 'success', className: 'bg-transparent text-success-11 border-success-7 hover:bg-success-3 active:bg-success-4' },\n { variant: 'outline', color: 'warning', className: 'bg-transparent text-warning-11 border-warning-7 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'outline', color: 'info', className: 'bg-transparent text-info-11 border-info-7 hover:bg-info-3 active:bg-info-4' },\n { variant: 'outline', color: 'neutral', className: 'bg-transparent text-surface-fg border-surface-border-strong hover:bg-surface-raised-hover active:bg-surface-raised-active' },\n\n // ============ GHOST ============\n // ghost+accent uses neutral look for backward compat (most common ghost is toolbar/icon ghost)\n { variant: 'ghost', color: 'accent', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n { variant: 'ghost', color: 'error', className: 'bg-transparent text-error-11 hover:bg-error-3 active:bg-error-4' },\n { variant: 'ghost', color: 'success', className: 'bg-transparent text-success-11 hover:bg-success-3 active:bg-success-4' },\n { variant: 'ghost', color: 'warning', className: 'bg-transparent text-warning-11 hover:bg-warning-3 active:bg-warning-4' },\n { variant: 'ghost', color: 'info', className: 'bg-transparent text-info-11 hover:bg-info-3 active:bg-info-4' },\n { variant: 'ghost', color: 'neutral', className: 'bg-transparent text-surface-fg-muted hover:bg-surface-raised-hover hover:text-surface-fg active:bg-surface-raised-active' },\n\n // ============ LINK ============\n { variant: 'link', color: 'accent', className: 'text-accent-11' },\n { variant: 'link', color: 'error', className: 'text-error-11' },\n { variant: 'link', color: 'success', className: 'text-success-11' },\n { variant: 'link', color: 'warning', className: 'text-warning-11' },\n { variant: 'link', color: 'info', className: 'text-info-11' },\n { variant: 'link', color: 'neutral', className: 'text-surface-fg-muted' },\n ],\n defaultVariants: {\n variant: 'solid',\n color: 'accent',\n weight: 'semibold',\n size: 'md',\n },\n },\n)\n\n/** Extra horizontal padding for pill shape — rounded ends eat into visual space */\nconst pillPaddingClass: Record<string, string> = {\n xs: 'px-ds-04',\n sm: 'px-ds-05',\n md: 'px-ds-06',\n lg: 'px-ds-07',\n 'compact-xs': 'px-ds-03',\n 'compact-sm': 'px-ds-04',\n 'compact-md': 'px-ds-05',\n}\n\n/** Negative margin to tighten icon side padding — pulls icon closer to button edge */\nconst iconInsetClass: Record<string, { start: string; end: string }> = {\n xs: { start: '-ml-0.5', end: '-mr-0.5' },\n sm: { start: '-ml-1', end: '-mr-1' },\n md: { start: '-ml-1.5', end: '-mr-1.5' },\n lg: { start: '-ml-2', end: '-mr-2' },\n 'compact-xs': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-sm': { start: '-ml-0.5', end: '-mr-0.5' },\n 'compact-md': { start: '-ml-1', end: '-mr-1' },\n icon: { start: '', end: '' },\n 'icon-xs': { start: '', end: '' },\n 'icon-sm': { start: '', end: '' },\n 'icon-md': { start: '', end: '' },\n 'icon-lg': { start: '', end: '' },\n}\n\n/** Map button size to spinner size */\nconst BUTTON_TO_SPINNER_SIZE: Record<string, 'sm' | 'md'> = {\n xs: 'sm',\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n 'compact-xs': 'sm',\n 'compact-sm': 'sm',\n 'compact-md': 'sm',\n icon: 'sm',\n 'icon-xs': 'sm',\n 'icon-sm': 'sm',\n 'icon-md': 'sm',\n 'icon-lg': 'md',\n}\n\n/** Map button size to Icon context size */\nconst BUTTON_TO_ICON_SIZE: Record<string, IconSize> = {\n xs: 'xs', sm: 'sm', md: 'md', lg: 'lg',\n 'compact-xs': 'xs', 'compact-sm': 'sm', 'compact-md': 'md',\n icon: 'md', 'icon-xs': 'xs', 'icon-sm': 'sm', 'icon-md': 'md', 'icon-lg': 'lg',\n}\n\n/**\n * Props for Button — the primary action component with a two-axis variant system,\n * multiple size options, icon slots, and a built-in loading state.\n *\n * **Two axes:**\n * - `variant` controls **visual style**: `\"solid\"` (default, filled) | `\"soft\"` (tinted bg) |\n * `\"outline\"` (bordered) | `\"ghost\"` (transparent, for toolbars) | `\"link\"` (underline, inline)\n * - `color` controls **semantic intent**: `\"accent\"` (default, brand) | `\"error\"` (destructive) |\n * `\"success\"` | `\"warning\"` | `\"info\"` | `\"neutral\"` (subdued)\n *\n * **Sizes:** `xs` | `sm` | `md` (default) | `lg` for text buttons;\n * `compact-xs` | `compact-sm` | `compact-md` for height-less inline buttons;\n * `icon` | `icon-xs` | `icon-sm` | `icon-md` | `icon-lg` for square icon-only buttons.\n *\n * **Shape:** `\"default\"` uses the `--radius-control` token; `\"pill\"` applies `rounded-pill` (fully-rounded).\n *\n * **Weight:** `\"semibold\"` (default) | `\"normal\"` for lighter labels.\n *\n * **Note:** `ghost` + `accent` renders with neutral styling for backward compat —\n * most ghost buttons are toolbar/icon actions where neutral is expected.\n *\n * **Loading:** When `loading={true}` the button is disabled and aria-busy is set.\n * Use `loadingPosition` to control where the spinner appears.\n *\n * @example\n * // Primary save action (default variant + color):\n * <Button onClick={handleSave}>Save changes</Button>\n *\n * @example\n * // Soft success feedback:\n * <Button variant=\"soft\" color=\"success\" startIcon={<Icon icon={IconCheck} />}>\n * Approved\n * </Button>\n *\n * @example\n * // Destructive delete with loading state:\n * <Button variant=\"solid\" color=\"error\" startIcon={<Icon icon={IconTrash} />} loading={isDeleting}>\n * Delete project\n * </Button>\n *\n * @example\n * // Compact pill tag:\n * <Button variant=\"soft\" color=\"warning\" size=\"compact-sm\" shape=\"pill\">\n * Overdue\n * </Button>\n *\n * @example\n * // Ghost toolbar action:\n * <Button variant=\"ghost\" size=\"sm\" startIcon={<Icon icon={IconEdit} />}>\n * Edit\n * </Button>\n */\nexport interface ButtonProps\n extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'color'>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean\n /** Button shape — 'pill' applies rounded-pill for chip/tag-like buttons */\n shape?: 'default' | 'pill'\n /** Icon element rendered before children — use <Icon icon={...} /> */\n startIcon?: IconInput\n /** Icon element rendered after children — use <Icon icon={...} /> */\n endIcon?: IconInput\n /** Show loading spinner and disable button */\n loading?: boolean\n /** Where to render the spinner: replaces startIcon, endIcon, or centers over children */\n loadingPosition?: 'start' | 'end' | 'center'\n /** Stretch to full width of parent */\n fullWidth?: boolean\n /**\n * Async click handler — auto-manages loading → success/error states.\n * When provided, the button shows a spinner while the promise is pending,\n * then briefly flashes green (success) or red (error) before reverting.\n * Overrides `onClick` and `loading` when active.\n */\n onClickAsync?: (e: React.MouseEvent<HTMLButtonElement>) => Promise<void>\n /** How long (ms) to show the success/error state before reverting. Default: 1500 */\n asyncFeedbackDuration?: number\n\n /**\n * Show processing animation — animated border/glow while content stays visible.\n * `true` = \"working\" speed. Semantic speeds:\n * - `\"ambient\"` (3s) — background sync, file upload\n * - `\"working\"` (2s) — standard API call, generation\n * - `\"urgent\"` (1s) — retry, nearly done\n */\n processing?: boolean | 'ambient' | 'working' | 'urgent'\n\n /** Override processing animation color. Defaults to button's own color. */\n processingColor?: 'accent' | 'error' | 'success' | 'warning' | 'info' | 'neutral'\n\n /** Disable button during processing. Default: true. Set false for cancel-by-click patterns. */\n processingDisabled?: boolean\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n variant,\n color,\n weight,\n size,\n asChild = false,\n shape,\n startIcon,\n endIcon,\n loading: loadingProp = false,\n loadingPosition = 'start',\n fullWidth = false,\n disabled,\n onClick,\n onClickAsync,\n asyncFeedbackDuration = 1500,\n processing: processingProp,\n processingColor,\n processingDisabled = true,\n children,\n ...props\n },\n ref,\n ) => {\n const group = useButtonGroup()\n const groupItem = useButtonGroupItem()\n const resolvedVariant = variant ?? group.variant\n const resolvedColor = color ?? group.color\n const resolvedWeight = weight ?? group.weight ?? 'semibold'\n const resolvedShape = shape ?? group.shape ?? 'default'\n const resolvedSize = size ?? group.size ?? 'md'\n // ButtonGroup can propagate disabled to all children\n const resolvedDisabled = disabled ?? group.disabled\n\n // When inside an attached ButtonGroup, adjust border-radius based on position\n const groupRadiusStyle = groupItem && group.attached !== false\n ? getGroupPositionStyle(groupItem.position, group.orientation ?? 'horizontal')\n : undefined\n // Stretch to fill when inside a vertical or fullWidth ButtonGroup\n const groupStretch = group._stretch ?? false\n\n const prefersReduced = useReducedMotion()\n\n // Refs + effect for smooth width transitions (must be before any early returns)\n const wrapperRef = React.useRef<HTMLSpanElement>(null)\n const btnRef = React.useRef<HTMLButtonElement | null>(null)\n const rafRef = React.useRef<number | undefined>(undefined)\n\n \n React.useEffect(() => {\n const btn = btnRef.current\n const wrapper = wrapperRef.current\n if (!btn || !wrapper || fullWidth || groupStretch || prefersReduced) return\n\n rafRef.current = requestAnimationFrame(() => {\n wrapper.style.width = 'auto'\n const w = btn.offsetWidth\n if (w > 0) {\n wrapper.getBoundingClientRect()\n wrapper.style.width = `${w}px`\n }\n })\n return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current) }\n }) // run on every render to catch content changes\n\n // Async state machine: idle → loading → success | error → idle\n type AsyncState = 'idle' | 'loading' | 'success' | 'error'\n const [asyncState, setAsyncState] = React.useState<AsyncState>('idle')\n const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)\n const isMountedRef = React.useRef(true)\n\n React.useEffect(() => () => {\n isMountedRef.current = false\n clearTimeout(timeoutRef.current)\n }, [])\n\n const handleAsyncClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (!onClickAsync || asyncState !== 'idle') return\n setAsyncState('loading')\n onClickAsync(e)\n .then(() => { if (isMountedRef.current) setAsyncState('success') })\n .catch(() => { if (isMountedRef.current) setAsyncState('error') })\n .finally(() => {\n if (isMountedRef.current) {\n timeoutRef.current = setTimeout(() => {\n if (isMountedRef.current) setAsyncState('idle')\n }, asyncFeedbackDuration)\n }\n })\n }\n\n const isAsync = !!onClickAsync\n const loading = isAsync ? asyncState === 'loading' : loadingProp\n const isAsyncFeedback = asyncState === 'success' || asyncState === 'error'\n\n // Processing: explicit prop takes priority, otherwise auto-processing during onClickAsync.\n // Processing is always OFF during async feedback (success/error) so the feedback colors show.\n const autoProcessing = isAsync && asyncState === 'loading' && !processingProp\n const processingSpeed: ProcessingSpeed | undefined = isAsyncFeedback ? undefined\n : processingProp === true ? 'working'\n : processingProp === false || !processingProp\n ? (autoProcessing ? 'working' : undefined)\n : processingProp\n const isProcessing = !!processingSpeed\n const resolvedProcessingColor = processingColor ?? resolvedColor ?? 'accent'\n\n if (asChild) {\n // Slot merges all props into the child element via cloneElement at runtime.\n // We cast here because SlotProps only types React.HTMLAttributes<HTMLElement>,\n // which excludes button-specific attrs like `disabled`.\n const slotProps = {\n className: cn(\n buttonVariants({ variant: resolvedVariant, color: resolvedColor, weight: resolvedWeight, size: resolvedSize }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n className,\n ),\n ref,\n disabled: resolvedDisabled || loading,\n 'aria-busy': loading || undefined,\n ...props,\n } as React.ComponentPropsWithRef<typeof Slot>\n return (\n <Slot {...slotProps}>\n <Slottable>{children}</Slottable>\n </Slot>\n )\n }\n\n const inset = iconInsetClass[resolvedSize] ?? { start: '', end: '' }\n // Dim icons on filled variants (Radix pattern — icon is decorative, text is primary)\n const dimIcon = resolvedVariant === 'solid' || resolvedVariant === 'soft' || resolvedVariant === 'outline'\n\n const renderStartSlot = () => {\n if (loading && loadingPosition === 'start') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', startIcon && inset.start)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (startIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.start, dimIcon && 'opacity-90')}>\n {normalizeIcon(startIcon)}\n </span>\n )\n }\n return null\n }\n\n const renderEndSlot = () => {\n if (loading && loadingPosition === 'end') {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center', endIcon && inset.end)}>\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n )\n }\n if (endIcon) {\n return (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', inset.end, dimIcon && 'opacity-90')}>\n {normalizeIcon(endIcon)}\n </span>\n )\n }\n return null\n }\n\n // Separate DevalokGrain elements (need to be direct button children for absolute positioning)\n // from text/other content (needs z-elevation above grain)\n const childArray = React.Children.toArray(children)\n const grainElements: React.ReactNode[] = []\n const contentElements: React.ReactNode[] = []\n childArray.forEach((child) => {\n if (React.isValidElement(child) && (child.type as { displayName?: string })?.displayName === 'DevalokGrain') {\n grainElements.push(child)\n } else {\n contentElements.push(child)\n }\n })\n\n const renderChildren = () => {\n if (loading && loadingPosition === 'center') {\n return (\n <span className=\"relative inline-flex items-center justify-center\">\n <span className=\"invisible\">{contentElements}</span>\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner size={BUTTON_TO_SPINNER_SIZE[resolvedSize]} variant=\"bare\" />\n </span>\n </span>\n )\n }\n // Only wrap in z-elevated span when grain is present (to sit above grain layers).\n // Without grain, render children directly to preserve flex layout.\n if (grainElements.length > 0) {\n return <span>{contentElements}</span>\n }\n return <>{contentElements}</>\n }\n\n // Async feedback: override color to show green/red\n const feedbackColorClass = isAsyncFeedback\n ? asyncState === 'success'\n ? 'bg-success-9 text-success-fg border-transparent hover:bg-success-9'\n : 'bg-error-9 text-error-fg border-transparent hover:bg-error-9'\n : undefined\n\n // Async feedback icon — uses Icon's draw animation for pen-stroke effect\n const asyncFeedbackIcon = isAsyncFeedback ? (\n <span className={cn('inline-flex shrink-0 items-center justify-center pointer-events-none', startIcon && inset.start)}>\n <Icon icon={asyncState === 'success' ? IconCheck : IconX} animate=\"draw\" />\n </span>\n ) : null\n\n const iconSize = BUTTON_TO_ICON_SIZE[resolvedSize] ?? 'md'\n\n const buttonEl = (\n <motion.button\n {...motionProps(props)}\n style={{ ...props.style, ...groupRadiusStyle }}\n className={cn(\n buttonVariants({\n // When processing (and not showing async feedback), force soft variant so ants pop\n variant: isProcessing && !isAsyncFeedback && resolvedVariant !== 'ghost' && resolvedVariant !== 'outline' && resolvedVariant !== 'link' ? 'soft' : resolvedVariant,\n color: resolvedColor,\n weight: resolvedWeight,\n size: resolvedSize,\n }),\n resolvedShape === 'pill' && 'rounded-pill',\n resolvedShape === 'pill' && pillPaddingClass[resolvedSize],\n (fullWidth || groupStretch) && 'w-full',\n // Asymmetric timing: hover-out is slow+relaxed, hover-in is fast+snappy (applied via hover: override)\n !loading && !isAsyncFeedback && 'transition-[color,background-color,border-color,box-shadow,transform,filter] duration-moderate-01 ease-productive-exit',\n !loading && !isAsyncFeedback && 'hover:duration-fast-02 hover:ease-productive-entrance',\n !loading && !isAsyncFeedback && 'active:scale-[0.95] active:brightness-[0.92] active:saturate-[1.1] active:duration-[0ms]',\n feedbackColorClass,\n isAsyncFeedback && 'transition-colors duration-moderate-01 ease-productive-standard',\n isProcessing && processingDisabled && 'pointer-events-none cursor-default',\n className,\n )}\n ref={(el: HTMLButtonElement | null) => {\n btnRef.current = el\n if (typeof ref === 'function') ref(el)\n else if (ref) (ref as React.MutableRefObject<HTMLButtonElement | null>).current = el\n }}\n disabled={resolvedDisabled || (loading && !isProcessing)}\n aria-busy={loading || isProcessing || undefined}\n aria-disabled={isProcessing && processingDisabled || undefined}\n onClick={isAsync ? handleAsyncClick : (isProcessing && processingDisabled ? undefined : onClick)}\n >\n {/* Grain layers render as direct children (need absolute positioning) */}\n {grainElements}\n {/* Content renders above grain via z-[2] span wrapper */}\n {isAsyncFeedback ? asyncFeedbackIcon : renderStartSlot()}\n {isAsyncFeedback ? contentElements : renderChildren()}\n {isAsyncFeedback ? null : renderEndSlot()}\n </motion.button>\n )\n\n // Always wrap in a positioned container so the overlay can render\n // as a sibling OUTSIDE the button (not affected by disabled opacity).\n // Keeping the wrapper always-on prevents React unmount/remount on\n // processing toggle, enabling smooth CSS transitions between states.\n return (\n <IconProvider size={iconSize}>\n <span\n ref={wrapperRef}\n className={cn('relative inline-flex', fullWidth && 'w-full')}\n style={{\n ...(fullWidth || groupStretch || prefersReduced ? undefined : { transition: 'width 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)' }),\n ...groupRadiusStyle,\n }}\n >\n {buttonEl}\n <ProcessingOverlay\n active={isProcessing}\n speed={processingSpeed ?? 'working'}\n color={resolvedProcessingColor}\n />\n </span>\n </IconProvider>\n )\n },\n)\nButton.displayName = 'Button'\n\nexport { Button }\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-input.d.ts","sourceRoot":"","sources":["../../src/ui/color-input.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAoF9B,KAAK,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;AAIxC,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC7F,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,gFAAgF;IAChF,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,CAAA;IAC7D,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,WAAW,CAAA;IAC3B,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAC/B;AAuDD,QAAA,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"color-input.d.ts","sourceRoot":"","sources":["../../src/ui/color-input.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAoF9B,KAAK,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;AAIxC,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC7F,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oCAAoC;IACpC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,gFAAgF;IAChF,OAAO,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,CAAA;IAC7D,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wDAAwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,WAAW,CAAA;IAC3B,2CAA2C;IAC3C,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAA;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAC/B;AAuDD,QAAA,MAAM,UAAU,wFA2Yf,CAAA;AAGD,OAAO,EAAE,UAAU,EAAE,CAAA"}
|
package/dist/ui/color-input.js
CHANGED
|
@@ -48,7 +48,7 @@ function g(e, t, n) {
|
|
|
48
48
|
};
|
|
49
49
|
return m(o(0), o(8), o(4));
|
|
50
50
|
}
|
|
51
|
-
var
|
|
51
|
+
var ee = [
|
|
52
52
|
{
|
|
53
53
|
hex: "#C53637",
|
|
54
54
|
label: "Red"
|
|
@@ -90,7 +90,7 @@ var _ = [
|
|
|
90
90
|
label: "Pink"
|
|
91
91
|
}
|
|
92
92
|
];
|
|
93
|
-
function
|
|
93
|
+
function te(e) {
|
|
94
94
|
let t = p(e);
|
|
95
95
|
if (!t) return !1;
|
|
96
96
|
let [n, r, i] = [
|
|
@@ -103,7 +103,7 @@ function v(e) {
|
|
|
103
103
|
});
|
|
104
104
|
return .2126 * n + .7152 * r + .0722 * i > .4;
|
|
105
105
|
}
|
|
106
|
-
function
|
|
106
|
+
function _({ label: e, value: t, onChange: r, onBlur: i, disabled: a, maxLength: o = 3, prefix: s, className: c, id: d }) {
|
|
107
107
|
return /* @__PURE__ */ u("div", {
|
|
108
108
|
className: n("flex flex-col gap-ds-01", c),
|
|
109
109
|
children: [/* @__PURE__ */ l("label", {
|
|
@@ -128,33 +128,33 @@ function y({ label: e, value: t, onChange: r, onBlur: i, disabled: a, maxLength:
|
|
|
128
128
|
})]
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
|
-
var
|
|
132
|
-
let [
|
|
131
|
+
var v = c.forwardRef(({ value: v = "#000000", onChange: y, presets: b, disabled: x = !1, showPicker: S = !0, defaultFormat: C = "hex", align: ne = "start", variant: re = "default", className: w, id: ie, ...T }, E) => {
|
|
132
|
+
let [D, O] = c.useState(C), [k, A] = c.useState(!1), j = c.useId(), M = r(), N = ie ?? M.inputId, [P, F] = c.useState(v), [I, L] = c.useState(null);
|
|
133
133
|
c.useEffect(() => {
|
|
134
|
-
L(
|
|
135
|
-
}, [
|
|
136
|
-
let [R, z] = c.useState(
|
|
137
|
-
|
|
134
|
+
F(v), L(null);
|
|
135
|
+
}, [v]);
|
|
136
|
+
let [R, z] = c.useState(v), [B, V] = c.useState([]), H = c.useRef(!1), U = (e) => {
|
|
137
|
+
x || (e && (z(P), V([])), L(null), A(e));
|
|
138
138
|
}, W = (e) => {
|
|
139
|
-
if (
|
|
139
|
+
if (x) return;
|
|
140
140
|
let t = (e.startsWith("#") ? e : `#${e}`).toLowerCase();
|
|
141
|
-
V((e) => e[e.length - 1] ===
|
|
141
|
+
V((e) => e[e.length - 1] === P ? e : [...e.slice(-19), P]), F(t), L(null), y?.(t);
|
|
142
142
|
}, G = (e) => {
|
|
143
|
-
if (
|
|
143
|
+
if (x) return;
|
|
144
144
|
let t = (e.startsWith("#") ? e : `#${e}`).toLowerCase();
|
|
145
|
-
H.current || (H.current = !0, V((e) => e[e.length - 1] ===
|
|
145
|
+
H.current || (H.current = !0, V((e) => e[e.length - 1] === P ? e : [...e.slice(-19), P])), F(t), y?.(t);
|
|
146
146
|
}, K = () => {
|
|
147
147
|
H.current = !1;
|
|
148
148
|
}, q = () => {
|
|
149
149
|
if (B.length === 0) return;
|
|
150
150
|
let e = B[B.length - 1];
|
|
151
|
-
V((e) => e.slice(0, -1)),
|
|
151
|
+
V((e) => e.slice(0, -1)), F(e), y?.(e);
|
|
152
152
|
}, J = () => {
|
|
153
|
-
|
|
154
|
-
}, Y =
|
|
153
|
+
F(R), y?.(R), V([]);
|
|
154
|
+
}, Y = b === !1 ? [] : b ? b.map((e) => typeof e == "string" ? {
|
|
155
155
|
hex: e,
|
|
156
156
|
label: e
|
|
157
|
-
} : e) :
|
|
157
|
+
} : e) : ee, X = p(P), Z = h(P), Q = (e, t) => {
|
|
158
158
|
if (!X) return;
|
|
159
159
|
let n = parseInt(t, 10);
|
|
160
160
|
if (isNaN(n)) return;
|
|
@@ -166,27 +166,27 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
166
166
|
if (isNaN(n)) return;
|
|
167
167
|
let r = Math.max(0, Math.min(e === "h" ? 360 : 100, n));
|
|
168
168
|
W(g(e === "h" ? r : Z.h, e === "s" ? r : Z.s, e === "l" ? r : Z.l));
|
|
169
|
-
},
|
|
169
|
+
}, ae = [
|
|
170
170
|
"hex",
|
|
171
171
|
"rgb",
|
|
172
172
|
"hsl"
|
|
173
173
|
];
|
|
174
174
|
return /* @__PURE__ */ l("div", {
|
|
175
|
-
ref:
|
|
176
|
-
className: n("inline-flex flex-col",
|
|
177
|
-
...
|
|
175
|
+
ref: E,
|
|
176
|
+
className: n("inline-flex flex-col", w),
|
|
177
|
+
...T,
|
|
178
178
|
children: /* @__PURE__ */ u(a, {
|
|
179
|
-
open:
|
|
179
|
+
open: k,
|
|
180
180
|
onOpenChange: U,
|
|
181
181
|
children: [/* @__PURE__ */ l(s, {
|
|
182
182
|
asChild: !0,
|
|
183
|
-
children:
|
|
183
|
+
children: re === "inline" ? /* @__PURE__ */ l(f.button, {
|
|
184
184
|
type: "button",
|
|
185
|
-
disabled:
|
|
186
|
-
className: n("group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium", "focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base",
|
|
185
|
+
disabled: x,
|
|
186
|
+
className: n("group flex items-center justify-center rounded-control px-ds-04 py-ds-02 font-mono text-body-sm font-medium", "focus:outline-hidden focus:ring-2 focus:ring-accent-9 focus:ring-offset-2 focus:ring-offset-surface-base", x && "cursor-not-allowed opacity-50"),
|
|
187
187
|
animate: {
|
|
188
|
-
backgroundColor:
|
|
189
|
-
color:
|
|
188
|
+
backgroundColor: P,
|
|
189
|
+
color: te(P) ? "rgba(0,0,0,0.8)" : "rgba(255,255,255,0.95)"
|
|
190
190
|
},
|
|
191
191
|
whileHover: {
|
|
192
192
|
y: -1,
|
|
@@ -194,26 +194,26 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
194
194
|
},
|
|
195
195
|
whileTap: { scale: .97 },
|
|
196
196
|
transition: t.smooth,
|
|
197
|
-
id:
|
|
198
|
-
"aria-describedby":
|
|
199
|
-
"aria-invalid":
|
|
200
|
-
"aria-label":
|
|
201
|
-
children:
|
|
197
|
+
id: N,
|
|
198
|
+
"aria-describedby": M.helperTextId,
|
|
199
|
+
"aria-invalid": M.state === "error" || void 0,
|
|
200
|
+
"aria-label": M.inputId ? void 0 : `Color picker: ${P}`,
|
|
201
|
+
children: P.toUpperCase()
|
|
202
202
|
}) : /* @__PURE__ */ u(f.button, {
|
|
203
203
|
type: "button",
|
|
204
|
-
disabled:
|
|
205
|
-
className: n("group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong", "hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9",
|
|
204
|
+
disabled: x,
|
|
205
|
+
className: n("group relative flex items-center overflow-hidden rounded-control border border-surface-border-strong", "hover:border-accent-7 focus:border-accent-7 focus:outline-hidden focus:ring-1 focus:ring-accent-9", x && "cursor-not-allowed opacity-50"),
|
|
206
206
|
whileHover: { scale: 1.02 },
|
|
207
207
|
whileTap: { scale: .98 },
|
|
208
208
|
transition: t.snappy,
|
|
209
|
-
id:
|
|
210
|
-
"aria-describedby":
|
|
211
|
-
"aria-invalid":
|
|
212
|
-
"aria-label":
|
|
209
|
+
id: N,
|
|
210
|
+
"aria-describedby": M.helperTextId,
|
|
211
|
+
"aria-invalid": M.state === "error" || void 0,
|
|
212
|
+
"aria-label": M.inputId ? void 0 : `Color picker: ${P}`,
|
|
213
213
|
children: [
|
|
214
214
|
/* @__PURE__ */ l(f.span, {
|
|
215
215
|
className: "absolute inset-0",
|
|
216
|
-
animate: { background: `linear-gradient(to right, ${
|
|
216
|
+
animate: { background: `linear-gradient(to right, ${P} 0%, ${P} 35%, transparent 70%)` },
|
|
217
217
|
transition: { duration: .3 }
|
|
218
218
|
}),
|
|
219
219
|
/* @__PURE__ */ l("span", {
|
|
@@ -225,25 +225,25 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
225
225
|
}),
|
|
226
226
|
/* @__PURE__ */ l("span", {
|
|
227
227
|
className: "relative z-10 py-ds-02 pl-6 pr-ds-03 font-mono text-body-sm text-surface-fg",
|
|
228
|
-
children:
|
|
228
|
+
children: P.toUpperCase()
|
|
229
229
|
})
|
|
230
230
|
]
|
|
231
231
|
})
|
|
232
232
|
}), /* @__PURE__ */ l(o, {
|
|
233
233
|
role: "dialog",
|
|
234
234
|
"aria-label": "Color picker",
|
|
235
|
-
align:
|
|
235
|
+
align: ne,
|
|
236
236
|
sideOffset: 8,
|
|
237
237
|
className: "w-[272px] rounded-overlay-lg bg-surface-overlay p-0 shadow-floating",
|
|
238
238
|
children: /* @__PURE__ */ u("div", {
|
|
239
239
|
className: "flex flex-col",
|
|
240
240
|
children: [
|
|
241
|
-
|
|
241
|
+
S && /* @__PURE__ */ l("div", {
|
|
242
242
|
className: "p-ds-04 pb-ds-03",
|
|
243
243
|
onPointerUp: K,
|
|
244
244
|
onPointerLeave: K,
|
|
245
245
|
children: /* @__PURE__ */ l(i, {
|
|
246
|
-
color:
|
|
246
|
+
color: P,
|
|
247
247
|
onChange: G,
|
|
248
248
|
className: "w-full!",
|
|
249
249
|
style: { height: 160 }
|
|
@@ -253,12 +253,12 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
253
253
|
className: "border-t border-surface-border px-ds-04 py-ds-03",
|
|
254
254
|
children: [/* @__PURE__ */ l("div", {
|
|
255
255
|
className: "mb-ds-03 flex items-center gap-ds-01",
|
|
256
|
-
children:
|
|
256
|
+
children: ae.map((e) => /* @__PURE__ */ u("button", {
|
|
257
257
|
type: "button",
|
|
258
|
-
onClick: () =>
|
|
259
|
-
className: n("relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors",
|
|
260
|
-
children: [
|
|
261
|
-
layoutId: `color-input-format-pill-${
|
|
258
|
+
onClick: () => O(e),
|
|
259
|
+
className: n("relative min-h-6 rounded-control-inner px-ds-02 py-px text-label-xs font-semibold uppercase tracking-wider transition-colors", D === e ? "text-accent-11" : "text-surface-fg-muted hover:text-surface-fg"),
|
|
260
|
+
children: [D === e && /* @__PURE__ */ l(f.span, {
|
|
261
|
+
layoutId: `color-input-format-pill-${j}`,
|
|
262
262
|
className: "absolute inset-0 rounded-control-inner bg-accent-3",
|
|
263
263
|
transition: t.snappy
|
|
264
264
|
}), /* @__PURE__ */ l("span", {
|
|
@@ -269,7 +269,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
269
269
|
}), /* @__PURE__ */ u(d, {
|
|
270
270
|
mode: "wait",
|
|
271
271
|
children: [
|
|
272
|
-
|
|
272
|
+
D === "hex" && /* @__PURE__ */ l(f.div, {
|
|
273
273
|
initial: {
|
|
274
274
|
opacity: 0,
|
|
275
275
|
y: 4
|
|
@@ -284,24 +284,24 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
284
284
|
},
|
|
285
285
|
transition: { duration: e.moderate01 },
|
|
286
286
|
className: "flex gap-ds-02",
|
|
287
|
-
children: /* @__PURE__ */ l(
|
|
288
|
-
id: `${
|
|
287
|
+
children: /* @__PURE__ */ l(_, {
|
|
288
|
+
id: `${j}-hex`,
|
|
289
289
|
label: "Hex",
|
|
290
|
-
value: I.replace("#", "").toUpperCase(),
|
|
290
|
+
value: I ?? P.replace("#", "").toUpperCase(),
|
|
291
291
|
onChange: (e) => {
|
|
292
292
|
let t = e.replace(/[^0-9a-fA-F]/g, "").slice(0, 6);
|
|
293
|
-
t.length === 6 && W(`#${t}`);
|
|
293
|
+
L(t.toUpperCase()), t.length === 6 && W(`#${t}`);
|
|
294
294
|
},
|
|
295
295
|
onBlur: () => {
|
|
296
|
-
|
|
296
|
+
L(null);
|
|
297
297
|
},
|
|
298
|
-
disabled:
|
|
298
|
+
disabled: x,
|
|
299
299
|
maxLength: 6,
|
|
300
300
|
prefix: "#",
|
|
301
301
|
className: "flex-1"
|
|
302
302
|
})
|
|
303
303
|
}, "hex"),
|
|
304
|
-
|
|
304
|
+
D === "rgb" && X && /* @__PURE__ */ u(f.div, {
|
|
305
305
|
initial: {
|
|
306
306
|
opacity: 0,
|
|
307
307
|
y: 4
|
|
@@ -317,33 +317,33 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
317
317
|
transition: { duration: e.moderate01 },
|
|
318
318
|
className: "flex gap-ds-02",
|
|
319
319
|
children: [
|
|
320
|
-
/* @__PURE__ */ l(
|
|
321
|
-
id: `${
|
|
320
|
+
/* @__PURE__ */ l(_, {
|
|
321
|
+
id: `${j}-r`,
|
|
322
322
|
label: "R",
|
|
323
323
|
value: String(X.r),
|
|
324
324
|
onChange: (e) => Q("r", e),
|
|
325
|
-
disabled:
|
|
325
|
+
disabled: x,
|
|
326
326
|
className: "flex-1"
|
|
327
327
|
}),
|
|
328
|
-
/* @__PURE__ */ l(
|
|
329
|
-
id: `${
|
|
328
|
+
/* @__PURE__ */ l(_, {
|
|
329
|
+
id: `${j}-g`,
|
|
330
330
|
label: "G",
|
|
331
331
|
value: String(X.g),
|
|
332
332
|
onChange: (e) => Q("g", e),
|
|
333
|
-
disabled:
|
|
333
|
+
disabled: x,
|
|
334
334
|
className: "flex-1"
|
|
335
335
|
}),
|
|
336
|
-
/* @__PURE__ */ l(
|
|
337
|
-
id: `${
|
|
336
|
+
/* @__PURE__ */ l(_, {
|
|
337
|
+
id: `${j}-b`,
|
|
338
338
|
label: "B",
|
|
339
339
|
value: String(X.b),
|
|
340
340
|
onChange: (e) => Q("b", e),
|
|
341
|
-
disabled:
|
|
341
|
+
disabled: x,
|
|
342
342
|
className: "flex-1"
|
|
343
343
|
})
|
|
344
344
|
]
|
|
345
345
|
}, "rgb"),
|
|
346
|
-
|
|
346
|
+
D === "hsl" && Z && /* @__PURE__ */ u(f.div, {
|
|
347
347
|
initial: {
|
|
348
348
|
opacity: 0,
|
|
349
349
|
y: 4
|
|
@@ -359,28 +359,28 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
359
359
|
transition: { duration: e.moderate01 },
|
|
360
360
|
className: "flex gap-ds-02",
|
|
361
361
|
children: [
|
|
362
|
-
/* @__PURE__ */ l(
|
|
363
|
-
id: `${
|
|
362
|
+
/* @__PURE__ */ l(_, {
|
|
363
|
+
id: `${j}-h`,
|
|
364
364
|
label: "H",
|
|
365
365
|
value: String(Z.h),
|
|
366
366
|
onChange: (e) => $("h", e),
|
|
367
|
-
disabled:
|
|
367
|
+
disabled: x,
|
|
368
368
|
className: "flex-1"
|
|
369
369
|
}),
|
|
370
|
-
/* @__PURE__ */ l(
|
|
371
|
-
id: `${
|
|
370
|
+
/* @__PURE__ */ l(_, {
|
|
371
|
+
id: `${j}-s`,
|
|
372
372
|
label: "S",
|
|
373
373
|
value: String(Z.s),
|
|
374
374
|
onChange: (e) => $("s", e),
|
|
375
|
-
disabled:
|
|
375
|
+
disabled: x,
|
|
376
376
|
className: "flex-1"
|
|
377
377
|
}),
|
|
378
|
-
/* @__PURE__ */ l(
|
|
379
|
-
id: `${
|
|
378
|
+
/* @__PURE__ */ l(_, {
|
|
379
|
+
id: `${j}-l`,
|
|
380
380
|
label: "L",
|
|
381
381
|
value: String(Z.l),
|
|
382
382
|
onChange: (e) => $("l", e),
|
|
383
|
-
disabled:
|
|
383
|
+
disabled: x,
|
|
384
384
|
className: "flex-1"
|
|
385
385
|
})
|
|
386
386
|
]
|
|
@@ -393,10 +393,10 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
393
393
|
children: /* @__PURE__ */ l("div", {
|
|
394
394
|
className: "flex flex-wrap gap-ds-02",
|
|
395
395
|
children: Y.map((e, r) => {
|
|
396
|
-
let i =
|
|
396
|
+
let i = P.toLowerCase() === e.hex.toLowerCase();
|
|
397
397
|
return /* @__PURE__ */ l(f.button, {
|
|
398
398
|
type: "button",
|
|
399
|
-
disabled:
|
|
399
|
+
disabled: x,
|
|
400
400
|
onClick: () => W(e.hex),
|
|
401
401
|
initial: {
|
|
402
402
|
opacity: 0,
|
|
@@ -412,7 +412,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
412
412
|
...t.bouncy,
|
|
413
413
|
delay: r * .02
|
|
414
414
|
},
|
|
415
|
-
className: n("h-6 w-6 rounded-control-inner border", i ? "border-accent-7 ring-2 ring-accent-9/30" : "border-surface-border hover:border-surface-border-strong",
|
|
415
|
+
className: n("h-6 w-6 rounded-control-inner border", i ? "border-accent-7 ring-2 ring-accent-9/30" : "border-surface-border hover:border-surface-border-strong", x && "cursor-not-allowed opacity-50"),
|
|
416
416
|
style: { backgroundColor: e.hex },
|
|
417
417
|
title: e.label,
|
|
418
418
|
"aria-label": `${e.label}: ${e.hex}`
|
|
@@ -420,7 +420,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
420
420
|
})
|
|
421
421
|
})
|
|
422
422
|
}),
|
|
423
|
-
(B.length > 0 ||
|
|
423
|
+
(B.length > 0 || P !== R) && /* @__PURE__ */ u(f.div, {
|
|
424
424
|
initial: {
|
|
425
425
|
opacity: 0,
|
|
426
426
|
height: 0
|
|
@@ -451,7 +451,7 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
451
451
|
className: "min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-surface-fg",
|
|
452
452
|
children: "Undo"
|
|
453
453
|
}),
|
|
454
|
-
|
|
454
|
+
P !== R && /* @__PURE__ */ l("button", {
|
|
455
455
|
type: "button",
|
|
456
456
|
onClick: J,
|
|
457
457
|
className: "min-h-6 rounded-control-inner px-ds-02 py-px text-caption font-medium text-surface-fg-muted transition-colors hover:text-error-11",
|
|
@@ -465,6 +465,6 @@ var b = c.forwardRef(({ value: b = "#000000", onChange: x, presets: S, disabled:
|
|
|
465
465
|
})
|
|
466
466
|
});
|
|
467
467
|
});
|
|
468
|
-
|
|
468
|
+
v.displayName = "ColorInput";
|
|
469
469
|
//#endregion
|
|
470
|
-
export {
|
|
470
|
+
export { v as ColorInput };
|