@epilot/spark-ui 0.15.1 → 0.16.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/dist/components/accordion.cjs +4 -4
- package/dist/components/accordion.cjs.map +1 -1
- package/dist/components/accordion.d.ts +1 -1
- package/dist/components/accordion.js +4 -4
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/attachment.cjs +3 -3
- package/dist/components/attachment.cjs.map +1 -1
- package/dist/components/attachment.js +3 -3
- package/dist/components/attachment.js.map +1 -1
- package/dist/components/badge.cjs +1 -1
- package/dist/components/badge.cjs.map +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/badge.js.map +1 -1
- package/dist/components/bar-chart.js +1 -1
- package/dist/components/box.cjs +1 -1
- package/dist/components/box.cjs.map +1 -1
- package/dist/components/box.d.cts +1 -1
- package/dist/components/box.d.ts +1 -1
- package/dist/components/box.js +1 -1
- package/dist/components/box.js.map +1 -1
- package/dist/components/breadcrumbs.cjs +1 -1
- package/dist/components/breadcrumbs.cjs.map +1 -1
- package/dist/components/breadcrumbs.js +1 -1
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/bubble.cjs +1 -1
- package/dist/components/bubble.cjs.map +1 -1
- package/dist/components/bubble.d.cts +1 -1
- package/dist/components/bubble.d.ts +1 -1
- package/dist/components/bubble.js +1 -1
- package/dist/components/bubble.js.map +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/card.cjs +2 -2
- package/dist/components/card.cjs.map +1 -1
- package/dist/components/card.d.cts +1 -1
- package/dist/components/card.d.ts +1 -1
- package/dist/components/card.js +2 -2
- package/dist/components/card.js.map +1 -1
- package/dist/components/checkbox.cjs +1 -1
- package/dist/components/checkbox.cjs.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/day-of-week-picker.cjs +2 -2
- package/dist/components/day-of-week-picker.cjs.map +1 -1
- package/dist/components/day-of-week-picker.js +2 -2
- package/dist/components/day-of-week-picker.js.map +1 -1
- package/dist/components/device-card.cjs +2 -2
- package/dist/components/device-card.cjs.map +1 -1
- package/dist/components/device-card.js +2 -2
- package/dist/components/device-card.js.map +1 -1
- package/dist/components/drawer.cjs +1 -1
- package/dist/components/drawer.cjs.map +1 -1
- package/dist/components/drawer.js +1 -1
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/dropdown-menu.cjs +4 -4
- package/dist/components/dropdown-menu.cjs.map +1 -1
- package/dist/components/dropdown-menu.js +4 -4
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/empty-state.cjs +1 -1
- package/dist/components/empty-state.cjs.map +1 -1
- package/dist/components/empty-state.js +1 -1
- package/dist/components/empty-state.js.map +1 -1
- package/dist/components/feed-in-hero.cjs +1 -1
- package/dist/components/feed-in-hero.cjs.map +1 -1
- package/dist/components/feed-in-hero.js +1 -1
- package/dist/components/feed-in-hero.js.map +1 -1
- package/dist/components/field.cjs +43 -8
- package/dist/components/field.cjs.map +1 -1
- package/dist/components/field.d.cts +7 -0
- package/dist/components/field.d.ts +7 -0
- package/dist/components/field.js +43 -8
- package/dist/components/field.js.map +1 -1
- package/dist/components/info-block.cjs +2 -2
- package/dist/components/info-block.cjs.map +1 -1
- package/dist/components/info-block.d.cts +1 -1
- package/dist/components/info-block.d.ts +1 -1
- package/dist/components/info-block.js +2 -2
- package/dist/components/info-block.js.map +1 -1
- package/dist/components/input-group.cjs +1 -1
- package/dist/components/input-group.cjs.map +1 -1
- package/dist/components/input-group.js +1 -1
- package/dist/components/input-group.js.map +1 -1
- package/dist/components/input-otp.cjs +3 -2
- package/dist/components/input-otp.cjs.map +1 -1
- package/dist/components/input-otp.js +3 -2
- package/dist/components/input-otp.js.map +1 -1
- package/dist/components/input.cjs +3 -2
- package/dist/components/input.cjs.map +1 -1
- package/dist/components/input.js +3 -2
- package/dist/components/input.js.map +1 -1
- package/dist/components/line-chart.cjs +1 -1
- package/dist/components/line-chart.js +2 -2
- package/dist/components/list.cjs +10 -10
- package/dist/components/list.cjs.map +1 -1
- package/dist/components/list.d.cts +1 -1
- package/dist/components/list.d.ts +1 -1
- package/dist/components/list.js +10 -10
- package/dist/components/list.js.map +1 -1
- package/dist/components/marker.d.cts +1 -1
- package/dist/components/marker.d.ts +1 -1
- package/dist/components/message-scroller.cjs +1 -1
- package/dist/components/message-scroller.js +1 -1
- package/dist/components/page-header.d.cts +1 -1
- package/dist/components/page-header.d.ts +1 -1
- package/dist/components/power-history-chart.cjs +1 -1
- package/dist/components/power-history-chart.js +2 -2
- package/dist/components/power-history.cjs +1 -1
- package/dist/components/power-history.js +1 -1
- package/dist/components/power-network.cjs +7 -7
- package/dist/components/power-network.cjs.map +1 -1
- package/dist/components/power-network.js +7 -7
- package/dist/components/power-network.js.map +1 -1
- package/dist/components/schedule-list.cjs +3 -3
- package/dist/components/schedule-list.cjs.map +1 -1
- package/dist/components/schedule-list.js +3 -3
- package/dist/components/schedule-list.js.map +1 -1
- package/dist/components/select.cjs +4 -3
- package/dist/components/select.cjs.map +1 -1
- package/dist/components/select.js +4 -3
- package/dist/components/select.js.map +1 -1
- package/dist/components/series-legend.cjs +1 -1
- package/dist/components/series-legend.cjs.map +1 -1
- package/dist/components/series-legend.js +1 -1
- package/dist/components/series-legend.js.map +1 -1
- package/dist/components/skeleton.cjs +1 -1
- package/dist/components/skeleton.cjs.map +1 -1
- package/dist/components/skeleton.js +1 -1
- package/dist/components/skeleton.js.map +1 -1
- package/dist/components/stat-card.cjs +1 -1
- package/dist/components/stat-card.cjs.map +1 -1
- package/dist/components/stat-card.js +1 -1
- package/dist/components/stat-card.js.map +1 -1
- package/dist/components/stepper.cjs +3 -3
- package/dist/components/stepper.cjs.map +1 -1
- package/dist/components/stepper.js +3 -3
- package/dist/components/stepper.js.map +1 -1
- package/dist/components/textarea.cjs +3 -2
- package/dist/components/textarea.cjs.map +1 -1
- package/dist/components/textarea.js +3 -2
- package/dist/components/textarea.js.map +1 -1
- package/dist/components/time-picker.cjs +1 -1
- package/dist/components/time-picker.cjs.map +1 -1
- package/dist/components/time-picker.js +1 -1
- package/dist/components/time-picker.js.map +1 -1
- package/dist/components/toast.cjs +1 -1
- package/dist/components/toast.cjs.map +1 -1
- package/dist/components/toast.js +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/styles/theme.css +1 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.cjs","names":["React","useTheme","Skeleton","Separator"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n const ariaDescribedBy =\n [descriptionId, options?.ariaDescribedBy].filter(Boolean).join(' ') ||\n undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n return { field, id, ariaDescribedBy, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell is the box\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-lg px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n ...props\n}: FieldProps) {\n const id = useId()\n const [hasDescription, setHasDescription] = React.useState(false)\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-0.5 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray-light transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('mt-0.5 text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn('mt-0.5 text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"field.cjs","names":["React","useTheme","Skeleton","Separator"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n errorId: string\n hasError: boolean\n setHasError: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const errorId = field?.hasError ? field.errorId : undefined\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n // error before hint: the actionable message should be announced first\n const ariaDescribedBy =\n [errorId, descriptionId, options?.ariaDescribedBy]\n .filter(Boolean)\n .join(' ') || undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const ariaInvalid = field?.hasError || undefined\n return { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell IS the input's box —\n // rounded-md tracks Input/Select/etc.'s own control radius, not the container one.\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-md px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n 'data-invalid'?: boolean | 'true' | 'false'\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n 'data-invalid': dataInvalid,\n ...props\n}: FieldProps) {\n const id = useId()\n const [descriptionCount, setDescriptionCount] = React.useState(0)\n const [errorCount, setErrorCount] = React.useState(0)\n // counts, not flags: one slot unmounting must not clear what siblings still need\n const setHasDescription = React.useCallback(\n (has: boolean) => setDescriptionCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const setHasError = React.useCallback(\n (has: boolean) => setErrorCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const hasDescription = descriptionCount > 0\n const hasError = errorCount > 0\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n errorId: `${fieldId}-error`,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n setHasDescription,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n data-invalid={dataInvalid ?? (hasError || undefined)}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-0.5 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray-light transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('mt-0.5 text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n id,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const field = useFieldContext()\n const setHasError = field?.setHasError\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n const hasContent = Boolean(content)\n // a custom id means no element carries field.errorId, so don't advertise it\n const hasCustomId = id != null\n\n // must run before the empty-content early return to keep hook order stable\n React.useEffect(() => {\n if (!setHasError || !hasContent || hasCustomId) return\n setHasError(true)\n return () => setHasError(false)\n }, [setHasError, hasContent, hasCustomId])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n id={id ?? field?.errorId}\n className={cn('mt-0.5 text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
|
|
@@ -10,6 +10,9 @@ type FieldContextValue = {
|
|
|
10
10
|
descriptionId: string;
|
|
11
11
|
hasDescription: boolean;
|
|
12
12
|
setHasDescription: (has: boolean) => void;
|
|
13
|
+
errorId: string;
|
|
14
|
+
hasError: boolean;
|
|
15
|
+
setHasError: (has: boolean) => void;
|
|
13
16
|
readOnly: boolean;
|
|
14
17
|
labelPosition: SparkLabelPosition;
|
|
15
18
|
inputStyle: SparkInputStyle;
|
|
@@ -24,6 +27,7 @@ declare function useFieldControl(options?: {
|
|
|
24
27
|
field: FieldContextValue | null;
|
|
25
28
|
id: string | undefined;
|
|
26
29
|
ariaDescribedBy: string | undefined;
|
|
30
|
+
ariaInvalid: true | undefined;
|
|
27
31
|
inputStyle: SparkInputStyle;
|
|
28
32
|
inputColor: SparkInputColor;
|
|
29
33
|
};
|
|
@@ -47,6 +51,7 @@ interface FieldProps extends React$1.ComponentProps<'div'> {
|
|
|
47
51
|
inputStyle?: SparkInputStyle;
|
|
48
52
|
inputColor?: SparkInputColor;
|
|
49
53
|
readOnly?: boolean;
|
|
54
|
+
'data-invalid'?: boolean | 'true' | 'false';
|
|
50
55
|
}
|
|
51
56
|
declare function Field({
|
|
52
57
|
className,
|
|
@@ -55,6 +60,7 @@ declare function Field({
|
|
|
55
60
|
inputStyle: inputStyleProp,
|
|
56
61
|
inputColor: inputColorProp,
|
|
57
62
|
readOnly,
|
|
63
|
+
'data-invalid': dataInvalid,
|
|
58
64
|
...props
|
|
59
65
|
}: FieldProps): import("react/jsx-runtime").JSX.Element;
|
|
60
66
|
declare function FieldContent({
|
|
@@ -109,6 +115,7 @@ declare function FieldError({
|
|
|
109
115
|
className,
|
|
110
116
|
children,
|
|
111
117
|
errors,
|
|
118
|
+
id,
|
|
112
119
|
...props
|
|
113
120
|
}: React$1.ComponentProps<'div'> & {
|
|
114
121
|
errors?: Array<{
|
|
@@ -10,6 +10,9 @@ type FieldContextValue = {
|
|
|
10
10
|
descriptionId: string;
|
|
11
11
|
hasDescription: boolean;
|
|
12
12
|
setHasDescription: (has: boolean) => void;
|
|
13
|
+
errorId: string;
|
|
14
|
+
hasError: boolean;
|
|
15
|
+
setHasError: (has: boolean) => void;
|
|
13
16
|
readOnly: boolean;
|
|
14
17
|
labelPosition: SparkLabelPosition;
|
|
15
18
|
inputStyle: SparkInputStyle;
|
|
@@ -24,6 +27,7 @@ declare function useFieldControl(options?: {
|
|
|
24
27
|
field: FieldContextValue | null;
|
|
25
28
|
id: string | undefined;
|
|
26
29
|
ariaDescribedBy: string | undefined;
|
|
30
|
+
ariaInvalid: true | undefined;
|
|
27
31
|
inputStyle: SparkInputStyle;
|
|
28
32
|
inputColor: SparkInputColor;
|
|
29
33
|
};
|
|
@@ -47,6 +51,7 @@ interface FieldProps extends React$1.ComponentProps<'div'> {
|
|
|
47
51
|
inputStyle?: SparkInputStyle;
|
|
48
52
|
inputColor?: SparkInputColor;
|
|
49
53
|
readOnly?: boolean;
|
|
54
|
+
'data-invalid'?: boolean | 'true' | 'false';
|
|
50
55
|
}
|
|
51
56
|
declare function Field({
|
|
52
57
|
className,
|
|
@@ -55,6 +60,7 @@ declare function Field({
|
|
|
55
60
|
inputStyle: inputStyleProp,
|
|
56
61
|
inputColor: inputColorProp,
|
|
57
62
|
readOnly,
|
|
63
|
+
'data-invalid': dataInvalid,
|
|
58
64
|
...props
|
|
59
65
|
}: FieldProps): import("react/jsx-runtime").JSX.Element;
|
|
60
66
|
declare function FieldContent({
|
|
@@ -109,6 +115,7 @@ declare function FieldError({
|
|
|
109
115
|
className,
|
|
110
116
|
children,
|
|
111
117
|
errors,
|
|
118
|
+
id,
|
|
112
119
|
...props
|
|
113
120
|
}: React$1.ComponentProps<'div'> & {
|
|
114
121
|
errors?: Array<{
|
package/dist/components/field.js
CHANGED
|
@@ -16,12 +16,21 @@ function useFieldContext() {
|
|
|
16
16
|
function useFieldControl(options) {
|
|
17
17
|
const field = useFieldContext();
|
|
18
18
|
const theme = useTheme();
|
|
19
|
+
const id = options?.id ?? field?.id;
|
|
20
|
+
const ariaDescribedBy = [
|
|
21
|
+
field?.hasError ? field.errorId : void 0,
|
|
22
|
+
field?.hasDescription ? field.descriptionId : void 0,
|
|
23
|
+
options?.ariaDescribedBy
|
|
24
|
+
].filter(Boolean).join(" ") || void 0;
|
|
25
|
+
const inputStyle = options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? "soft";
|
|
26
|
+
const inputColor = field?.inputColor ?? theme.inputColor ?? "brand";
|
|
19
27
|
return {
|
|
20
28
|
field,
|
|
21
|
-
id
|
|
22
|
-
ariaDescribedBy
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
id,
|
|
30
|
+
ariaDescribedBy,
|
|
31
|
+
ariaInvalid: field?.hasError || void 0,
|
|
32
|
+
inputStyle,
|
|
33
|
+
inputColor
|
|
25
34
|
};
|
|
26
35
|
}
|
|
27
36
|
function FieldSet({ className, ...props }) {
|
|
@@ -49,7 +58,7 @@ function FieldGroup({ className, ...props }) {
|
|
|
49
58
|
const fieldVariants = cva("group/field relative flex w-full flex-col data-[invalid=true]:text-error-active", {
|
|
50
59
|
variants: {
|
|
51
60
|
labelPosition: {
|
|
52
|
-
inset: "gap-y-1 rounded-
|
|
61
|
+
inset: "gap-y-1 rounded-md px-4 py-3",
|
|
53
62
|
outset: "gap-y-2"
|
|
54
63
|
},
|
|
55
64
|
inputStyle: {
|
|
@@ -117,9 +126,14 @@ const fieldVariants = cva("group/field relative flex w-full flex-col data-[inval
|
|
|
117
126
|
}
|
|
118
127
|
]
|
|
119
128
|
});
|
|
120
|
-
function Field({ className, children, labelPosition: labelPositionProp, inputStyle: inputStyleProp, inputColor: inputColorProp, readOnly = false, ...props }) {
|
|
129
|
+
function Field({ className, children, labelPosition: labelPositionProp, inputStyle: inputStyleProp, inputColor: inputColorProp, readOnly = false, "data-invalid": dataInvalid, ...props }) {
|
|
121
130
|
const id = useId();
|
|
122
|
-
const [
|
|
131
|
+
const [descriptionCount, setDescriptionCount] = React$1.useState(0);
|
|
132
|
+
const [errorCount, setErrorCount] = React$1.useState(0);
|
|
133
|
+
const setHasDescription = React$1.useCallback((has) => setDescriptionCount((n) => n + (has ? 1 : -1)), []);
|
|
134
|
+
const setHasError = React$1.useCallback((has) => setErrorCount((n) => n + (has ? 1 : -1)), []);
|
|
135
|
+
const hasDescription = descriptionCount > 0;
|
|
136
|
+
const hasError = errorCount > 0;
|
|
123
137
|
const theme = useTheme();
|
|
124
138
|
const labelPosition = labelPositionProp ?? theme.labelPosition ?? "inset";
|
|
125
139
|
const inputStyle = inputStyleProp ?? theme.inputStyle ?? "soft";
|
|
@@ -132,6 +146,9 @@ function Field({ className, children, labelPosition: labelPositionProp, inputSty
|
|
|
132
146
|
descriptionId: `${fieldId}-description`,
|
|
133
147
|
hasDescription,
|
|
134
148
|
setHasDescription,
|
|
149
|
+
errorId: `${fieldId}-error`,
|
|
150
|
+
hasError,
|
|
151
|
+
setHasError,
|
|
135
152
|
readOnly,
|
|
136
153
|
labelPosition,
|
|
137
154
|
inputStyle,
|
|
@@ -140,6 +157,9 @@ function Field({ className, children, labelPosition: labelPositionProp, inputSty
|
|
|
140
157
|
fieldId,
|
|
141
158
|
labelId,
|
|
142
159
|
hasDescription,
|
|
160
|
+
setHasDescription,
|
|
161
|
+
hasError,
|
|
162
|
+
setHasError,
|
|
143
163
|
readOnly,
|
|
144
164
|
labelPosition,
|
|
145
165
|
inputStyle,
|
|
@@ -153,6 +173,7 @@ function Field({ className, children, labelPosition: labelPositionProp, inputSty
|
|
|
153
173
|
"data-label-position": labelPosition,
|
|
154
174
|
"data-input-style": inputStyle,
|
|
155
175
|
"data-input-color": inputColor,
|
|
176
|
+
"data-invalid": dataInvalid ?? (hasError || void 0),
|
|
156
177
|
"aria-labelledby": readOnly ? labelId : void 0,
|
|
157
178
|
className: cn(fieldVariants({
|
|
158
179
|
labelPosition,
|
|
@@ -249,7 +270,9 @@ function FieldSeparator({ children, className, ...props }) {
|
|
|
249
270
|
})]
|
|
250
271
|
});
|
|
251
272
|
}
|
|
252
|
-
function FieldError({ className, children, errors, ...props }) {
|
|
273
|
+
function FieldError({ className, children, errors, id, ...props }) {
|
|
274
|
+
const field = useFieldContext();
|
|
275
|
+
const setHasError = field?.setHasError;
|
|
253
276
|
const content = React$1.useMemo(() => {
|
|
254
277
|
if (children) return children;
|
|
255
278
|
if (!errors?.length) return null;
|
|
@@ -260,10 +283,22 @@ function FieldError({ className, children, errors, ...props }) {
|
|
|
260
283
|
children: unique.map((error, index) => error?.message && /* @__PURE__ */ jsx("li", { children: error.message }, index))
|
|
261
284
|
});
|
|
262
285
|
}, [children, errors]);
|
|
286
|
+
const hasContent = Boolean(content);
|
|
287
|
+
const hasCustomId = id != null;
|
|
288
|
+
React$1.useEffect(() => {
|
|
289
|
+
if (!setHasError || !hasContent || hasCustomId) return;
|
|
290
|
+
setHasError(true);
|
|
291
|
+
return () => setHasError(false);
|
|
292
|
+
}, [
|
|
293
|
+
setHasError,
|
|
294
|
+
hasContent,
|
|
295
|
+
hasCustomId
|
|
296
|
+
]);
|
|
263
297
|
if (!content) return null;
|
|
264
298
|
return /* @__PURE__ */ jsx("div", {
|
|
265
299
|
role: "alert",
|
|
266
300
|
"data-slot": "field-error",
|
|
301
|
+
id: id ?? field?.errorId,
|
|
267
302
|
className: cn("mt-0.5 text-sm font-normal text-error", className),
|
|
268
303
|
...props,
|
|
269
304
|
children: content
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","names":["React"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n const ariaDescribedBy =\n [descriptionId, options?.ariaDescribedBy].filter(Boolean).join(' ') ||\n undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n return { field, id, ariaDescribedBy, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell is the box\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-lg px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n ...props\n}: FieldProps) {\n const id = useId()\n const [hasDescription, setHasDescription] = React.useState(false)\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-0.5 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray-light transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('mt-0.5 text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn('mt-0.5 text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"field.js","names":["React"],"sources":["../../src/components/field.tsx"],"sourcesContent":["'use client'\n\nimport { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { useId } from 'react'\nimport type {\n SparkInputColor,\n SparkInputStyle,\n SparkLabelPosition,\n} from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { Separator } from './separator'\nimport { Skeleton } from './skeleton'\nimport { useTheme } from './theme'\n\ntype FieldContextValue = {\n id: string\n labelId: string\n descriptionId: string\n hasDescription: boolean\n setHasDescription: (has: boolean) => void\n errorId: string\n hasError: boolean\n setHasError: (has: boolean) => void\n readOnly: boolean\n labelPosition: SparkLabelPosition\n inputStyle: SparkInputStyle\n inputColor: SparkInputColor\n}\n\nconst FieldContext = React.createContext<FieldContextValue | null>(null)\n\nexport function useFieldContext() {\n return React.useContext(FieldContext)\n}\n\n// Field→Theme→default resolution + id/aria-describedby wiring, shared by every\n// control that can sit inside a Field (Input, SelectTrigger, …) so they can't\n// drift on how a style/color/id resolves. `variant` is the control's own\n// per-instance override (already normalized — e.g. Input maps its 'none' to\n// undefined before calling this).\nexport function useFieldControl(options?: {\n id?: string\n ariaDescribedBy?: string\n variant?: SparkInputStyle\n}) {\n const field = useFieldContext()\n const theme = useTheme()\n const id = options?.id ?? field?.id\n const errorId = field?.hasError ? field.errorId : undefined\n const descriptionId = field?.hasDescription ? field.descriptionId : undefined\n // error before hint: the actionable message should be announced first\n const ariaDescribedBy =\n [errorId, descriptionId, options?.ariaDescribedBy]\n .filter(Boolean)\n .join(' ') || undefined\n const inputStyle =\n options?.variant ?? field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const ariaInvalid = field?.hasError || undefined\n return { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor }\n}\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n 'flex flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = 'legend',\n ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n 'mb-1.5 font-medium text-gray data-[variant=label]:text-sm data-[variant=legend]:text-base',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n 'group/field-group flex w-full flex-col gap-[calc(var(--spark-layout-gap)*4)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n 'group/field relative flex w-full flex-col data-[invalid=true]:text-error-active',\n {\n variants: {\n labelPosition: {\n // inset puts label + input inside one shell, so the shell IS the input's box —\n // rounded-md tracks Input/Select/etc.'s own control radius, not the container one.\n // focus inside inset is the classic underline cue, not a shell ring\n inset: 'gap-y-1 rounded-md px-4 py-3',\n outset: 'gap-y-2',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-gray-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: 'border border-input bg-base-accent-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: 'border border-input-gray bg-base-gray-surface',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: 'border border-input',\n },\n {\n labelPosition: 'inset',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: 'border border-input-gray',\n },\n // ghost inset = bare label + underlined input; the input carries the line\n {\n labelPosition: 'inset',\n inputStyle: 'ghost',\n class: 'rounded-none px-0',\n },\n // shared inset states: filled shells swap bg, bordered shells swap border\n // invalid hover deepens the error tint instead of falling back to accent\n {\n labelPosition: 'inset',\n inputStyle: ['soft', 'surface'],\n class:\n 'data-[disabled=true]:bg-base-gray-soft data-[invalid=true]:bg-base-error-soft data-[invalid=true]:has-[:is(input,textarea,[data-slot=select-trigger]):not(:disabled)]:hover:bg-red-a4',\n },\n {\n labelPosition: 'inset',\n inputStyle: ['surface', 'outlined'],\n class:\n 'data-[disabled=true]:border-input-disabled data-[invalid=true]:border-input-invalid',\n },\n ],\n },\n)\n\ninterface FieldProps extends React.ComponentProps<'div'> {\n labelPosition?: SparkLabelPosition\n inputStyle?: SparkInputStyle\n inputColor?: SparkInputColor\n readOnly?: boolean\n 'data-invalid'?: boolean | 'true' | 'false'\n}\n\nfunction Field({\n className,\n children,\n labelPosition: labelPositionProp,\n inputStyle: inputStyleProp,\n inputColor: inputColorProp,\n readOnly = false,\n 'data-invalid': dataInvalid,\n ...props\n}: FieldProps) {\n const id = useId()\n const [descriptionCount, setDescriptionCount] = React.useState(0)\n const [errorCount, setErrorCount] = React.useState(0)\n // counts, not flags: one slot unmounting must not clear what siblings still need\n const setHasDescription = React.useCallback(\n (has: boolean) => setDescriptionCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const setHasError = React.useCallback(\n (has: boolean) => setErrorCount((n) => n + (has ? 1 : -1)),\n [],\n )\n const hasDescription = descriptionCount > 0\n const hasError = errorCount > 0\n // knobs are structural (they move the label / pick the box carrier), so they\n // resolve here via the <Theme> context; props override per instance\n const theme = useTheme()\n const labelPosition = labelPositionProp ?? theme.labelPosition ?? 'inset'\n const inputStyle = inputStyleProp ?? theme.inputStyle ?? 'soft'\n const inputColor = inputColorProp ?? theme.inputColor ?? 'brand'\n const fieldId = `field-${id}`\n const labelId = `${fieldId}-label`\n const value = React.useMemo<FieldContextValue>(\n () => ({\n id: fieldId,\n labelId,\n descriptionId: `${fieldId}-description`,\n hasDescription,\n setHasDescription,\n errorId: `${fieldId}-error`,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n }),\n [\n fieldId,\n labelId,\n hasDescription,\n setHasDescription,\n hasError,\n setHasError,\n readOnly,\n labelPosition,\n inputStyle,\n inputColor,\n ],\n )\n\n return (\n <FieldContext.Provider value={value}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-label-position={labelPosition}\n data-input-style={inputStyle}\n data-input-color={inputColor}\n data-invalid={dataInvalid ?? (hasError || undefined)}\n aria-labelledby={readOnly ? labelId : undefined}\n className={cn(\n fieldVariants({ labelPosition, inputStyle, inputColor }),\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </FieldContext.Provider>\n )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col gap-0.5 leading-snug',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst fieldLabelClassName =\n 'text-sm leading-5 font-normal text-gray-light transition-all group-data-[invalid=true]/field:text-error-active! motion-reduce:transition-none'\n\nfunction FieldLabel({\n className,\n htmlFor,\n srOnly,\n children,\n ...props\n}: React.ComponentProps<'label'> & { srOnly?: boolean }) {\n const field = useFieldContext()\n const classNames = cn(\n // labels stay full-contrast even when disabled — the control itself\n // (dimmed text, gray shell) signals the state\n fieldLabelClassName,\n // visually hidden but kept in the a11y tree (still names + focuses the control)\n srOnly && 'sr-only',\n className,\n )\n\n if (field?.readOnly) {\n return (\n <div data-slot=\"field-label\" id={field.labelId} className={classNames}>\n {children}\n </div>\n )\n }\n\n return (\n <label\n data-slot=\"field-label\"\n className={classNames}\n htmlFor={htmlFor ?? field?.id}\n {...props}\n >\n {children}\n </label>\n )\n}\n\nfunction FieldValue({\n className,\n id,\n title,\n truncate,\n children,\n ...props\n}: React.ComponentProps<'div'> & { truncate?: boolean }) {\n return (\n <div\n data-slot=\"field-value\"\n id={id}\n // truncated string values keep the full text reachable on hover\n title={\n title ??\n (truncate && typeof children === 'string' ? children : undefined)\n }\n className={cn(\n // values are content, not controls — disabled dims but stays ≥4.5:1\n 'min-h-8 w-full text-base text-gray tabular-nums group-data-[disabled=true]/field:opacity-70',\n truncate\n ? 'block truncate leading-8'\n : 'inline-flex items-center wrap-anywhere whitespace-pre-wrap',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nfunction FieldSkeleton({\n className,\n labelClassName,\n valueClassName,\n truncate,\n ...props\n}: React.ComponentProps<'div'> & {\n truncate?: boolean\n labelClassName?: string\n valueClassName?: string\n}) {\n return (\n <div\n data-slot=\"field-skeleton\"\n aria-hidden=\"true\"\n className={cn('flex w-full flex-col gap-y-1', className)}\n {...props}\n >\n <Skeleton\n data-slot=\"field-skeleton-label\"\n className={cn('h-5 w-24', labelClassName)}\n />\n <Skeleton\n data-slot=\"field-skeleton-value\"\n className={cn(\n 'h-8 min-h-8 w-full',\n truncate && 'max-w-full truncate',\n valueClassName,\n )}\n />\n </div>\n )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-title\"\n className={cn(\n 'flex w-fit items-center gap-2 text-sm font-medium text-gray',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n id,\n ...props\n}: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const setHasDescription = field?.setHasDescription\n\n React.useEffect(() => {\n if (!setHasDescription) return\n setHasDescription(true)\n return () => setHasDescription(false)\n }, [setHasDescription])\n\n return (\n <div\n data-slot=\"field-description\"\n id={id ?? field?.descriptionId}\n className={cn('mt-0.5 text-sm leading-normal text-gray-light', className)}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn('relative -my-2 h-5 text-sm', className)}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-(--spark-background) px-2 text-gray-light\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n id,\n ...props\n}: React.ComponentProps<'div'> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const field = useFieldContext()\n const setHasError = field?.setHasError\n const content = React.useMemo(() => {\n if (children) return children\n if (!errors?.length) return null\n const unique = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n if (unique.length === 1) return unique[0]?.message\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {unique.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>,\n )}\n </ul>\n )\n }, [children, errors])\n\n const hasContent = Boolean(content)\n // a custom id means no element carries field.errorId, so don't advertise it\n const hasCustomId = id != null\n\n // must run before the empty-content early return to keep hook order stable\n React.useEffect(() => {\n if (!setHasError || !hasContent || hasCustomId) return\n setHasError(true)\n return () => setHasError(false)\n }, [setHasError, hasContent, hasCustomId])\n\n if (!content) return null\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n id={id ?? field?.errorId}\n className={cn('mt-0.5 text-sm font-normal text-error', className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldContent,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLabel,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldSkeleton,\n FieldTitle,\n FieldValue,\n}\nexport type { FieldProps }\n"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ let cnfast = require("cnfast");
|
|
|
9
9
|
//#region src/components/info-block.tsx
|
|
10
10
|
const infoBlockVariants = (0, class_variance_authority.cva)("flex items-center gap-3", {
|
|
11
11
|
variants: { variant: {
|
|
12
|
-
default: "rounded-
|
|
12
|
+
default: "rounded-lg border border-gray p-4",
|
|
13
13
|
bare: "rounded-none border-none"
|
|
14
14
|
} },
|
|
15
15
|
defaultVariants: { variant: "default" }
|
|
@@ -21,7 +21,7 @@ const InfoBlock = react.forwardRef(({ className, variant, ...props }, ref) => /*
|
|
|
21
21
|
}));
|
|
22
22
|
InfoBlock.displayName = "InfoBlock";
|
|
23
23
|
const InfoBlockIcon = react.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
24
|
-
className: (0, cnfast.cn)("flex size-10 shrink-0 items-center justify-center rounded-
|
|
24
|
+
className: (0, cnfast.cn)("flex size-10 shrink-0 items-center justify-center rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))]", className),
|
|
25
25
|
ref,
|
|
26
26
|
...props
|
|
27
27
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"info-block.cjs","names":["React"],"sources":["../../src/components/info-block.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\n\nconst infoBlockVariants = cva('flex items-center gap-3', {\n variants: {\n variant: {\n default: 'rounded-
|
|
1
|
+
{"version":3,"file":"info-block.cjs","names":["React"],"sources":["../../src/components/info-block.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\n\nconst infoBlockVariants = cva('flex items-center gap-3', {\n variants: {\n variant: {\n default: 'rounded-lg border border-gray p-4',\n bare: 'rounded-none border-none',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nconst InfoBlock = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof infoBlockVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n className={cn(infoBlockVariants({ variant }), className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlock.displayName = 'InfoBlock'\n\nconst InfoBlockIcon = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n className={cn(\n // max() pill escape (matches Icon): a tile stays rounded-md at low Roundness but\n // becomes a circle at large/full, same as it did pre-harmonization via clamping.\n 'flex size-10 shrink-0 items-center justify-center rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))]',\n className,\n )}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockIcon.displayName = 'InfoBlockIcon'\n\nconst InfoBlockContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n className={cn('flex min-w-0 flex-1 flex-col gap-2', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockContent.displayName = 'InfoBlockContent'\n\nconst InfoBlockHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n className={cn('flex items-center justify-between gap-2', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockHeader.displayName = 'InfoBlockHeader'\n\nconst InfoBlockTitle = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-sm font-medium text-gray', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockTitle.displayName = 'InfoBlockTitle'\n\nconst InfoBlockLabel = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-xs font-medium text-gray-light', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockLabel.displayName = 'InfoBlockLabel'\n\nconst InfoBlockDescription = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-xs text-gray-light', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockDescription.displayName = 'InfoBlockDescription'\n\nconst InfoBlockValue = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-lg font-bold text-gray tabular-nums', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockValue.displayName = 'InfoBlockValue'\n\nexport {\n InfoBlock,\n InfoBlockContent,\n InfoBlockDescription,\n InfoBlockHeader,\n InfoBlockIcon,\n InfoBlockLabel,\n InfoBlockTitle,\n InfoBlockValue,\n}\n"],"mappings":";;;;;;;;;AAIA,MAAM,qBAAA,GAAA,yBAAA,KAAwB,2BAA2B;CACvD,UAAU,EACR,SAAS;EACP,SAAS;EACT,MAAM;CACR,EACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CAAC;AAED,MAAM,YAAYA,MAAM,YAGrB,EAAE,WAAW,SAAS,GAAG,SAAS,QACnC,iBAAA,GAAA,kBAAA,KAAC,OAAD;CACE,YAAA,GAAA,OAAA,IAAc,kBAAkB,EAAE,QAAQ,CAAC,GAAG,SAAS;CAClD;CACL,GAAI;AACL,CAAA,CACF;AAED,UAAU,cAAc;AAExB,MAAM,gBAAgBA,MAAM,YAGzB,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,OAAD;CACE,YAAA,GAAA,OAAA,IAGE,sHACA,SACF;CACK;CACL,GAAI;AACL,CAAA,CACF;AAED,cAAc,cAAc;AAE5B,MAAM,mBAAmBA,MAAM,YAG5B,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,OAAD;CACE,YAAA,GAAA,OAAA,IAAc,sCAAsC,SAAS;CACxD;CACL,GAAI;AACL,CAAA,CACF;AAED,iBAAiB,cAAc;AAE/B,MAAM,kBAAkBA,MAAM,YAG3B,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,OAAD;CACE,YAAA,GAAA,OAAA,IAAc,2CAA2C,SAAS;CAC7D;CACL,GAAI;AACL,CAAA,CACF;AAED,gBAAgB,cAAc;AAE9B,MAAM,iBAAiBA,MAAM,YAG1B,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,QAAD;CACE,YAAA,GAAA,OAAA,IAAc,iCAAiC,SAAS;CACnD;CACL,GAAI;AACL,CAAA,CACF;AAED,eAAe,cAAc;AAE7B,MAAM,iBAAiBA,MAAM,YAG1B,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,QAAD;CACE,YAAA,GAAA,OAAA,IAAc,uCAAuC,SAAS;CACzD;CACL,GAAI;AACL,CAAA,CACF;AAED,eAAe,cAAc;AAE7B,MAAM,uBAAuBA,MAAM,YAGhC,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,QAAD;CACE,YAAA,GAAA,OAAA,IAAc,2BAA2B,SAAS;CAC7C;CACL,GAAI;AACL,CAAA,CACF;AAED,qBAAqB,cAAc;AAEnC,MAAM,iBAAiBA,MAAM,YAG1B,EAAE,WAAW,GAAG,SAAS,QAC1B,iBAAA,GAAA,kBAAA,KAAC,QAAD;CACE,YAAA,GAAA,OAAA,IAAc,4CAA4C,SAAS;CAC9D;CACL,GAAI;AACL,CAAA,CACF;AAED,eAAe,cAAc"}
|
|
@@ -5,7 +5,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
5
5
|
|
|
6
6
|
//#region src/components/info-block.d.ts
|
|
7
7
|
declare const InfoBlock: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
8
|
-
variant?: "
|
|
8
|
+
variant?: "default" | "bare" | null | undefined;
|
|
9
9
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLDivElement>>;
|
|
10
10
|
declare const InfoBlockIcon: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
|
|
11
11
|
declare const InfoBlockContent: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
|
|
@@ -5,7 +5,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
5
5
|
|
|
6
6
|
//#region src/components/info-block.d.ts
|
|
7
7
|
declare const InfoBlock: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & VariantProps<(props?: ({
|
|
8
|
-
variant?: "
|
|
8
|
+
variant?: "default" | "bare" | null | undefined;
|
|
9
9
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & React$1.RefAttributes<HTMLDivElement>>;
|
|
10
10
|
declare const InfoBlockIcon: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
|
|
11
11
|
declare const InfoBlockContent: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
|
|
@@ -6,7 +6,7 @@ import { cva } from "class-variance-authority";
|
|
|
6
6
|
//#region src/components/info-block.tsx
|
|
7
7
|
const infoBlockVariants = cva("flex items-center gap-3", {
|
|
8
8
|
variants: { variant: {
|
|
9
|
-
default: "rounded-
|
|
9
|
+
default: "rounded-lg border border-gray p-4",
|
|
10
10
|
bare: "rounded-none border-none"
|
|
11
11
|
} },
|
|
12
12
|
defaultVariants: { variant: "default" }
|
|
@@ -18,7 +18,7 @@ const InfoBlock = React$1.forwardRef(({ className, variant, ...props }, ref) =>
|
|
|
18
18
|
}));
|
|
19
19
|
InfoBlock.displayName = "InfoBlock";
|
|
20
20
|
const InfoBlockIcon = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
|
|
21
|
-
className: cn("flex size-10 shrink-0 items-center justify-center rounded-
|
|
21
|
+
className: cn("flex size-10 shrink-0 items-center justify-center rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))]", className),
|
|
22
22
|
ref,
|
|
23
23
|
...props
|
|
24
24
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"info-block.js","names":["React"],"sources":["../../src/components/info-block.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\n\nconst infoBlockVariants = cva('flex items-center gap-3', {\n variants: {\n variant: {\n default: 'rounded-
|
|
1
|
+
{"version":3,"file":"info-block.js","names":["React"],"sources":["../../src/components/info-block.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\n\nconst infoBlockVariants = cva('flex items-center gap-3', {\n variants: {\n variant: {\n default: 'rounded-lg border border-gray p-4',\n bare: 'rounded-none border-none',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nconst InfoBlock = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof infoBlockVariants>\n>(({ className, variant, ...props }, ref) => (\n <div\n className={cn(infoBlockVariants({ variant }), className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlock.displayName = 'InfoBlock'\n\nconst InfoBlockIcon = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n className={cn(\n // max() pill escape (matches Icon): a tile stays rounded-md at low Roundness but\n // becomes a circle at large/full, same as it did pre-harmonization via clamping.\n 'flex size-10 shrink-0 items-center justify-center rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))]',\n className,\n )}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockIcon.displayName = 'InfoBlockIcon'\n\nconst InfoBlockContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n className={cn('flex min-w-0 flex-1 flex-col gap-2', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockContent.displayName = 'InfoBlockContent'\n\nconst InfoBlockHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n className={cn('flex items-center justify-between gap-2', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockHeader.displayName = 'InfoBlockHeader'\n\nconst InfoBlockTitle = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-sm font-medium text-gray', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockTitle.displayName = 'InfoBlockTitle'\n\nconst InfoBlockLabel = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-xs font-medium text-gray-light', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockLabel.displayName = 'InfoBlockLabel'\n\nconst InfoBlockDescription = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-xs text-gray-light', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockDescription.displayName = 'InfoBlockDescription'\n\nconst InfoBlockValue = React.forwardRef<\n HTMLSpanElement,\n React.HTMLAttributes<HTMLSpanElement>\n>(({ className, ...props }, ref) => (\n <span\n className={cn('text-lg font-bold text-gray tabular-nums', className)}\n ref={ref}\n {...props}\n />\n))\n\nInfoBlockValue.displayName = 'InfoBlockValue'\n\nexport {\n InfoBlock,\n InfoBlockContent,\n InfoBlockDescription,\n InfoBlockHeader,\n InfoBlockIcon,\n InfoBlockLabel,\n InfoBlockTitle,\n InfoBlockValue,\n}\n"],"mappings":";;;;;;AAIA,MAAM,oBAAoB,IAAI,2BAA2B;CACvD,UAAU,EACR,SAAS;EACP,SAAS;EACT,MAAM;CACR,EACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CAAC;AAED,MAAM,YAAYA,QAAM,YAGrB,EAAE,WAAW,SAAS,GAAG,SAAS,QACnC,oBAAC,OAAD;CACE,WAAW,GAAG,kBAAkB,EAAE,QAAQ,CAAC,GAAG,SAAS;CAClD;CACL,GAAI;AACL,CAAA,CACF;AAED,UAAU,cAAc;AAExB,MAAM,gBAAgBA,QAAM,YAGzB,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACE,WAAW,GAGT,sHACA,SACF;CACK;CACL,GAAI;AACL,CAAA,CACF;AAED,cAAc,cAAc;AAE5B,MAAM,mBAAmBA,QAAM,YAG5B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACE,WAAW,GAAG,sCAAsC,SAAS;CACxD;CACL,GAAI;AACL,CAAA,CACF;AAED,iBAAiB,cAAc;AAE/B,MAAM,kBAAkBA,QAAM,YAG3B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,OAAD;CACE,WAAW,GAAG,2CAA2C,SAAS;CAC7D;CACL,GAAI;AACL,CAAA,CACF;AAED,gBAAgB,cAAc;AAE9B,MAAM,iBAAiBA,QAAM,YAG1B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,QAAD;CACE,WAAW,GAAG,iCAAiC,SAAS;CACnD;CACL,GAAI;AACL,CAAA,CACF;AAED,eAAe,cAAc;AAE7B,MAAM,iBAAiBA,QAAM,YAG1B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,QAAD;CACE,WAAW,GAAG,uCAAuC,SAAS;CACzD;CACL,GAAI;AACL,CAAA,CACF;AAED,eAAe,cAAc;AAE7B,MAAM,uBAAuBA,QAAM,YAGhC,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,QAAD;CACE,WAAW,GAAG,2BAA2B,SAAS;CAC7C;CACL,GAAI;AACL,CAAA,CACF;AAED,qBAAqB,cAAc;AAEnC,MAAM,iBAAiBA,QAAM,YAG1B,EAAE,WAAW,GAAG,SAAS,QAC1B,oBAAC,QAAD;CACE,WAAW,GAAG,4CAA4C,SAAS;CAC9D;CACL,GAAI;AACL,CAAA,CACF;AAED,eAAe,cAAc"}
|
|
@@ -16,7 +16,7 @@ const inputGroupVariants = (0, class_variance_authority.cva)("group/input-group
|
|
|
16
16
|
variants: {
|
|
17
17
|
chrome: {
|
|
18
18
|
inset: GHOST,
|
|
19
|
-
box: "h-11 rounded-
|
|
19
|
+
box: "h-11 rounded-md px-3 transition-all motion-reduce:transition-none"
|
|
20
20
|
},
|
|
21
21
|
inputStyle: {
|
|
22
22
|
soft: "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group.cjs","names":["useFieldContext","useTheme","React","Input"],"sources":["../../src/components/input-group.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { useFieldContext } from './field'\nimport { Input, type InputProps } from './input'\nimport { useTheme } from './theme'\n\nconst GHOST =\n 'rounded-none border-0 border-b-2 px-0 focus-within:border-b-input-active has-[[data-slot=input][aria-invalid=true]]:border-b-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-b-red-a8! group-data-[invalid=true]/field:border-b-input-invalid! group-data-[invalid=true]/field:focus-within:border-b-red-a8!'\n\nconst inputGroupVariants = cva(\n 'group/input-group relative flex h-10 w-full min-w-0 items-center gap-2 bg-transparent transition-[color,border-color] outline-none motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; the group keeps the\n // classic underline (inputs inside stay chrome-less)\n inset: GHOST,\n // h-11 matches the standalone Input box\n box: 'h-11 rounded-
|
|
1
|
+
{"version":3,"file":"input-group.cjs","names":["useFieldContext","useTheme","React","Input"],"sources":["../../src/components/input-group.tsx"],"sourcesContent":["'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { useFieldContext } from './field'\nimport { Input, type InputProps } from './input'\nimport { useTheme } from './theme'\n\nconst GHOST =\n 'rounded-none border-0 border-b-2 px-0 focus-within:border-b-input-active has-[[data-slot=input][aria-invalid=true]]:border-b-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-b-red-a8! group-data-[invalid=true]/field:border-b-input-invalid! group-data-[invalid=true]/field:focus-within:border-b-red-a8!'\n\nconst inputGroupVariants = cva(\n 'group/input-group relative flex h-10 w-full min-w-0 items-center gap-2 bg-transparent transition-[color,border-color] outline-none motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; the group keeps the\n // classic underline (inputs inside stay chrome-less)\n inset: GHOST,\n // h-11 matches the standalone Input box\n box: 'h-11 rounded-md px-3 transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n // invalid hover deepens the error tint instead of the accent hover\n class:\n 'group-data-[invalid=true]/field:bg-base-error-soft focus-within:ring-2 focus-within:ring-offset-2 group-data-[invalid=true]/field:focus-within:ring-red-a8 has-[[data-slot=input][aria-invalid=true]]:bg-base-error-soft has-[[data-slot=input][aria-invalid=true]]:focus-within:ring-red-a8 has-[[data-slot=input][aria-invalid=true]:not(:disabled)]:hover:bg-red-a4 group-data-[invalid=true]/field:has-[input:not(:disabled)]:hover:bg-red-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class:\n 'bg-input-base focus-within:ring-input-active has-[input:not(:disabled)]:hover:bg-input-base-hover',\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class:\n 'bg-base-gray-soft focus-within:ring-gray-a8 has-[input:not(:disabled)]:hover:bg-gray-a4',\n },\n {\n chrome: 'box',\n inputStyle: ['surface', 'outlined'],\n class:\n 'border group-data-[invalid=true]/field:border-input-invalid focus-within:ring-1 group-data-[invalid=true]/field:focus-within:border-input-invalid! group-data-[invalid=true]/field:focus-within:ring-red-a4! has-[[data-slot=input][aria-invalid=true]]:border-input-invalid has-[[data-slot=input][aria-invalid=true]]:focus-within:border-input-invalid! has-[[data-slot=input][aria-invalid=true]]:focus-within:ring-red-a4!',\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class:\n 'border-input bg-base-accent-surface focus-within:border-input-active focus-within:ring-spark-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class:\n 'border-input-gray bg-base-gray-surface focus-within:border-gray-a8 focus-within:ring-gray-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class:\n 'border-input focus-within:border-input-active focus-within:ring-spark-a4',\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class:\n 'border-input-gray focus-within:border-gray-a8 focus-within:ring-gray-a4',\n },\n { chrome: 'box', inputStyle: 'ghost', class: GHOST },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: 'border-b-input',\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: 'border-b-input-gray',\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\n// The group carries the box + focus/invalid states; inputs inside are\n// chrome-less (variant=\"none\"). Style follows the enclosing Field's knobs,\n// else the <Theme> input-style/input-color knobs.\nfunction InputGroup({ className, ...props }: React.ComponentProps<'div'>) {\n const field = useFieldContext()\n const theme = useTheme()\n const inputStyle = field?.inputStyle ?? theme.inputStyle ?? 'soft'\n const inputColor = field?.inputColor ?? theme.inputColor ?? 'brand'\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n inputGroupVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n 'flex h-auto cursor-text items-center justify-center gap-2 py-2 text-sm font-medium text-gray-light select-none [&_svg:not([class*=size-])]:size-4',\n {\n variants: {\n align: {\n // button addons bring their own inner padding — pull them halfway\n // into the group's px so the visual gap matches the text side\n 'inline-start': 'order-first has-[>button]:-ml-2',\n 'inline-end': 'order-last has-[>button]:-mr-2',\n },\n },\n defaultVariants: {\n align: 'inline-start',\n },\n },\n)\n\nfunction InputGroupAddon({\n className,\n align = 'inline-start',\n ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n // chrome, not a control: the click only forwards focus to the input the\n // way a label would, and Tab already reaches that input directly\n role=\"presentation\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(event) => {\n if ((event.target as HTMLElement).closest('button')) return\n event.currentTarget.parentElement?.querySelector('input')?.focus()\n }}\n {...props}\n />\n )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {\n return (\n <span\n className={cn(\n 'flex items-center gap-2 text-xs text-gray-light [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4',\n className,\n )}\n {...props}\n />\n )\n}\n\nconst InputGroupInput = React.forwardRef<HTMLInputElement, InputProps>(\n function InputGroupInput({ className, ...props }, ref) {\n return (\n <Input\n data-slot=\"input\"\n variant=\"none\"\n className={cn('flex-1', className)}\n ref={ref}\n {...props}\n />\n )\n },\n)\n\nexport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText }\n"],"mappings":";;;;;;;;;;;;;AASA,MAAM,QACJ;AAEF,MAAM,sBAAA,GAAA,yBAAA,KACJ,oKACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAO;GAEP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GAEZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY,CAAC,WAAW,UAAU;GAClC,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OACE;EACJ;EACA;GAAE,QAAQ;GAAO,YAAY;GAAS,OAAO;EAAM;EACnD;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAO;EACT;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAKA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,MAAM,QAAQA,yBAAAA,gBAAgB;CAC9B,MAAM,QAAQC,yBAAAA,SAAS;CACvB,MAAM,aAAa,OAAO,cAAc,MAAM,cAAc;CAC5D,MAAM,aAAa,OAAO,cAAc,MAAM,cAAc;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,YAAA,GAAA,OAAA,IACE,mBAAmB;GAAE,QANZ,OAAO,kBAAkB,UAAU,UAAU;GAMzB;GAAY;EAAW,CAAC,GACrD,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,2BAAA,GAAA,yBAAA,KACJ,qJACA;CACE,UAAU,EACR,OAAO;EAGL,gBAAgB;EAChB,cAAc;CAChB,EACF;CACA,iBAAiB,EACf,OAAO,eACT;AACF,CACF;AAEA,SAAS,gBAAgB,EACvB,WACA,QAAQ,gBACR,GAAG,SAC0E;CAC7E,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAGE,MAAK;EACL,aAAU;EACV,cAAY;EACZ,YAAA,GAAA,OAAA,IAAc,wBAAwB,EAAE,MAAM,CAAC,GAAG,SAAS;EAC3D,UAAU,UAAU;GAClB,IAAK,MAAM,OAAuB,QAAQ,QAAQ,GAAG;GACrD,MAAM,cAAc,eAAe,cAAc,OAAO,GAAG,MAAM;EACnE;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAuC;CAC7E,OACE,iBAAA,GAAA,kBAAA,KAAC,QAAD;EACE,YAAA,GAAA,OAAA,IACE,kHACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,MAAM,kBAAkBC,MAAM,WAC5B,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAS,KAAK;CACrD,OACE,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,OAAD;EACE,aAAU;EACV,SAAQ;EACR,YAAA,GAAA,OAAA,IAAc,UAAU,SAAS;EAC5B;EACL,GAAI;CACL,CAAA;AAEL,CACF"}
|
|
@@ -13,7 +13,7 @@ const inputGroupVariants = cva("group/input-group relative flex h-10 w-full min-
|
|
|
13
13
|
variants: {
|
|
14
14
|
chrome: {
|
|
15
15
|
inset: GHOST,
|
|
16
|
-
box: "h-11 rounded-
|
|
16
|
+
box: "h-11 rounded-md px-3 transition-all motion-reduce:transition-none"
|
|
17
17
|
},
|
|
18
18
|
inputStyle: {
|
|
19
19
|
soft: "",
|