@adea-ai/ui 0.117.0 → 0.118.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/composites/action-button/action-button.d.ts.map +1 -1
- package/dist/components/composites/action-button/action-button.js +1 -0
- package/dist/components/composites/action-button/action-button.js.map +1 -1
- package/dist/components/composites/list-row/list-row-control.d.ts.map +1 -1
- package/dist/components/composites/list-row/list-row-control.js +1 -0
- package/dist/components/composites/list-row/list-row-control.js.map +1 -1
- package/dist/components/composites/list-row/list-row.d.ts.map +1 -1
- package/dist/components/composites/list-row/list-row.js +16 -9
- package/dist/components/composites/list-row/list-row.js.map +1 -1
- package/dist/components/composites/settings/settings-navigation.d.ts.map +1 -1
- package/dist/components/composites/settings/settings-navigation.js +15 -6
- package/dist/components/composites/settings/settings-navigation.js.map +1 -1
- package/dist/components/composites/settings/settings.d.ts +3 -2
- package/dist/components/composites/settings/settings.d.ts.map +1 -1
- package/dist/components/composites/settings/settings.js +3 -2
- package/dist/components/composites/settings/settings.js.map +1 -1
- package/dist/components/ui/alert/alert.d.ts +7 -0
- package/dist/components/ui/alert/alert.d.ts.map +1 -1
- package/dist/components/ui/alert/alert.js +18 -1
- package/dist/components/ui/alert/alert.js.map +1 -1
- package/dist/components/ui/alert/index.d.ts +1 -1
- package/dist/components/ui/alert/index.d.ts.map +1 -1
- package/dist/components/ui/alert/index.js +2 -2
- package/dist/components/ui/badge/badge.d.ts.map +1 -1
- package/dist/components/ui/badge/badge.js +1 -0
- package/dist/components/ui/badge/badge.js.map +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts +6 -0
- package/dist/components/ui/breadcrumb/breadcrumb.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb/breadcrumb.js +19 -8
- package/dist/components/ui/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/ui/breadcrumb/index.d.ts +1 -1
- package/dist/components/ui/breadcrumb/index.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb/index.js +2 -2
- package/dist/components/ui/button/button.d.ts.map +1 -1
- package/dist/components/ui/button/button.js +1 -0
- package/dist/components/ui/button/button.js.map +1 -1
- package/dist/components/ui/card/card.d.ts +19 -9
- package/dist/components/ui/card/card.d.ts.map +1 -1
- package/dist/components/ui/card/card.js +21 -3
- package/dist/components/ui/card/card.js.map +1 -1
- package/dist/components/ui/card/index.d.ts +1 -1
- package/dist/components/ui/card/index.d.ts.map +1 -1
- package/dist/components/ui/card/index.js +2 -2
- package/dist/components/ui/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox/checkbox.js +1 -0
- package/dist/components/ui/checkbox/checkbox.js.map +1 -1
- package/dist/components/ui/dialog/dialog.d.ts +15 -0
- package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog/dialog.js +11 -3
- package/dist/components/ui/dialog/dialog.js.map +1 -1
- package/dist/components/ui/dialog/index.d.ts +1 -1
- package/dist/components/ui/dialog/index.d.ts.map +1 -1
- package/dist/components/ui/entity-icon/entity-icon.d.ts +10 -0
- package/dist/components/ui/entity-icon/entity-icon.d.ts.map +1 -1
- package/dist/components/ui/entity-icon/entity-icon.js +11 -2
- package/dist/components/ui/entity-icon/entity-icon.js.map +1 -1
- package/dist/components/ui/field/field.d.ts +11 -1
- package/dist/components/ui/field/field.d.ts.map +1 -1
- package/dist/components/ui/field/field.js +2 -2
- package/dist/components/ui/field/field.js.map +1 -1
- package/dist/components/ui/field/index.d.ts +1 -1
- package/dist/components/ui/field/index.d.ts.map +1 -1
- package/dist/components/ui/input-group/index.d.ts +1 -1
- package/dist/components/ui/input-group/index.d.ts.map +1 -1
- package/dist/components/ui/input-group/input-group.d.ts +8 -1
- package/dist/components/ui/input-group/input-group.d.ts.map +1 -1
- package/dist/components/ui/input-group/input-group.js +16 -20
- package/dist/components/ui/input-group/input-group.js.map +1 -1
- package/dist/components/ui/native-select/native-select.d.ts +8 -1
- package/dist/components/ui/native-select/native-select.d.ts.map +1 -1
- package/dist/components/ui/native-select/native-select.js +9 -2
- package/dist/components/ui/native-select/native-select.js.map +1 -1
- package/dist/components/ui/progress/progress.d.ts.map +1 -1
- package/dist/components/ui/progress/progress.js +6 -3
- package/dist/components/ui/progress/progress.js.map +1 -1
- package/dist/components/ui/radio-group/radio-group.d.ts +18 -3
- package/dist/components/ui/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/ui/radio-group/radio-group.js +32 -7
- package/dist/components/ui/radio-group/radio-group.js.map +1 -1
- package/dist/components/ui/select/select.d.ts.map +1 -1
- package/dist/components/ui/select/select.js +10 -7
- package/dist/components/ui/select/select.js.map +1 -1
- package/dist/components/ui/sheet/sheet.d.ts +1 -0
- package/dist/components/ui/sheet/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet/sheet.js +27 -2
- package/dist/components/ui/sheet/sheet.js.map +1 -1
- package/dist/components/ui/slider/slider.d.ts.map +1 -1
- package/dist/components/ui/slider/slider.js +6 -3
- package/dist/components/ui/slider/slider.js.map +1 -1
- package/dist/components/ui/status-chip/status-chip.d.ts.map +1 -1
- package/dist/components/ui/status-chip/status-chip.js +1 -1
- package/dist/components/ui/status-chip/status-chip.js.map +1 -1
- package/dist/components/ui/switch/switch.d.ts.map +1 -1
- package/dist/components/ui/switch/switch.js +1 -0
- package/dist/components/ui/switch/switch.js.map +1 -1
- package/dist/components/ui/tabs/tabs.d.ts +18 -0
- package/dist/components/ui/tabs/tabs.d.ts.map +1 -1
- package/dist/components/ui/tabs/tabs.js +22 -4
- package/dist/components/ui/tabs/tabs.js.map +1 -1
- package/dist/components/ui/toggle/toggle.d.ts.map +1 -1
- package/dist/components/ui/toggle/toggle.js +9 -6
- package/dist/components/ui/toggle/toggle.js.map +1 -1
- package/dist/components/ui/toggle-group/toggle-group.d.ts.map +1 -1
- package/dist/components/ui/toggle-group/toggle-group.js +2 -0
- package/dist/components/ui/toggle-group/toggle-group.js.map +1 -1
- package/dist/components/ui/typography/typography.d.ts +12 -1
- package/dist/components/ui/typography/typography.d.ts.map +1 -1
- package/dist/components/ui/typography/typography.js +16 -2
- package/dist/components/ui/typography/typography.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/lib/cn-tables.generated.js +5 -5
- package/dist/lib/cn-tables.generated.js.map +1 -1
- package/dist/lib/tokens.d.ts.map +1 -1
- package/dist/lib/tokens.js +7 -2
- package/dist/lib/tokens.js.map +1 -1
- package/dist/r/list-row.json +1 -0
- package/dist/r/registry.json +1 -0
- package/dist/r/src/components/composites/action-button/action-button.tsx +3 -0
- package/dist/r/src/components/composites/list-row/list-row-control.tsx +1 -0
- package/dist/r/src/components/composites/list-row/list-row.tsx +3 -2
- package/dist/r/src/components/composites/settings/settings-navigation.tsx +7 -3
- package/dist/r/src/components/composites/settings/settings.tsx +3 -2
- package/dist/r/src/components/ui/alert/alert.tsx +17 -0
- package/dist/r/src/components/ui/alert/index.ts +8 -1
- package/dist/r/src/components/ui/badge/badge.tsx +1 -0
- package/dist/r/src/components/ui/breadcrumb/breadcrumb.tsx +18 -8
- package/dist/r/src/components/ui/breadcrumb/index.ts +1 -0
- package/dist/r/src/components/ui/button/button.tsx +1 -0
- package/dist/r/src/components/ui/card/card.tsx +30 -13
- package/dist/r/src/components/ui/card/index.ts +1 -0
- package/dist/r/src/components/ui/checkbox/checkbox.tsx +1 -0
- package/dist/r/src/components/ui/dialog/dialog.tsx +26 -2
- package/dist/r/src/components/ui/dialog/index.ts +1 -0
- package/dist/r/src/components/ui/entity-icon/entity-icon.tsx +15 -0
- package/dist/r/src/components/ui/field/field.tsx +23 -3
- package/dist/r/src/components/ui/field/index.ts +1 -0
- package/dist/r/src/components/ui/input-group/index.ts +1 -0
- package/dist/r/src/components/ui/input-group/input-group.tsx +28 -5
- package/dist/r/src/components/ui/native-select/native-select.tsx +20 -3
- package/dist/r/src/components/ui/progress/progress.tsx +5 -1
- package/dist/r/src/components/ui/radio-group/radio-group.tsx +40 -3
- package/dist/r/src/components/ui/select/select.tsx +1 -0
- package/dist/r/src/components/ui/sheet/sheet.tsx +20 -2
- package/dist/r/src/components/ui/slider/slider.tsx +1 -0
- package/dist/r/src/components/ui/status-chip/status-chip.tsx +1 -0
- package/dist/r/src/components/ui/switch/switch.tsx +1 -0
- package/dist/r/src/components/ui/tabs/tabs.tsx +33 -4
- package/dist/r/src/components/ui/toggle/toggle.tsx +1 -0
- package/dist/r/src/components/ui/toggle-group/toggle-group.tsx +2 -0
- package/dist/r/src/components/ui/typography/typography.tsx +20 -1
- package/dist/r/src/lib/cn-tables.generated.ts +5 -5
- package/dist/r/src/lib/tokens.ts +7 -2
- package/dist/r/src/styles/base.css +4 -1
- package/dist/r/src/styles/theme.css +4 -0
- package/package.json +1 -1
- package/registry.json +1 -0
- package/src/components/composites/action-button/action-button.tsx +3 -0
- package/src/components/composites/list-row/list-row-control.tsx +1 -0
- package/src/components/composites/list-row/list-row.tsx +3 -2
- package/src/components/composites/settings/settings-navigation.tsx +7 -3
- package/src/components/composites/settings/settings.tsx +3 -2
- package/src/components/ui/alert/alert.tsx +17 -0
- package/src/components/ui/alert/index.ts +8 -1
- package/src/components/ui/badge/badge.tsx +1 -0
- package/src/components/ui/breadcrumb/breadcrumb.tsx +18 -8
- package/src/components/ui/breadcrumb/index.ts +1 -0
- package/src/components/ui/button/button.tsx +1 -0
- package/src/components/ui/card/card.tsx +30 -13
- package/src/components/ui/card/index.ts +1 -0
- package/src/components/ui/checkbox/checkbox.tsx +1 -0
- package/src/components/ui/dialog/dialog.tsx +26 -2
- package/src/components/ui/dialog/index.ts +1 -0
- package/src/components/ui/entity-icon/entity-icon.tsx +15 -0
- package/src/components/ui/field/field.tsx +23 -3
- package/src/components/ui/field/index.ts +1 -0
- package/src/components/ui/input-group/index.ts +1 -0
- package/src/components/ui/input-group/input-group.tsx +28 -5
- package/src/components/ui/native-select/native-select.tsx +20 -3
- package/src/components/ui/progress/progress.tsx +5 -1
- package/src/components/ui/radio-group/radio-group.tsx +40 -3
- package/src/components/ui/select/select.tsx +1 -0
- package/src/components/ui/sheet/sheet.tsx +20 -2
- package/src/components/ui/slider/slider.tsx +1 -0
- package/src/components/ui/status-chip/status-chip.tsx +1 -0
- package/src/components/ui/switch/switch.tsx +1 -0
- package/src/components/ui/tabs/tabs.tsx +33 -4
- package/src/components/ui/toggle/toggle.tsx +1 -0
- package/src/components/ui/toggle-group/toggle-group.tsx +2 -0
- package/src/components/ui/typography/typography.tsx +20 -1
- package/src/lib/cn-tables.generated.ts +5 -5
- package/src/lib/tokens.ts +7 -2
- package/src/styles/base.css +4 -1
- package/src/styles/theme.css +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.js","names":["Dialog","KobalteDialog","Content","KobalteDialogContent","Overlay","KobalteDialogOverlay","X","Accessor","ComponentProps","JSX","createRenderEffect","onCleanup","Show","splitProps","dialogSurface","overlayMotion","overlayPositioner","overlayScrim","overlayTitle","cn","Tooltip","TooltipContent","TooltipTrigger","FocusCycle","content","HTMLElement","opener","openerEligible","closed","focusMovedOutside","closeAutoFocusScheduled","frame","fallbackTimer","observer","MutationObserver","onFocusIn","event","FocusEvent","canRestoreFocus","target","isConnected","document","body","documentElement","closest","matches","getClientRects","length","hasOtherOverlay","querySelectorAll","some","overlay","contains","DialogFocusRestorationOptions","open","restoreFocusRef","onOpenAutoFocus","onCloseAutoFocus","createDialogFocusRestoration","callerOnOpenAutoFocus","callerOnCloseAutoFocus","focusCycles","WeakMap","activeFocusCycle","pendingOpener","pendingOpenerEligible","active","activeElement","finishFocusCycle","cycle","undefined","window","cancelAnimationFrame","clearTimeout","disconnect","removeEventListener","scheduleFocusRestore","requestAnimationFrame","focusIsAvailable","Node","focus","preventScroll","Event","element","currentTarget","openerWasCaptured","focusEvent","set","addEventListener","get","defaultPrevented","observe","attributes","attributeFilter","childList","subtree","queueMicrotask","setTimeout","props","_$createComponent","DialogTrigger","Trigger","DialogPortal","Portal","DialogOverlay","local","rest","_$mergeProps","class","DialogContentProps","closeButton","Element","positioner","DialogContent","children","_el$","_tmpl$","_$insert","_$memo","when","as","CloseButton","_$effect","_$className","DialogHeader","band","_el$2","_tmpl$2","_$spread","DialogFooter","_el$3","_tmpl$3","DialogTitle","Title","DialogDescription","Description","DialogCloseButton","DialogClose","Dialog","_$createComponent","KobalteDialog","KobalteDialogOverlay","_$mergeProps","KobalteDialogContent","_$memo","_$className"],"sources":["../../../../src/components/ui/dialog/dialog.tsx"],"sourcesContent":["import {\n Dialog as KobalteDialog,\n Content as KobalteDialogContent,\n Overlay as KobalteDialogOverlay,\n} from '@kobalte/core/dialog'\n// AlertDialog assigns to the shared DialogRoot.Content object, so these named exports stay role-stable.\nimport { X } from 'lucide-solid'\nimport type { Accessor, ComponentProps, JSX } from 'solid-js'\nimport { createRenderEffect, onCleanup, Show, splitProps } from 'solid-js'\nimport {\n dialogSurface,\n overlayMotion,\n overlayPositioner,\n overlayScrim,\n overlayTitle,\n} from '#lib/overlay'\nimport { cn } from '#lib/utils'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'\n\ntype FocusCycle = {\n content: HTMLElement\n opener: HTMLElement | null\n openerEligible: boolean\n closed: boolean\n focusMovedOutside: boolean\n closeAutoFocusScheduled: boolean\n frame?: number\n fallbackTimer?: number\n observer?: MutationObserver\n onFocusIn: (event: FocusEvent) => void\n}\n\nfunction canRestoreFocus(target: HTMLElement): boolean {\n return (\n target.isConnected &&\n target !== document.body &&\n target !== document.documentElement &&\n !target.closest('[inert], [aria-hidden=\"true\"]') &&\n !target.matches(':disabled') &&\n target.getClientRects().length > 0\n )\n}\n\nfunction hasOtherOverlay(content: HTMLElement, opener: HTMLElement): boolean {\n return [...document.querySelectorAll<HTMLElement>('[role=\"dialog\"], [role=\"alertdialog\"]')].some(\n (overlay) =>\n overlay !== content &&\n !content.contains(overlay) &&\n !overlay.contains(opener) &&\n !overlay.closest('[aria-hidden=\"true\"], [inert]') &&\n overlay.getClientRects().length > 0\n )\n}\n\ntype DialogFocusRestorationOptions = {\n open: Accessor<boolean>\n restoreFocusRef?: Accessor<HTMLElement | undefined>\n onOpenAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onOpenAutoFocus']\n onCloseAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onCloseAutoFocus']\n}\n\n/**\n * Adds guarded opener capture and restoration to a Kobalte dialog content.\n * Composed surfaces use this internal helper; it is omitted from the public\n * dialog barrel so the restoration policy stays with the dialog components.\n */\nexport function createDialogFocusRestoration({\n open,\n restoreFocusRef,\n onOpenAutoFocus: callerOnOpenAutoFocus,\n onCloseAutoFocus: callerOnCloseAutoFocus,\n}: DialogFocusRestorationOptions) {\n const focusCycles = new WeakMap<HTMLElement, FocusCycle>()\n let activeFocusCycle: FocusCycle | undefined\n let pendingOpener: HTMLElement | null = null\n let pendingOpenerEligible = false\n\n createRenderEffect(() => {\n if (!open() || typeof document === 'undefined') {\n pendingOpener = null\n pendingOpenerEligible = false\n return\n }\n const active = restoreFocusRef?.() ?? document.activeElement\n pendingOpener = active instanceof HTMLElement ? active : null\n pendingOpenerEligible = active instanceof HTMLElement && canRestoreFocus(active)\n })\n\n const finishFocusCycle = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) window.cancelAnimationFrame(cycle.frame)\n if (cycle.fallbackTimer !== undefined) window.clearTimeout(cycle.fallbackTimer)\n cycle.observer?.disconnect()\n document.removeEventListener('focusin', cycle.onFocusIn)\n if (activeFocusCycle === cycle) activeFocusCycle = undefined\n }\n\n const scheduleFocusRestore = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) return\n cycle.frame = window.requestAnimationFrame(() => {\n cycle.frame = undefined\n const opener = cycle.opener\n const active = document.activeElement\n const focusIsAvailable =\n active === document.body ||\n active === document.documentElement ||\n active === cycle.content ||\n (active instanceof Node && cycle.content.contains(active))\n if (\n activeFocusCycle !== cycle ||\n !cycle.closed ||\n cycle.focusMovedOutside ||\n !opener ||\n !opener.isConnected ||\n opener.matches(':disabled') ||\n opener.getClientRects().length === 0 ||\n !focusIsAvailable ||\n hasOtherOverlay(cycle.content, opener)\n ) {\n finishFocusCycle(cycle)\n return\n }\n\n // Inert and aria-hidden are removed by the dialog's containment cleanup.\n // Wait for that cleanup before returning focus to the original control.\n if (opener.closest('[inert], [aria-hidden=\"true\"]')) return\n if (cycle.openerEligible && canRestoreFocus(opener)) {\n opener.focus({ preventScroll: true })\n }\n finishFocusCycle(cycle)\n })\n }\n\n const onOpenAutoFocus = (event: Event) => {\n const element = event.currentTarget\n if (element instanceof HTMLElement) {\n if (activeFocusCycle) finishFocusCycle(activeFocusCycle)\n\n const openerWasCaptured = pendingOpener !== null\n const opener = pendingOpener ?? document.activeElement\n const openerEligible = openerWasCaptured\n ? pendingOpenerEligible\n : opener instanceof HTMLElement && canRestoreFocus(opener)\n pendingOpener = null\n pendingOpenerEligible = false\n const cycle: FocusCycle = {\n content: element,\n opener: opener instanceof HTMLElement ? opener : null,\n openerEligible,\n closed: false,\n focusMovedOutside: false,\n closeAutoFocusScheduled: false,\n onFocusIn: (focusEvent) => {\n const target = focusEvent.target\n if (\n !(target instanceof HTMLElement) ||\n target === document.body ||\n target === document.documentElement\n ) {\n return\n }\n if (\n target === element ||\n element.contains(target) ||\n target === (opener instanceof HTMLElement ? opener : null)\n ) {\n if (!cycle.closed) cycle.focusMovedOutside = false\n return\n }\n cycle.focusMovedOutside = true\n },\n }\n focusCycles.set(element, cycle)\n activeFocusCycle = cycle\n document.addEventListener('focusin', cycle.onFocusIn)\n }\n callerOnOpenAutoFocus?.(event)\n }\n\n const onCloseAutoFocus = (event: Event) => {\n const element = event.currentTarget\n const cycle = element instanceof HTMLElement ? focusCycles.get(element) : undefined\n callerOnCloseAutoFocus?.(event)\n\n if (!cycle) return\n cycle.closed = true\n\n // A caller that prevents Kobalte's close autofocus owns the focus decision.\n if (event.defaultPrevented) {\n finishFocusCycle(cycle)\n return\n }\n\n if (cycle.fallbackTimer !== undefined) {\n window.clearTimeout(cycle.fallbackTimer)\n cycle.fallbackTimer = undefined\n }\n cycle.closeAutoFocusScheduled = true\n cycle.observer = new MutationObserver(() => scheduleFocusRestore(cycle))\n cycle.observer.observe(document.body, {\n attributes: true,\n attributeFilter: ['aria-hidden', 'inert'],\n childList: true,\n subtree: true,\n })\n scheduleFocusRestore(cycle)\n }\n\n onCleanup(() => {\n const cycle = activeFocusCycle\n if (!cycle) return\n cycle.closed = true\n\n // Kobalte dispatches unmount autofocus from a timer. This fallback only\n // releases the scoped focus listener if the content did not dispatch it.\n queueMicrotask(() => {\n if (cycle.closeAutoFocusScheduled) return\n cycle.fallbackTimer = window.setTimeout(() => {\n cycle.fallbackTimer = undefined\n if (!cycle.closeAutoFocusScheduled) finishFocusCycle(cycle)\n }, 0)\n })\n })\n\n return { onOpenAutoFocus, onCloseAutoFocus }\n}\n\n/**\n * Dialog.\n *\n * A modal surface for a decision or a short task. `Dialog.Portal` keeps the\n * panel out of the app's stacking and overflow contexts, `Dialog.Overlay`\n * dims what is behind it, and Kobalte handles the focus trap, the escape key,\n * scroll locking and returning focus to the trigger on close.\n *\n * The close button is part of the content rather than optional, because every\n * modal needs a way out that is not the keyboard. A dialog whose only exit is\n * Escape is a trap for anyone using a pointer.\n */\nexport function Dialog(props: ComponentProps<typeof KobalteDialog>) {\n return <KobalteDialog {...props} />\n}\n\nexport function DialogTrigger(props: ComponentProps<typeof KobalteDialog.Trigger>) {\n return <KobalteDialog.Trigger {...props} />\n}\n\nexport function DialogPortal(props: ComponentProps<typeof KobalteDialog.Portal>) {\n return <KobalteDialog.Portal {...props} />\n}\n\nexport function DialogOverlay(props: ComponentProps<typeof KobalteDialogOverlay>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialogOverlay\n class={cn(\n overlayScrim,\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type DialogContentProps = ComponentProps<typeof KobalteDialogContent> & {\n /**\n * Replaces the default close button. Pass `false` to remove it — only for a\n * dialog that cannot be dismissed (an update that must finish); anything the\n * user can escape from needs the button.\n */\n closeButton?: JSX.Element | false\n /** Use a 1rem inset as the positioner bounds for tall, viewport-filling surfaces. */\n positioner?: 'default' | 'inset'\n}\n\nexport function DialogContent(props: DialogContentProps) {\n const [local, rest] = splitProps(props, ['class', 'children', 'closeButton', 'positioner'])\n\n return (\n <KobalteDialog.Portal>\n <DialogOverlay />\n <div class={cn(overlayPositioner, local.positioner === 'inset' && 'inset-4 grid-rows-1 p-0')}>\n <KobalteDialogContent\n class={cn(\n dialogSurface,\n overlayMotion,\n 'relative grid w-full max-w-lg gap-4 p-5',\n local.class\n )}\n {...rest}\n >\n {local.children}\n <Show when={local.closeButton !== false}>\n {/* The corner close is icon-only, so it carries the shared tooltip\n treatment while its accessible name stays \"Close\". */}\n <Tooltip>\n <TooltipTrigger\n as={KobalteDialog.CloseButton}\n aria-label=\"Close\"\n class={cn(\n 'absolute top-3.5 end-3.5 rounded-md p-1 text-muted-foreground',\n 'transition-colors ease-out hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle outline-none'\n )}\n >\n {local.closeButton ?? <X class=\"size-4\" />}\n </TooltipTrigger>\n <TooltipContent>Close dialog.</TooltipContent>\n </Tooltip>\n </Show>\n </KobalteDialogContent>\n </div>\n </KobalteDialog.Portal>\n )\n}\n\n/**\n * The dialog's title block. `band` steps it onto the elevation ladder's\n * subtle-fill rung (`--muted`), the same treatment as the sheet parts' band —\n * for the dialog family whose panel anatomy matches a sheet's (a title band\n * over a full-bleed shell, such as a settings dialog) rather than the centred\n * modal's documented flat surface. See `SheetFooter` for the rung's rationale.\n */\nexport function DialogHeader(props: ComponentProps<'div'> & { band?: boolean }) {\n const [local, rest] = splitProps(props, ['class', 'band'])\n return (\n <div\n data-slot=\"dialog-header\"\n class={cn('flex flex-col gap-1.5 pe-6 text-start', { 'bg-muted': local.band }, local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"dialog-footer\"\n class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogTitle(props: ComponentProps<typeof KobalteDialog.Title>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.Title class={cn(overlayTitle, local.class)} {...rest} />\n}\n\nexport function DialogDescription(props: ComponentProps<typeof KobalteDialog.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialog.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />\n )\n}\n\nexport function DialogCloseButton(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n\n/**\n * The close control, unstyled and polymorphic — for a footer's text \"Cancel\" or\n * \"Close\", which is a different control from the corner icon `DialogCloseButton`\n * draws. Take it as `as={Button}` so it carries the button's variants rather than\n * a copied class string.\n */\nexport function DialogClose(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dialog.js","names":["Dialog","KobalteDialog","Content","KobalteDialogContent","Overlay","KobalteDialogOverlay","X","Accessor","ComponentProps","JSX","createRenderEffect","onCleanup","Show","splitProps","dialogSurface","overlayMotion","overlayPositioner","overlayScrim","overlayTitle","cn","Tooltip","TooltipContent","TooltipTrigger","FocusCycle","content","HTMLElement","opener","openerEligible","closed","focusMovedOutside","closeAutoFocusScheduled","frame","fallbackTimer","observer","MutationObserver","onFocusIn","event","FocusEvent","canRestoreFocus","target","isConnected","document","body","documentElement","closest","matches","getClientRects","length","hasOtherOverlay","querySelectorAll","some","overlay","contains","DialogFocusRestorationOptions","open","restoreFocusRef","onOpenAutoFocus","onCloseAutoFocus","createDialogFocusRestoration","callerOnOpenAutoFocus","callerOnCloseAutoFocus","focusCycles","WeakMap","activeFocusCycle","pendingOpener","pendingOpenerEligible","active","activeElement","finishFocusCycle","cycle","undefined","window","cancelAnimationFrame","clearTimeout","disconnect","removeEventListener","scheduleFocusRestore","requestAnimationFrame","focusIsAvailable","Node","focus","preventScroll","Event","element","currentTarget","openerWasCaptured","focusEvent","set","addEventListener","get","defaultPrevented","observe","attributes","attributeFilter","childList","subtree","queueMicrotask","setTimeout","props","_$createComponent","DialogTrigger","Trigger","DialogPortal","Portal","DialogOverlay","local","rest","_$mergeProps","class","DialogContentProps","closeButton","Element","positioner","size","DialogContentSize","dialogContentSizes","sm","md","lg","xl","const","DialogContent","children","_el$","_tmpl$","_$insert","_$memo","when","as","CloseButton","_$effect","_$className","DialogHeader","band","_el$2","_tmpl$2","_$spread","DialogFooter","_el$3","_tmpl$3","DialogTitle","Title","DialogDescription","Description","DialogCloseButton","DialogClose","Dialog","_$createComponent","KobalteDialog","KobalteDialogOverlay","_$mergeProps","KobalteDialogContent","_$memo","_$className"],"sources":["../../../../src/components/ui/dialog/dialog.tsx"],"sourcesContent":["import {\n Dialog as KobalteDialog,\n Content as KobalteDialogContent,\n Overlay as KobalteDialogOverlay,\n} from '@kobalte/core/dialog'\n// AlertDialog assigns to the shared DialogRoot.Content object, so these named exports stay role-stable.\nimport { X } from 'lucide-solid'\nimport type { Accessor, ComponentProps, JSX } from 'solid-js'\nimport { createRenderEffect, onCleanup, Show, splitProps } from 'solid-js'\nimport {\n dialogSurface,\n overlayMotion,\n overlayPositioner,\n overlayScrim,\n overlayTitle,\n} from '#lib/overlay'\nimport { cn } from '#lib/utils'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'\n\ntype FocusCycle = {\n content: HTMLElement\n opener: HTMLElement | null\n openerEligible: boolean\n closed: boolean\n focusMovedOutside: boolean\n closeAutoFocusScheduled: boolean\n frame?: number\n fallbackTimer?: number\n observer?: MutationObserver\n onFocusIn: (event: FocusEvent) => void\n}\n\nfunction canRestoreFocus(target: HTMLElement): boolean {\n return (\n target.isConnected &&\n target !== document.body &&\n target !== document.documentElement &&\n !target.closest('[inert], [aria-hidden=\"true\"]') &&\n !target.matches(':disabled') &&\n target.getClientRects().length > 0\n )\n}\n\nfunction hasOtherOverlay(content: HTMLElement, opener: HTMLElement): boolean {\n return [...document.querySelectorAll<HTMLElement>('[role=\"dialog\"], [role=\"alertdialog\"]')].some(\n (overlay) =>\n overlay !== content &&\n !content.contains(overlay) &&\n !overlay.contains(opener) &&\n !overlay.closest('[aria-hidden=\"true\"], [inert]') &&\n overlay.getClientRects().length > 0\n )\n}\n\ntype DialogFocusRestorationOptions = {\n open: Accessor<boolean>\n restoreFocusRef?: Accessor<HTMLElement | undefined>\n onOpenAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onOpenAutoFocus']\n onCloseAutoFocus?: ComponentProps<typeof KobalteDialogContent>['onCloseAutoFocus']\n}\n\n/**\n * Adds guarded opener capture and restoration to a Kobalte dialog content.\n * Composed surfaces use this internal helper; it is omitted from the public\n * dialog barrel so the restoration policy stays with the dialog components.\n */\nexport function createDialogFocusRestoration({\n open,\n restoreFocusRef,\n onOpenAutoFocus: callerOnOpenAutoFocus,\n onCloseAutoFocus: callerOnCloseAutoFocus,\n}: DialogFocusRestorationOptions) {\n const focusCycles = new WeakMap<HTMLElement, FocusCycle>()\n let activeFocusCycle: FocusCycle | undefined\n let pendingOpener: HTMLElement | null = null\n let pendingOpenerEligible = false\n\n createRenderEffect(() => {\n if (!open() || typeof document === 'undefined') {\n pendingOpener = null\n pendingOpenerEligible = false\n return\n }\n const active = restoreFocusRef?.() ?? document.activeElement\n pendingOpener = active instanceof HTMLElement ? active : null\n pendingOpenerEligible = active instanceof HTMLElement && canRestoreFocus(active)\n })\n\n const finishFocusCycle = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) window.cancelAnimationFrame(cycle.frame)\n if (cycle.fallbackTimer !== undefined) window.clearTimeout(cycle.fallbackTimer)\n cycle.observer?.disconnect()\n document.removeEventListener('focusin', cycle.onFocusIn)\n if (activeFocusCycle === cycle) activeFocusCycle = undefined\n }\n\n const scheduleFocusRestore = (cycle: FocusCycle) => {\n if (cycle.frame !== undefined) return\n cycle.frame = window.requestAnimationFrame(() => {\n cycle.frame = undefined\n const opener = cycle.opener\n const active = document.activeElement\n const focusIsAvailable =\n active === document.body ||\n active === document.documentElement ||\n active === cycle.content ||\n (active instanceof Node && cycle.content.contains(active))\n if (\n activeFocusCycle !== cycle ||\n !cycle.closed ||\n cycle.focusMovedOutside ||\n !opener ||\n !opener.isConnected ||\n opener.matches(':disabled') ||\n opener.getClientRects().length === 0 ||\n !focusIsAvailable ||\n hasOtherOverlay(cycle.content, opener)\n ) {\n finishFocusCycle(cycle)\n return\n }\n\n // Inert and aria-hidden are removed by the dialog's containment cleanup.\n // Wait for that cleanup before returning focus to the original control.\n if (opener.closest('[inert], [aria-hidden=\"true\"]')) return\n if (cycle.openerEligible && canRestoreFocus(opener)) {\n opener.focus({ preventScroll: true })\n }\n finishFocusCycle(cycle)\n })\n }\n\n const onOpenAutoFocus = (event: Event) => {\n const element = event.currentTarget\n if (element instanceof HTMLElement) {\n if (activeFocusCycle) finishFocusCycle(activeFocusCycle)\n\n const openerWasCaptured = pendingOpener !== null\n const opener = pendingOpener ?? document.activeElement\n const openerEligible = openerWasCaptured\n ? pendingOpenerEligible\n : opener instanceof HTMLElement && canRestoreFocus(opener)\n pendingOpener = null\n pendingOpenerEligible = false\n const cycle: FocusCycle = {\n content: element,\n opener: opener instanceof HTMLElement ? opener : null,\n openerEligible,\n closed: false,\n focusMovedOutside: false,\n closeAutoFocusScheduled: false,\n onFocusIn: (focusEvent) => {\n const target = focusEvent.target\n if (\n !(target instanceof HTMLElement) ||\n target === document.body ||\n target === document.documentElement\n ) {\n return\n }\n if (\n target === element ||\n element.contains(target) ||\n target === (opener instanceof HTMLElement ? opener : null)\n ) {\n if (!cycle.closed) cycle.focusMovedOutside = false\n return\n }\n cycle.focusMovedOutside = true\n },\n }\n focusCycles.set(element, cycle)\n activeFocusCycle = cycle\n document.addEventListener('focusin', cycle.onFocusIn)\n }\n callerOnOpenAutoFocus?.(event)\n }\n\n const onCloseAutoFocus = (event: Event) => {\n const element = event.currentTarget\n const cycle = element instanceof HTMLElement ? focusCycles.get(element) : undefined\n callerOnCloseAutoFocus?.(event)\n\n if (!cycle) return\n cycle.closed = true\n\n // A caller that prevents Kobalte's close autofocus owns the focus decision.\n if (event.defaultPrevented) {\n finishFocusCycle(cycle)\n return\n }\n\n if (cycle.fallbackTimer !== undefined) {\n window.clearTimeout(cycle.fallbackTimer)\n cycle.fallbackTimer = undefined\n }\n cycle.closeAutoFocusScheduled = true\n cycle.observer = new MutationObserver(() => scheduleFocusRestore(cycle))\n cycle.observer.observe(document.body, {\n attributes: true,\n attributeFilter: ['aria-hidden', 'inert'],\n childList: true,\n subtree: true,\n })\n scheduleFocusRestore(cycle)\n }\n\n onCleanup(() => {\n const cycle = activeFocusCycle\n if (!cycle) return\n cycle.closed = true\n\n // Kobalte dispatches unmount autofocus from a timer. This fallback only\n // releases the scoped focus listener if the content did not dispatch it.\n queueMicrotask(() => {\n if (cycle.closeAutoFocusScheduled) return\n cycle.fallbackTimer = window.setTimeout(() => {\n cycle.fallbackTimer = undefined\n if (!cycle.closeAutoFocusScheduled) finishFocusCycle(cycle)\n }, 0)\n })\n })\n\n return { onOpenAutoFocus, onCloseAutoFocus }\n}\n\n/**\n * Dialog.\n *\n * A modal surface for a decision or a short task. `Dialog.Portal` keeps the\n * panel out of the app's stacking and overflow contexts, `Dialog.Overlay`\n * dims what is behind it, and Kobalte handles the focus trap, the escape key,\n * scroll locking and returning focus to the trigger on close.\n *\n * The close button is part of the content rather than optional, because every\n * modal needs a way out that is not the keyboard. A dialog whose only exit is\n * Escape is a trap for anyone using a pointer.\n */\nexport function Dialog(props: ComponentProps<typeof KobalteDialog>) {\n return <KobalteDialog {...props} />\n}\n\nexport function DialogTrigger(props: ComponentProps<typeof KobalteDialog.Trigger>) {\n return <KobalteDialog.Trigger {...props} />\n}\n\nexport function DialogPortal(props: ComponentProps<typeof KobalteDialog.Portal>) {\n return <KobalteDialog.Portal {...props} />\n}\n\nexport function DialogOverlay(props: ComponentProps<typeof KobalteDialogOverlay>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialogOverlay\n class={cn(\n overlayScrim,\n 'data-expanded:animate-in data-expanded:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type DialogContentProps = ComponentProps<typeof KobalteDialogContent> & {\n /**\n * Replaces the default close button. Pass `false` to remove it — only for a\n * dialog that cannot be dismissed (an update that must finish); anything the\n * user can escape from needs the button.\n */\n closeButton?: JSX.Element | false\n /** Use a 1rem inset as the positioner bounds for tall, viewport-filling surfaces. */\n positioner?: 'default' | 'inset'\n /**\n * The panel's maximum width. `md` (32rem) is the default and right for a\n * confirmation or a short form; `sm` (28rem) for a single question; `lg`\n * (42rem) for a picker or a form with two columns; `xl` (48rem) for a\n * multi-step flow that needs a table or a preview beside its fields.\n */\n size?: DialogContentSize\n}\n\n/** The dialog width ladder, so a caller picks a rung instead of a `max-w-*`. */\nexport const dialogContentSizes = {\n sm: 'max-w-md',\n md: 'max-w-lg',\n lg: 'max-w-2xl',\n xl: 'max-w-3xl',\n} as const\n\nexport type DialogContentSize = keyof typeof dialogContentSizes\n\nexport function DialogContent(props: DialogContentProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'children',\n 'closeButton',\n 'positioner',\n 'size',\n ])\n\n return (\n <KobalteDialog.Portal>\n <DialogOverlay />\n <div class={cn(overlayPositioner, local.positioner === 'inset' && 'inset-4 grid-rows-1 p-0')}>\n <KobalteDialogContent\n class={cn(\n dialogSurface,\n overlayMotion,\n 'relative grid w-full gap-4 p-5',\n dialogContentSizes[local.size ?? 'md'],\n local.class\n )}\n {...rest}\n >\n {local.children}\n <Show when={local.closeButton !== false}>\n {/* The corner close is icon-only, so it carries the shared tooltip\n treatment while its accessible name stays \"Close\". */}\n <Tooltip>\n <TooltipTrigger\n as={KobalteDialog.CloseButton}\n aria-label=\"Close\"\n class={cn(\n 'absolute top-3.5 end-3.5 rounded-md p-1 text-muted-foreground',\n 'transition-colors ease-out hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle outline-none'\n )}\n >\n {local.closeButton ?? <X class=\"size-4\" />}\n </TooltipTrigger>\n <TooltipContent>Close dialog.</TooltipContent>\n </Tooltip>\n </Show>\n </KobalteDialogContent>\n </div>\n </KobalteDialog.Portal>\n )\n}\n\n/**\n * The dialog's title block. `band` steps it onto the elevation ladder's\n * subtle-fill rung (`--muted`), the same treatment as the sheet parts' band —\n * for the dialog family whose panel anatomy matches a sheet's (a title band\n * over a full-bleed shell, such as a settings dialog) rather than the centred\n * modal's documented flat surface. See `SheetFooter` for the rung's rationale.\n */\nexport function DialogHeader(props: ComponentProps<'div'> & { band?: boolean }) {\n const [local, rest] = splitProps(props, ['class', 'band'])\n return (\n <div\n data-slot=\"dialog-header\"\n class={cn('flex flex-col gap-1.5 pe-6 text-start', { 'bg-muted': local.band }, local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogFooter(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"dialog-footer\"\n class={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', local.class)}\n {...rest}\n />\n )\n}\n\nexport function DialogTitle(props: ComponentProps<typeof KobalteDialog.Title>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.Title class={cn(overlayTitle, local.class)} {...rest} />\n}\n\nexport function DialogDescription(props: ComponentProps<typeof KobalteDialog.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteDialog.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />\n )\n}\n\nexport function DialogCloseButton(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n\n/**\n * The close control, unstyled and polymorphic — for a footer's text \"Cancel\" or\n * \"Close\", which is a different control from the corner icon `DialogCloseButton`\n * draws. Take it as `as={Button}` so it carries the button's variants rather than\n * a copied class string.\n */\nexport function DialogClose(props: ComponentProps<typeof KobalteDialog.CloseButton>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteDialog.CloseButton class={cn('focus-ring', local.class)} {...rest} />\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type DialogContentProps, } from './dialog';
|
|
1
|
+
export { Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type DialogContentProps, type DialogContentSize, } from './dialog';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,EACb,KAAK,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/dialog/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAA"}
|
|
@@ -25,6 +25,14 @@ import { type VariantProps } from '#lib/variants';
|
|
|
25
25
|
* `shape="rounded"` is the default because a rounded square reads as an object
|
|
26
26
|
* and a circle reads as a person; use `circle` only when the tile really does
|
|
27
27
|
* hold a face.
|
|
28
|
+
*
|
|
29
|
+
* `monochrome` is for a third-party brand mark — a vendor logo drawn with its
|
|
30
|
+
* own `fill`. A brand's hex is chosen for a white page: GitHub's near-black and
|
|
31
|
+
* Slack's aubergine all but vanish on a dark tile, and no tone can be picked
|
|
32
|
+
* that suits every brand in both themes. `monochrome` repaints any explicitly
|
|
33
|
+
* filled shape in the tile's glyph colour (the tone's), so the mark stays
|
|
34
|
+
* recognisable by its shape and legible in every theme. Stroke-drawn icons
|
|
35
|
+
* (Lucide, `fill="none"`) are left alone.
|
|
28
36
|
*/
|
|
29
37
|
export declare const entityIconVariants: (props?: ({
|
|
30
38
|
shape?: "circle" | "square" | "rounded" | null | undefined;
|
|
@@ -50,6 +58,8 @@ export type EntityIconProps = Omit<ComponentProps<'span'>, 'children'> & EntityI
|
|
|
50
58
|
badge?: JSX.Element;
|
|
51
59
|
/** A second edge, drawn outside the tile — an active or selected ring. */
|
|
52
60
|
ring?: boolean;
|
|
61
|
+
/** Repaint a brand mark's own fills in the tile's glyph colour. */
|
|
62
|
+
monochrome?: boolean;
|
|
53
63
|
};
|
|
54
64
|
/**
|
|
55
65
|
* Two letters from a name, chosen so the result is stable and readable: the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-icon.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/entity-icon/entity-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAGtD
|
|
1
|
+
{"version":3,"file":"entity-icon.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/entity-icon/entity-icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,GAAG,EACT,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAGtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,kBAAkB;;;;8EA+B9B,CAAA;AAED,KAAK,sBAAsB,GAAG,YAAY,CAAC,OAAO,kBAAkB,CAAC,CAAA;AAErE,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,GACpE,sBAAsB,GAAG;IACvB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAA;IACZ,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO,CAAA;IAC9B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,CAAC,OAAO,CAAA;IACxC,wEAAwE;IACxE,KAAK,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACnB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAEH;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI7C;AAkCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eAoDhD"}
|
|
@@ -5,7 +5,7 @@ import { Show, createSignal, splitProps } from "solid-js";
|
|
|
5
5
|
//#region src/components/ui/entity-icon/entity-icon.tsx
|
|
6
6
|
var _tmpl$ = /*#__PURE__*/ template(`<img data-slot=entity-icon-image alt aria-hidden=true class="pointer-events-none absolute inset-0 size-full object-contain">`);
|
|
7
7
|
var _tmpl$2 = /*#__PURE__*/ template(`<span class="absolute right-0 bottom-0 translate-x-1/4 translate-y-1/4">`);
|
|
8
|
-
var _tmpl$3 = /*#__PURE__*/ template(`<span role=img>`);
|
|
8
|
+
var _tmpl$3 = /*#__PURE__*/ template(`<span data-slot=entity-icon role=img>`);
|
|
9
9
|
/**
|
|
10
10
|
* EntityIcon.
|
|
11
11
|
*
|
|
@@ -31,6 +31,14 @@ var _tmpl$3 = /*#__PURE__*/ template(`<span role=img>`);
|
|
|
31
31
|
* `shape="rounded"` is the default because a rounded square reads as an object
|
|
32
32
|
* and a circle reads as a person; use `circle` only when the tile really does
|
|
33
33
|
* hold a face.
|
|
34
|
+
*
|
|
35
|
+
* `monochrome` is for a third-party brand mark — a vendor logo drawn with its
|
|
36
|
+
* own `fill`. A brand's hex is chosen for a white page: GitHub's near-black and
|
|
37
|
+
* Slack's aubergine all but vanish on a dark tile, and no tone can be picked
|
|
38
|
+
* that suits every brand in both themes. `monochrome` repaints any explicitly
|
|
39
|
+
* filled shape in the tile's glyph colour (the tone's), so the mark stays
|
|
40
|
+
* recognisable by its shape and legible in every theme. Stroke-drawn icons
|
|
41
|
+
* (Lucide, `fill="none"`) are left alone.
|
|
34
42
|
*/
|
|
35
43
|
var entityIconVariants = cva("relative inline-flex shrink-0 items-center justify-center overflow-hidden border font-semibold select-none [&_svg]:pointer-events-none [&_svg]:shrink-0", {
|
|
36
44
|
variants: {
|
|
@@ -102,6 +110,7 @@ function EntityIcon(props) {
|
|
|
102
110
|
"fallback",
|
|
103
111
|
"badge",
|
|
104
112
|
"ring",
|
|
113
|
+
"monochrome",
|
|
105
114
|
"shape",
|
|
106
115
|
"size",
|
|
107
116
|
"tone",
|
|
@@ -126,7 +135,7 @@ function EntityIcon(props) {
|
|
|
126
135
|
shape: local.shape,
|
|
127
136
|
size: local.size,
|
|
128
137
|
tone: local.tone
|
|
129
|
-
}), local.ring && "ring-2 ring-ring ring-offset-2 ring-offset-background", local.class);
|
|
138
|
+
}), local.ring && "ring-2 ring-ring ring-offset-2 ring-offset-background", local.monochrome && "[&_[fill]:not([fill='none'])]:fill-current", local.class);
|
|
130
139
|
},
|
|
131
140
|
get ["aria-label"]() {
|
|
132
141
|
return local.name;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-icon.js","names":["createSignal","Show","splitProps","Component","ComponentProps","JSX","Dynamic","cva","VariantProps","cn","entityIconVariants","variants","shape","rounded","circle","square","size","xs","sm","md","lg","xl","tone","neutral","primary","bare","success","warning","danger","info","defaultVariants","EntityIconVariantProps","EntityIconProps","Omit","name","src","icon","Element","fallback","badge","ring","monogram","words","trim","split","filter","Boolean","length","toUpperCase","slice","Glyph","kind","value","props","glyph","_$createComponent","component","EntityIconImage","failed","setFailed","when","children","_el$","_tmpl$","addEventListener","_$effect","_$setAttribute","EntityIcon","local","rest","undefined","_el$2","_tmpl$3","_$spread","_$mergeProps","class","aria-label","_$insert","_$memo","keyed","_el$3","_tmpl$2","_$createComponent","_$setAttribute","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/entity-icon/entity-icon.tsx"],"sourcesContent":["import {\n createSignal,\n Show,\n splitProps,\n type Component,\n type ComponentProps,\n type JSX,\n} from 'solid-js'\nimport { Dynamic } from 'solid-js/web'\nimport { cva, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * EntityIcon.\n *\n * A tile that stands for a thing: a room, a project, an agent, an installed\n * plugin, a workspace. Its job is to be identifiable in a column of its\n * siblings, which is a different job from `Avatar`'s (identifying a *person*) and\n * the reason the two are separate components rather than one with a `round` prop.\n *\n * Three decisions are baked in because getting them wrong is what makes icon\n * grids look messy:\n *\n * 1. **A glyph is always present.** A brand with no logo gets a monogram, not an\n * empty box. `fallback` takes the name and returns the glyph, so a caller can\n * choose initials, a domain letter, or a kind icon. When `src` is supplied,\n * its contained image overlays that glyph and failure reveals the glyph below.\n * 2. **The tile owns its own contrast.** `tone` tints the background while\n * monogram text keeps the body foreground; vector glyphs retain the status\n * colour. A caller never picks a colour pair or ships a glyph that disappears.\n * 3. **Size is on the control ladder**, not arbitrary. A tile in a rail and a\n * tile in a detail header are the same two or three sizes every other\n * interactive element uses.\n *\n * `shape=\"rounded\"` is the default because a rounded square reads as an object\n * and a circle reads as a person; use `circle` only when the tile really does\n * hold a face.\n */\nexport const entityIconVariants = cva(\n 'relative inline-flex shrink-0 items-center justify-center overflow-hidden border font-semibold select-none [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n shape: {\n rounded: 'rounded-lg',\n circle: 'rounded-full',\n square: 'rounded-none',\n },\n size: {\n xs: 'size-5 text-2xs [&_svg]:size-3',\n sm: 'size-6 text-2xs [&_svg]:size-3.5',\n md: 'size-8 text-xs [&_svg]:size-4',\n lg: 'size-10 text-sm [&_svg]:size-5',\n xl: 'size-12 text-base [&_svg]:size-6',\n },\n tone: {\n /** Neutral: an inset tile with a hairline edge — the default. */\n neutral: 'border-border bg-muted text-muted-foreground',\n /** On the brand: for a thing the application itself owns. */\n primary: 'border-transparent bg-primary-subtle text-primary',\n /** Bare: no fill and no edge, for a tile that already sits on a surface. */\n bare: 'border-transparent bg-transparent text-foreground',\n success: 'border-transparent bg-success-subtle text-foreground [&_svg]:text-success',\n warning: 'border-transparent bg-warning-subtle text-foreground [&_svg]:text-warning',\n danger: 'border-transparent bg-destructive-subtle text-foreground [&_svg]:text-destructive',\n info: 'border-transparent bg-info-subtle text-foreground [&_svg]:text-info',\n },\n },\n defaultVariants: { shape: 'rounded', size: 'md', tone: 'neutral' },\n }\n)\n\ntype EntityIconVariantProps = VariantProps<typeof entityIconVariants>\n\nexport type EntityIconProps = Omit<ComponentProps<'span'>, 'children'> &\n EntityIconVariantProps & {\n /** The entity's name. Used for the accessible label and, via `fallback`, the monogram. */\n name: string\n /** Optional image URL. The image is decorative; `name` remains the accessible label. */\n src?: string\n /**\n * A logo or icon — a Lucide icon reference (`icon={Wrench}`) or an element\n * (`icon={<Wrench />}`). Both are accepted because both are what a caller\n * naturally writes, and the difference is an implementation detail they should\n * not have to know.\n */\n icon?: Component | JSX.Element\n /** Glyph for an entity with no icon. Defaults to the name's first two letters. */\n fallback?: (name: string) => JSX.Element\n /** A corner badge: a status dot, an unread count, an installed tick. */\n badge?: JSX.Element\n /** A second edge, drawn outside the tile — an active or selected ring. */\n ring?: boolean\n }\n\n/**\n * Two letters from a name, chosen so the result is stable and readable: the\n * first letter of the first two words when there are two (\"Agent HQ\" → \"AH\"),\n * otherwise the first two characters (\"Kitchen\" → \"Ki\").\n */\nexport function monogram(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n if (words.length >= 2) return (words[0]![0]! + words[1]![0]!).toUpperCase()\n return name.trim().slice(0, 2)\n}\n\n/**\n * A glyph is either a component reference or an element, and the two render\n * differently — `Dynamic` for the first, the element itself for the second. The\n * union is discriminated so the branch is checked rather than cast.\n */\ntype Glyph = { kind: 'component'; value: Component } | { kind: 'element'; value: JSX.Element }\n\nfunction Glyph(props: { glyph: Glyph }) {\n return props.glyph.kind === 'component' ? (\n <Dynamic component={props.glyph.value} />\n ) : (\n props.glyph.value\n )\n}\n\nfunction EntityIconImage(props: { src: string }) {\n const [failed, setFailed] = createSignal(false)\n\n return (\n <Show when={!failed()}>\n <img\n data-slot=\"entity-icon-image\"\n src={props.src}\n alt=\"\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 size-full object-contain\"\n onError={() => setFailed(true)}\n />\n </Show>\n )\n}\n\nexport function EntityIcon(props: EntityIconProps) {\n const [local, rest] = splitProps(props, [\n 'name',\n 'src',\n 'icon',\n 'fallback',\n 'badge',\n 'ring',\n 'shape',\n 'size',\n 'tone',\n 'class',\n ])\n\n const glyph = (): Glyph | undefined => {\n const icon = local.icon\n if (!icon) return undefined\n return typeof icon === 'function'\n ? { kind: 'component', value: icon as Component }\n : { kind: 'element', value: icon as JSX.Element }\n }\n\n return (\n <span\n class={cn(\n entityIconVariants({ shape: local.shape, size: local.size, tone: local.tone }),\n local.ring && 'ring-2 ring-ring ring-offset-2 ring-offset-background',\n local.class\n )}\n role=\"img\"\n aria-label={local.name}\n {...rest}\n >\n <Show\n when={glyph()}\n fallback={local.fallback ? local.fallback(local.name) : monogram(local.name)}\n >\n {(value) => <Glyph glyph={value()} />}\n </Show>\n <Show when={local.src} keyed>\n {(src) => <EntityIconImage src={src} />}\n </Show>\n <Show when={local.badge}>\n <span class=\"absolute right-0 bottom-0 translate-x-1/4 translate-y-1/4\">{local.badge}</span>\n </Show>\n </span>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"entity-icon.js","names":["createSignal","Show","splitProps","Component","ComponentProps","JSX","Dynamic","cva","VariantProps","cn","entityIconVariants","variants","shape","rounded","circle","square","size","xs","sm","md","lg","xl","tone","neutral","primary","bare","success","warning","danger","info","defaultVariants","EntityIconVariantProps","EntityIconProps","Omit","name","src","icon","Element","fallback","badge","ring","monochrome","monogram","words","trim","split","filter","Boolean","length","toUpperCase","slice","Glyph","kind","value","props","glyph","_$createComponent","component","EntityIconImage","failed","setFailed","when","children","_el$","_tmpl$","addEventListener","_$effect","_$setAttribute","EntityIcon","local","rest","undefined","_el$2","_tmpl$3","_$spread","_$mergeProps","class","aria-label","_$insert","_$memo","keyed","_el$3","_tmpl$2","_$createComponent","_$setAttribute","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/entity-icon/entity-icon.tsx"],"sourcesContent":["import {\n createSignal,\n Show,\n splitProps,\n type Component,\n type ComponentProps,\n type JSX,\n} from 'solid-js'\nimport { Dynamic } from 'solid-js/web'\nimport { cva, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * EntityIcon.\n *\n * A tile that stands for a thing: a room, a project, an agent, an installed\n * plugin, a workspace. Its job is to be identifiable in a column of its\n * siblings, which is a different job from `Avatar`'s (identifying a *person*) and\n * the reason the two are separate components rather than one with a `round` prop.\n *\n * Three decisions are baked in because getting them wrong is what makes icon\n * grids look messy:\n *\n * 1. **A glyph is always present.** A brand with no logo gets a monogram, not an\n * empty box. `fallback` takes the name and returns the glyph, so a caller can\n * choose initials, a domain letter, or a kind icon. When `src` is supplied,\n * its contained image overlays that glyph and failure reveals the glyph below.\n * 2. **The tile owns its own contrast.** `tone` tints the background while\n * monogram text keeps the body foreground; vector glyphs retain the status\n * colour. A caller never picks a colour pair or ships a glyph that disappears.\n * 3. **Size is on the control ladder**, not arbitrary. A tile in a rail and a\n * tile in a detail header are the same two or three sizes every other\n * interactive element uses.\n *\n * `shape=\"rounded\"` is the default because a rounded square reads as an object\n * and a circle reads as a person; use `circle` only when the tile really does\n * hold a face.\n *\n * `monochrome` is for a third-party brand mark — a vendor logo drawn with its\n * own `fill`. A brand's hex is chosen for a white page: GitHub's near-black and\n * Slack's aubergine all but vanish on a dark tile, and no tone can be picked\n * that suits every brand in both themes. `monochrome` repaints any explicitly\n * filled shape in the tile's glyph colour (the tone's), so the mark stays\n * recognisable by its shape and legible in every theme. Stroke-drawn icons\n * (Lucide, `fill=\"none\"`) are left alone.\n */\nexport const entityIconVariants = cva(\n 'relative inline-flex shrink-0 items-center justify-center overflow-hidden border font-semibold select-none [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n shape: {\n rounded: 'rounded-lg',\n circle: 'rounded-full',\n square: 'rounded-none',\n },\n size: {\n xs: 'size-5 text-2xs [&_svg]:size-3',\n sm: 'size-6 text-2xs [&_svg]:size-3.5',\n md: 'size-8 text-xs [&_svg]:size-4',\n lg: 'size-10 text-sm [&_svg]:size-5',\n xl: 'size-12 text-base [&_svg]:size-6',\n },\n tone: {\n /** Neutral: an inset tile with a hairline edge — the default. */\n neutral: 'border-border bg-muted text-muted-foreground',\n /** On the brand: for a thing the application itself owns. */\n primary: 'border-transparent bg-primary-subtle text-primary',\n /** Bare: no fill and no edge, for a tile that already sits on a surface. */\n bare: 'border-transparent bg-transparent text-foreground',\n success: 'border-transparent bg-success-subtle text-foreground [&_svg]:text-success',\n warning: 'border-transparent bg-warning-subtle text-foreground [&_svg]:text-warning',\n danger: 'border-transparent bg-destructive-subtle text-foreground [&_svg]:text-destructive',\n info: 'border-transparent bg-info-subtle text-foreground [&_svg]:text-info',\n },\n },\n defaultVariants: { shape: 'rounded', size: 'md', tone: 'neutral' },\n }\n)\n\ntype EntityIconVariantProps = VariantProps<typeof entityIconVariants>\n\nexport type EntityIconProps = Omit<ComponentProps<'span'>, 'children'> &\n EntityIconVariantProps & {\n /** The entity's name. Used for the accessible label and, via `fallback`, the monogram. */\n name: string\n /** Optional image URL. The image is decorative; `name` remains the accessible label. */\n src?: string\n /**\n * A logo or icon — a Lucide icon reference (`icon={Wrench}`) or an element\n * (`icon={<Wrench />}`). Both are accepted because both are what a caller\n * naturally writes, and the difference is an implementation detail they should\n * not have to know.\n */\n icon?: Component | JSX.Element\n /** Glyph for an entity with no icon. Defaults to the name's first two letters. */\n fallback?: (name: string) => JSX.Element\n /** A corner badge: a status dot, an unread count, an installed tick. */\n badge?: JSX.Element\n /** A second edge, drawn outside the tile — an active or selected ring. */\n ring?: boolean\n /** Repaint a brand mark's own fills in the tile's glyph colour. */\n monochrome?: boolean\n }\n\n/**\n * Two letters from a name, chosen so the result is stable and readable: the\n * first letter of the first two words when there are two (\"Agent HQ\" → \"AH\"),\n * otherwise the first two characters (\"Kitchen\" → \"Ki\").\n */\nexport function monogram(name: string): string {\n const words = name.trim().split(/\\s+/).filter(Boolean)\n if (words.length >= 2) return (words[0]![0]! + words[1]![0]!).toUpperCase()\n return name.trim().slice(0, 2)\n}\n\n/**\n * A glyph is either a component reference or an element, and the two render\n * differently — `Dynamic` for the first, the element itself for the second. The\n * union is discriminated so the branch is checked rather than cast.\n */\ntype Glyph = { kind: 'component'; value: Component } | { kind: 'element'; value: JSX.Element }\n\nfunction Glyph(props: { glyph: Glyph }) {\n return props.glyph.kind === 'component' ? (\n <Dynamic component={props.glyph.value} />\n ) : (\n props.glyph.value\n )\n}\n\nfunction EntityIconImage(props: { src: string }) {\n const [failed, setFailed] = createSignal(false)\n\n return (\n <Show when={!failed()}>\n <img\n data-slot=\"entity-icon-image\"\n src={props.src}\n alt=\"\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 size-full object-contain\"\n onError={() => setFailed(true)}\n />\n </Show>\n )\n}\n\nexport function EntityIcon(props: EntityIconProps) {\n const [local, rest] = splitProps(props, [\n 'name',\n 'src',\n 'icon',\n 'fallback',\n 'badge',\n 'ring',\n 'monochrome',\n 'shape',\n 'size',\n 'tone',\n 'class',\n ])\n\n const glyph = (): Glyph | undefined => {\n const icon = local.icon\n if (!icon) return undefined\n return typeof icon === 'function'\n ? { kind: 'component', value: icon as Component }\n : { kind: 'element', value: icon as JSX.Element }\n }\n\n return (\n <span\n data-slot=\"entity-icon\"\n class={cn(\n entityIconVariants({ shape: local.shape, size: local.size, tone: local.tone }),\n local.ring && 'ring-2 ring-ring ring-offset-2 ring-offset-background',\n // A presentation attribute (`fill=\"#4A154B\"`) loses to any CSS rule, so\n // this overrides the brand's hex without touching the caller's SVG.\n local.monochrome && \"[&_[fill]:not([fill='none'])]:fill-current\",\n local.class\n )}\n role=\"img\"\n aria-label={local.name}\n {...rest}\n >\n <Show\n when={glyph()}\n fallback={local.fallback ? local.fallback(local.name) : monogram(local.name)}\n >\n {(value) => <Glyph glyph={value()} />}\n </Show>\n <Show when={local.src} keyed>\n {(src) => <EntityIconImage src={src} />}\n </Show>\n <Show when={local.badge}>\n <span class=\"absolute right-0 bottom-0 translate-x-1/4 translate-y-1/4\">{local.badge}</span>\n </Show>\n </span>\n )\n}\n"],"mappings":"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"}
|
|
@@ -49,8 +49,18 @@ export declare function FieldTextArea(props: ComponentProps<typeof KobalteTextFi
|
|
|
49
49
|
* before reading the four fields inside it.
|
|
50
50
|
*/
|
|
51
51
|
export declare function FieldSet(props: ComponentProps<'fieldset'>): JSX.Element;
|
|
52
|
+
export type FieldGroupProps = ComponentProps<'div'> & {
|
|
53
|
+
/**
|
|
54
|
+
* `2` lays the fields out in two columns from the `sm` breakpoint up — a
|
|
55
|
+
* short form of paired values (host and port, a name and a model). A field
|
|
56
|
+
* that needs the full width says `class="col-span-full"`. Below `sm` it is
|
|
57
|
+
* one column again, because two inputs side by side on a phone are each too
|
|
58
|
+
* narrow to read.
|
|
59
|
+
*/
|
|
60
|
+
columns?: 1 | 2;
|
|
61
|
+
};
|
|
52
62
|
/** A visual stack for related controls that does not imply fieldset semantics. */
|
|
53
|
-
export declare function FieldGroup(props:
|
|
63
|
+
export declare function FieldGroup(props: FieldGroupProps): JSX.Element;
|
|
54
64
|
export declare function FieldLegend(props: ComponentProps<'legend'> & {
|
|
55
65
|
variant?: 'legend' | 'label';
|
|
56
66
|
}): JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/field/field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAOnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,eAGnE;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,GAAG;IAC7E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,eAkE9C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,eAK9E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,WAAW,CAAC,eAQ1F;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,YAAY,CAAC,eAKrF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,eAiB9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,eAiBpF;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,eAGzD;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/field/field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAOnD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,eAGnE;AAED,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,GAAG;IAC7E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;CACtB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,eAkE9C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,eAK9E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,WAAW,CAAC,eAQ1F;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,YAAY,CAAC,eAKrF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,eAiB9E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,eAiBpF;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,eAGzD;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG;IACpD;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;CAChB,CAAA;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eAYhD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;CAAE,eAY7F;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAA;CAC9C,eAYA"}
|
|
@@ -188,11 +188,11 @@ function FieldSet(props) {
|
|
|
188
188
|
}
|
|
189
189
|
/** A visual stack for related controls that does not imply fieldset semantics. */
|
|
190
190
|
function FieldGroup(props) {
|
|
191
|
-
const [local, rest] = splitProps(props, ["class"]);
|
|
191
|
+
const [local, rest] = splitProps(props, ["class", "columns"]);
|
|
192
192
|
return (() => {
|
|
193
193
|
var _el$5 = _tmpl$5();
|
|
194
194
|
spread(_el$5, mergeProps({ get ["class"]() {
|
|
195
|
-
return cn("flex flex-col gap-4", local.class);
|
|
195
|
+
return cn(local.columns === 2 ? "grid gap-4 sm:grid-cols-2" : "flex flex-col gap-4", local.class);
|
|
196
196
|
} }, rest), false, false);
|
|
197
197
|
return _el$5;
|
|
198
198
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.js","names":["TextField","KobalteTextField","ComponentProps","JSX","createUniqueId","Show","splitProps","Label","createFormFieldContext","FormFieldContext","cn","headingVariants","Field","props","local","rest","_$createComponent","_$mergeProps","class","FormFieldProps","Omit","label","hint","error","controlId","group","children","Element","FormField","fieldId","labelId","descriptionId","errorId","field","defaultControlId","help","when","_el$","_tmpl$","_$setAttribute","_$insert","_el$2","_tmpl$2","Provider","value","_el$3","_tmpl$3","_$spread","_c$","_$memo","FieldSet","aria-describedby","describedBy","aria-invalid","invalid","undefined","FieldLegend","id","variant","for","FieldLabel","FieldDescription","Description","FieldError","ErrorMessage","FieldInput","Input","FieldTextArea","TextArea","_el$4","_tmpl$4","FieldGroup","_el$5","_tmpl$5","_el$6","_tmpl$6","size","FieldSeparator","_el$7","_tmpl$8","_el$8","firstChild","_el$0","nextSibling","_el$9","_tmpl$7","_$createComponent","KobalteTextField","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/field/field.tsx"],"sourcesContent":["import { TextField as KobalteTextField } from '@kobalte/core/text-field'\nimport type { ComponentProps, JSX } from 'solid-js'\nimport { createUniqueId, Show, splitProps } from 'solid-js'\nimport { Label } from '../label/label'\nimport { createFormFieldContext, FormFieldContext } from '#lib/form-field'\nimport { cn } from '#lib/utils'\nimport { headingVariants } from '../typography'\n\n/**\n * Field.\n *\n * The wrapper that makes a form control describable and validatable: a label,\n * a description, an error message, and the ARIA relationships between them.\n *\n * This Kobalte TextField composition is for its own `FieldLabel`, `FieldInput`\n * and `FieldTextArea` parts. Use `FormField` to wire the standalone shared\n * controls, including checkboxes, switches and comboboxes.\n *\n * It is built on Kobalte's TextField specifically so `aria-describedby`,\n * `aria-invalid` and `aria-errormessage` are wired by construction. Those three\n * attributes are the difference between \"this field is required and empty\" and\n * a red border that only a sighted user can perceive — and they are also the\n * first thing a hand-rolled form drops.\n *\n * `Field` owns the description and the error slot, so its controls line up and\n * its messages land in the same place regardless of which TextField part is used.\n */\nexport function Field(props: ComponentProps<typeof KobalteTextField>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteTextField class={cn('flex flex-col gap-1.5', local.class)} {...rest} />\n}\n\nexport type FormFieldProps = Omit<ComponentProps<'div'>, 'children' | 'ref'> & {\n label: string\n hint?: string\n error?: string\n controlId?: string\n group?: boolean\n children: JSX.Element\n}\n\n/**\n * FormField.\n *\n * A shared label, help and validation wrapper for any one shared control. Its\n * context is consumed by Input, Textarea, NativeSelect, Checkbox, Switch,\n * RadioGroup and ComboboxInput, so the actual focusable element receives the\n * generated ID and description relationships. Set `group` when the label names\n * a set of controls; the wrapper then uses fieldset and legend semantics.\n */\nexport function FormField(props: FormFieldProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'hint',\n 'error',\n 'controlId',\n 'group',\n 'children',\n ])\n const fieldId = createUniqueId()\n const labelId = `${fieldId}-label`\n const descriptionId = `${fieldId}-description`\n const errorId = `${fieldId}-error`\n const field = createFormFieldContext({\n controlId: local.controlId,\n defaultControlId: fieldId,\n labelId,\n descriptionId,\n errorId,\n hint: () => local.hint,\n error: () => local.error,\n group: () => local.group ?? false,\n })\n const help = () => (\n <>\n <Show when={local.hint}>\n <p id={descriptionId} class=\"text-muted-foreground text-sm\">\n {local.hint}\n </p>\n </Show>\n <Show when={local.error}>\n <p id={errorId} role=\"alert\" class=\"text-foreground text-sm\">\n {local.error}\n </p>\n </Show>\n </>\n )\n\n return (\n <FormFieldContext.Provider value={field}>\n <div class={cn('flex flex-col gap-1.5', local.class)} {...rest}>\n {local.group ? (\n <FieldSet\n class=\"flex flex-col gap-1.5\"\n aria-describedby={field.describedBy()}\n aria-invalid={field.invalid() || undefined}\n >\n <FieldLegend id={labelId} variant=\"label\">\n {local.label}\n </FieldLegend>\n {local.children}\n {help()}\n </FieldSet>\n ) : (\n <>\n <Label id={labelId} for={field.controlId()}>\n {local.label}\n </Label>\n {local.children}\n {help()}\n </>\n )}\n </div>\n </FormFieldContext.Provider>\n )\n}\n\nexport function FieldLabel(props: ComponentProps<typeof KobalteTextField.Label>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTextField.Label class={cn('text-sm leading-none font-medium', local.class)} {...rest} />\n )\n}\n\nexport function FieldDescription(props: ComponentProps<typeof KobalteTextField.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTextField.Description\n class={cn('text-muted-foreground text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport function FieldError(props: ComponentProps<typeof KobalteTextField.ErrorMessage>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTextField.ErrorMessage class={cn('text-foreground text-sm', local.class)} {...rest} />\n )\n}\n\nexport function FieldInput(props: ComponentProps<typeof KobalteTextField.Input>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <KobalteTextField.Input\n class={cn(\n 'h-control-md w-full min-w-0 rounded-md border border-input bg-transparent px-control-md py-1 text-sm',\n 'transition-[color,box-shadow,border-color] ease-out outline-none',\n 'placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function FieldTextArea(props: ComponentProps<typeof KobalteTextField.TextArea>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <KobalteTextField.TextArea\n class={cn(\n 'flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-control-md py-2 text-sm',\n 'transition-[color,box-shadow,border-color] ease-out outline-none resize-y',\n 'placeholder:text-muted-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/**\n * A labelled group of fields with a single legend, for a real `<fieldset>`.\n * Grouping is what lets a screen reader announce \"Shipping address, group\"\n * before reading the four fields inside it.\n */\nexport function FieldSet(props: ComponentProps<'fieldset'>) {\n const [local, rest] = splitProps(props, ['class'])\n return <fieldset class={cn('flex flex-col gap-4', local.class)} {...rest} />\n}\n\n/** A visual stack for related controls that does not imply fieldset semantics. */\nexport function FieldGroup(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return <div data-slot=\"field-group\" class={cn('flex flex-col gap-4', local.class)} {...rest} />\n}\n\nexport function FieldLegend(props: ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n const [local, rest] = splitProps(props, ['class', 'variant'])\n return (\n <legend\n class={cn(\n 'mb-1',\n local.variant === 'label' ? 'text-sm font-medium' : headingVariants({ size: 'card' }),\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A horizontal rule with a word in it, for \"or continue with\" separators. */\nexport function FieldSeparator(props: {\n class?: string\n children?: ComponentProps<'span'>['children']\n}) {\n const [local, rest] = splitProps(props, ['class', 'children'])\n\n return (\n <div class={cn('relative flex items-center gap-3 py-1', local.class)} {...rest}>\n <span class=\"bg-border h-px flex-1\" />\n <Show when={local.children}>\n <span class=\"text-muted-foreground text-2xs tracking-wide uppercase\">{local.children}</span>\n </Show>\n <span class=\"bg-border h-px flex-1\" />\n </div>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"field.js","names":["TextField","KobalteTextField","ComponentProps","JSX","createUniqueId","Show","splitProps","Label","createFormFieldContext","FormFieldContext","cn","headingVariants","Field","props","local","rest","_$createComponent","_$mergeProps","class","FormFieldProps","Omit","label","hint","error","controlId","group","children","Element","FormField","fieldId","labelId","descriptionId","errorId","field","defaultControlId","help","when","_el$","_tmpl$","_$setAttribute","_$insert","_el$2","_tmpl$2","Provider","value","_el$3","_tmpl$3","_$spread","_c$","_$memo","FieldSet","aria-describedby","describedBy","aria-invalid","invalid","undefined","FieldLegend","id","variant","for","FieldLabel","FieldDescription","Description","FieldError","ErrorMessage","FieldInput","Input","FieldTextArea","TextArea","_el$4","_tmpl$4","FieldGroupProps","columns","FieldGroup","_el$5","_tmpl$5","_el$6","_tmpl$6","size","FieldSeparator","_el$7","_tmpl$8","_el$8","firstChild","_el$0","nextSibling","_el$9","_tmpl$7","_$createComponent","KobalteTextField","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/field/field.tsx"],"sourcesContent":["import { TextField as KobalteTextField } from '@kobalte/core/text-field'\nimport type { ComponentProps, JSX } from 'solid-js'\nimport { createUniqueId, Show, splitProps } from 'solid-js'\nimport { Label } from '../label/label'\nimport { createFormFieldContext, FormFieldContext } from '#lib/form-field'\nimport { cn } from '#lib/utils'\nimport { headingVariants } from '../typography'\n\n/**\n * Field.\n *\n * The wrapper that makes a form control describable and validatable: a label,\n * a description, an error message, and the ARIA relationships between them.\n *\n * This Kobalte TextField composition is for its own `FieldLabel`, `FieldInput`\n * and `FieldTextArea` parts. Use `FormField` to wire the standalone shared\n * controls, including checkboxes, switches and comboboxes.\n *\n * It is built on Kobalte's TextField specifically so `aria-describedby`,\n * `aria-invalid` and `aria-errormessage` are wired by construction. Those three\n * attributes are the difference between \"this field is required and empty\" and\n * a red border that only a sighted user can perceive — and they are also the\n * first thing a hand-rolled form drops.\n *\n * `Field` owns the description and the error slot, so its controls line up and\n * its messages land in the same place regardless of which TextField part is used.\n */\nexport function Field(props: ComponentProps<typeof KobalteTextField>) {\n const [local, rest] = splitProps(props, ['class'])\n return <KobalteTextField class={cn('flex flex-col gap-1.5', local.class)} {...rest} />\n}\n\nexport type FormFieldProps = Omit<ComponentProps<'div'>, 'children' | 'ref'> & {\n label: string\n hint?: string\n error?: string\n controlId?: string\n group?: boolean\n children: JSX.Element\n}\n\n/**\n * FormField.\n *\n * A shared label, help and validation wrapper for any one shared control. Its\n * context is consumed by Input, Textarea, NativeSelect, Checkbox, Switch,\n * RadioGroup and ComboboxInput, so the actual focusable element receives the\n * generated ID and description relationships. Set `group` when the label names\n * a set of controls; the wrapper then uses fieldset and legend semantics.\n */\nexport function FormField(props: FormFieldProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'hint',\n 'error',\n 'controlId',\n 'group',\n 'children',\n ])\n const fieldId = createUniqueId()\n const labelId = `${fieldId}-label`\n const descriptionId = `${fieldId}-description`\n const errorId = `${fieldId}-error`\n const field = createFormFieldContext({\n controlId: local.controlId,\n defaultControlId: fieldId,\n labelId,\n descriptionId,\n errorId,\n hint: () => local.hint,\n error: () => local.error,\n group: () => local.group ?? false,\n })\n const help = () => (\n <>\n <Show when={local.hint}>\n <p id={descriptionId} class=\"text-muted-foreground text-sm\">\n {local.hint}\n </p>\n </Show>\n <Show when={local.error}>\n <p id={errorId} role=\"alert\" class=\"text-foreground text-sm\">\n {local.error}\n </p>\n </Show>\n </>\n )\n\n return (\n <FormFieldContext.Provider value={field}>\n <div class={cn('flex flex-col gap-1.5', local.class)} {...rest}>\n {local.group ? (\n <FieldSet\n class=\"flex flex-col gap-1.5\"\n aria-describedby={field.describedBy()}\n aria-invalid={field.invalid() || undefined}\n >\n <FieldLegend id={labelId} variant=\"label\">\n {local.label}\n </FieldLegend>\n {local.children}\n {help()}\n </FieldSet>\n ) : (\n <>\n <Label id={labelId} for={field.controlId()}>\n {local.label}\n </Label>\n {local.children}\n {help()}\n </>\n )}\n </div>\n </FormFieldContext.Provider>\n )\n}\n\nexport function FieldLabel(props: ComponentProps<typeof KobalteTextField.Label>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTextField.Label class={cn('text-sm leading-none font-medium', local.class)} {...rest} />\n )\n}\n\nexport function FieldDescription(props: ComponentProps<typeof KobalteTextField.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTextField.Description\n class={cn('text-muted-foreground text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport function FieldError(props: ComponentProps<typeof KobalteTextField.ErrorMessage>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteTextField.ErrorMessage class={cn('text-foreground text-sm', local.class)} {...rest} />\n )\n}\n\nexport function FieldInput(props: ComponentProps<typeof KobalteTextField.Input>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <KobalteTextField.Input\n class={cn(\n 'h-control-md w-full min-w-0 rounded-md border border-input bg-transparent px-control-md py-1 text-sm',\n 'transition-[color,box-shadow,border-color] ease-out outline-none',\n 'placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function FieldTextArea(props: ComponentProps<typeof KobalteTextField.TextArea>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <KobalteTextField.TextArea\n class={cn(\n 'flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-control-md py-2 text-sm',\n 'transition-[color,box-shadow,border-color] ease-out outline-none resize-y',\n 'placeholder:text-muted-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/**\n * A labelled group of fields with a single legend, for a real `<fieldset>`.\n * Grouping is what lets a screen reader announce \"Shipping address, group\"\n * before reading the four fields inside it.\n */\nexport function FieldSet(props: ComponentProps<'fieldset'>) {\n const [local, rest] = splitProps(props, ['class'])\n return <fieldset class={cn('flex flex-col gap-4', local.class)} {...rest} />\n}\n\nexport type FieldGroupProps = ComponentProps<'div'> & {\n /**\n * `2` lays the fields out in two columns from the `sm` breakpoint up — a\n * short form of paired values (host and port, a name and a model). A field\n * that needs the full width says `class=\"col-span-full\"`. Below `sm` it is\n * one column again, because two inputs side by side on a phone are each too\n * narrow to read.\n */\n columns?: 1 | 2\n}\n\n/** A visual stack for related controls that does not imply fieldset semantics. */\nexport function FieldGroup(props: FieldGroupProps) {\n const [local, rest] = splitProps(props, ['class', 'columns'])\n return (\n <div\n data-slot=\"field-group\"\n class={cn(\n local.columns === 2 ? 'grid gap-4 sm:grid-cols-2' : 'flex flex-col gap-4',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function FieldLegend(props: ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n const [local, rest] = splitProps(props, ['class', 'variant'])\n return (\n <legend\n class={cn(\n 'mb-1',\n local.variant === 'label' ? 'text-sm font-medium' : headingVariants({ size: 'card' }),\n local.class\n )}\n {...rest}\n />\n )\n}\n\n/** A horizontal rule with a word in it, for \"or continue with\" separators. */\nexport function FieldSeparator(props: {\n class?: string\n children?: ComponentProps<'span'>['children']\n}) {\n const [local, rest] = splitProps(props, ['class', 'children'])\n\n return (\n <div class={cn('relative flex items-center gap-3 py-1', local.class)} {...rest}>\n <span class=\"bg-border h-px flex-1\" />\n <Show when={local.children}>\n <span class=\"text-muted-foreground text-2xs tracking-wide uppercase\">{local.children}</span>\n </Show>\n <span class=\"bg-border h-px flex-1\" />\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Field, FormField, FieldDescription, FieldError, FieldGroup, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, type FormFieldProps, } from './field';
|
|
1
|
+
export { Field, FormField, FieldDescription, FieldError, FieldGroup, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, type FieldGroupProps, type FormFieldProps, } from './field';
|
|
2
2
|
export { NumberField } from './number-field';
|
|
3
3
|
export type { NumberFieldProps } from './number-field';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/field/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,cAAc,GACpB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/field/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, type InputGroupAddonProps, } from './input-group';
|
|
1
|
+
export { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, type InputGroupAddonProps, type InputGroupProps, } from './input-group';
|
|
2
2
|
export { SecretInputGroup, type SecretInputGroupProps } from './secret-input-group';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -11,8 +11,15 @@ import type { ComponentProps, JSX } from 'solid-js';
|
|
|
11
11
|
* The focus ring therefore lives on the group and follows `focus-within`. A
|
|
12
12
|
* group containing several focusable things still reads as focused once, which
|
|
13
13
|
* is the correct affordance: the user is somewhere inside it.
|
|
14
|
+
*
|
|
15
|
+
* `size` is the control rung, matching `Input`: `sm` for a toolbar search beside
|
|
16
|
+
* `icon-sm` actions, `md` (the default) everywhere else. The group's input and
|
|
17
|
+
* text follow it.
|
|
14
18
|
*/
|
|
15
|
-
export
|
|
19
|
+
export type InputGroupProps = ComponentProps<'div'> & {
|
|
20
|
+
size?: 'sm' | 'md' | 'lg';
|
|
21
|
+
};
|
|
22
|
+
export declare function InputGroup(props: InputGroupProps): JSX.Element;
|
|
16
23
|
export declare function InputGroupInput(props: ComponentProps<'input'>): JSX.Element;
|
|
17
24
|
export type InputGroupAddonProps = ComponentProps<'span'> & {
|
|
18
25
|
/** Which edge the adornment sits on; also sets the pointer-events rule. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input-group/input-group.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAKnD
|
|
1
|
+
{"version":3,"file":"input-group.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input-group/input-group.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAKnD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG;IACpD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B,CAAA;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,eAuBhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,eAqC7D;AAED,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG;IAC1D,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;CACxB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,eAkB1D;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,eAoB/D;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,eAWxF"}
|
|
@@ -8,26 +8,22 @@ var _tmpl$2 = /*#__PURE__*/ template(`<input data-slot=input-group-input>`);
|
|
|
8
8
|
var _tmpl$3 = /*#__PURE__*/ template(`<span data-slot=input-group-addon>`);
|
|
9
9
|
var _tmpl$4 = /*#__PURE__*/ template(`<button type=button data-slot=input-group-button>`);
|
|
10
10
|
var _tmpl$5 = /*#__PURE__*/ template(`<span>`);
|
|
11
|
-
/**
|
|
12
|
-
* InputGroup.
|
|
13
|
-
*
|
|
14
|
-
* A field with attached chrome: a leading icon, a unit, a trailing button, a
|
|
15
|
-
* clear affordance. The point of the component is that the adornments and the
|
|
16
|
-
* input share *one* border and *one* focus ring, so the group reads as a single
|
|
17
|
-
* control. Two separate elements side by side always drift — the ring appears
|
|
18
|
-
* on the wrong box, or the border doubles where they meet.
|
|
19
|
-
*
|
|
20
|
-
* The focus ring therefore lives on the group and follows `focus-within`. A
|
|
21
|
-
* group containing several focusable things still reads as focused once, which
|
|
22
|
-
* is the correct affordance: the user is somewhere inside it.
|
|
23
|
-
*/
|
|
24
11
|
function InputGroup(props) {
|
|
25
|
-
const [local, rest] = splitProps(props, ["class"]);
|
|
12
|
+
const [local, rest] = splitProps(props, ["class", "size"]);
|
|
26
13
|
return (() => {
|
|
27
14
|
var _el$ = _tmpl$();
|
|
28
|
-
spread(_el$, mergeProps({
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
spread(_el$, mergeProps({
|
|
16
|
+
get ["data-size"]() {
|
|
17
|
+
return local.size;
|
|
18
|
+
},
|
|
19
|
+
get ["class"]() {
|
|
20
|
+
return cn("group/input-group border-input flex w-full min-w-0 items-center gap-1.5 rounded-md border bg-transparent", {
|
|
21
|
+
"h-control-sm px-control-xs": local.size === "sm",
|
|
22
|
+
"h-control-md px-control-sm": local.size === "md" || local.size === void 0,
|
|
23
|
+
"h-control-lg px-control-md": local.size === "lg"
|
|
24
|
+
}, "transition-[color,box-shadow,border-color] ease-out", "focus-within:border-ring focus-within:ring-3 focus-within:ring-primary-subtle", "has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:ring-3 has-[[aria-invalid=true]]:ring-destructive-subtle", "has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50", local.class);
|
|
25
|
+
}
|
|
26
|
+
}, rest), false, false);
|
|
31
27
|
return _el$;
|
|
32
28
|
})();
|
|
33
29
|
}
|
|
@@ -71,7 +67,7 @@ function InputGroupInput(props) {
|
|
|
71
67
|
return field?.["aria-errormessage"] ?? local["aria-errormessage"];
|
|
72
68
|
},
|
|
73
69
|
get ["class"]() {
|
|
74
|
-
return cn("h-full min-w-0 flex-1 bg-transparent text-sm outline-none", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed", local.class);
|
|
70
|
+
return cn("h-full min-w-0 flex-1 bg-transparent text-sm outline-none group-data-[size=sm]/input-group:text-xs", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed", local.class);
|
|
75
71
|
}
|
|
76
72
|
}, rest), false, false);
|
|
77
73
|
return _el$2;
|
|
@@ -92,7 +88,7 @@ function InputGroupAddon(props) {
|
|
|
92
88
|
return (() => {
|
|
93
89
|
var _el$3 = _tmpl$3();
|
|
94
90
|
spread(_el$3, mergeProps({ get ["class"]() {
|
|
95
|
-
return cn("text-muted-foreground flex shrink-0 items-center gap-1.5 text-sm select-none", "[&_svg]:pointer-events-none [&_svg]:size-4", {
|
|
91
|
+
return cn("text-muted-foreground flex shrink-0 items-center gap-1.5 text-sm select-none", "[&_svg]:pointer-events-none [&_svg]:size-4", "group-data-[size=sm]/input-group:text-xs group-data-[size=sm]/input-group:[&_svg]:size-3.5", {
|
|
96
92
|
"order-first": local.align !== "end",
|
|
97
93
|
"order-last": local.align === "end"
|
|
98
94
|
}, local.class);
|
|
@@ -119,7 +115,7 @@ function InputGroupText(props) {
|
|
|
119
115
|
return (() => {
|
|
120
116
|
var _el$5 = _tmpl$5();
|
|
121
117
|
spread(_el$5, mergeProps({ get ["class"]() {
|
|
122
|
-
return cn("text-muted-foreground text-sm", local.class);
|
|
118
|
+
return cn("text-muted-foreground text-sm group-data-[size=sm]/input-group:text-xs", local.class);
|
|
123
119
|
} }, rest), false, false);
|
|
124
120
|
return _el$5;
|
|
125
121
|
})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-group.js","names":["ComponentProps","JSX","splitProps","useFormFieldControl","cn","InputGroup","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","class","InputGroupInput","field","id","_el$2","_tmpl$2","aria-label","aria-labelledby","aria-describedby","aria-invalid","aria-errormessage","InputGroupAddonProps","align","InputGroupAddon","_el$3","_tmpl$3","_$insert","children","InputGroupButton","_el$4","_tmpl$4","InputGroupText","Element","_el$5","_tmpl$5","_$mergeProps"],"sources":["../../../../src/components/ui/input-group/input-group.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { useFormFieldControl } from '#lib/form-field'\nimport { cn } from '#lib/utils'\n\n/**\n * InputGroup.\n *\n * A field with attached chrome: a leading icon, a unit, a trailing button, a\n * clear affordance. The point of the component is that the adornments and the\n * input share *one* border and *one* focus ring, so the group reads as a single\n * control. Two separate elements side by side always drift — the ring appears\n * on the wrong box, or the border doubles where they meet.\n *\n * The focus ring therefore lives on the group and follows `focus-within`. A\n * group containing several focusable things still reads as focused once, which\n * is the correct affordance: the user is somewhere inside it.\n */\nexport
|
|
1
|
+
{"version":3,"file":"input-group.js","names":["ComponentProps","JSX","splitProps","useFormFieldControl","cn","InputGroupProps","size","InputGroup","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","data-size","class","undefined","InputGroupInput","field","id","_el$2","_tmpl$2","aria-label","aria-labelledby","aria-describedby","aria-invalid","aria-errormessage","InputGroupAddonProps","align","InputGroupAddon","_el$3","_tmpl$3","_$insert","children","InputGroupButton","_el$4","_tmpl$4","InputGroupText","Element","_el$5","_tmpl$5","_$mergeProps"],"sources":["../../../../src/components/ui/input-group/input-group.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { useFormFieldControl } from '#lib/form-field'\nimport { cn } from '#lib/utils'\n\n/**\n * InputGroup.\n *\n * A field with attached chrome: a leading icon, a unit, a trailing button, a\n * clear affordance. The point of the component is that the adornments and the\n * input share *one* border and *one* focus ring, so the group reads as a single\n * control. Two separate elements side by side always drift — the ring appears\n * on the wrong box, or the border doubles where they meet.\n *\n * The focus ring therefore lives on the group and follows `focus-within`. A\n * group containing several focusable things still reads as focused once, which\n * is the correct affordance: the user is somewhere inside it.\n *\n * `size` is the control rung, matching `Input`: `sm` for a toolbar search beside\n * `icon-sm` actions, `md` (the default) everywhere else. The group's input and\n * text follow it.\n */\nexport type InputGroupProps = ComponentProps<'div'> & {\n size?: 'sm' | 'md' | 'lg'\n}\n\nexport function InputGroup(props: InputGroupProps) {\n const [local, rest] = splitProps(props, ['class', 'size'])\n\n return (\n <div\n data-slot=\"input-group\"\n data-size={local.size}\n class={cn(\n 'group/input-group border-input flex w-full min-w-0 items-center gap-1.5 rounded-md border bg-transparent',\n {\n 'h-control-sm px-control-xs': local.size === 'sm',\n 'h-control-md px-control-sm': local.size === 'md' || local.size === undefined,\n 'h-control-lg px-control-md': local.size === 'lg',\n },\n 'transition-[color,box-shadow,border-color] ease-out',\n 'focus-within:border-ring focus-within:ring-3 focus-within:ring-primary-subtle',\n 'has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:ring-3 has-[[aria-invalid=true]]:ring-destructive-subtle',\n 'has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function InputGroupInput(props: ComponentProps<'input'>) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'id',\n 'aria-label',\n 'aria-labelledby',\n 'aria-describedby',\n 'aria-invalid',\n 'aria-errormessage',\n ])\n const field = useFormFieldControl('control', {\n id: local.id,\n 'aria-label': local['aria-label'],\n 'aria-labelledby': local['aria-labelledby'],\n 'aria-describedby': local['aria-describedby'],\n 'aria-invalid': local['aria-invalid'],\n 'aria-errormessage': local['aria-errormessage'],\n })\n\n return (\n <input\n data-slot=\"input-group-input\"\n id={field?.id ?? local.id}\n aria-label={local['aria-label']}\n aria-labelledby={field?.['aria-labelledby'] ?? local['aria-labelledby']}\n aria-describedby={field?.['aria-describedby'] ?? local['aria-describedby']}\n aria-invalid={field?.['aria-invalid'] ?? local['aria-invalid']}\n aria-errormessage={field?.['aria-errormessage'] ?? local['aria-errormessage']}\n class={cn(\n 'h-full min-w-0 flex-1 bg-transparent text-sm outline-none group-data-[size=sm]/input-group:text-xs',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport type InputGroupAddonProps = ComponentProps<'span'> & {\n /** Which edge the adornment sits on; also sets the pointer-events rule. */\n align?: 'start' | 'end'\n}\n\n/**\n * A non-interactive adornment. `pointer-events-none` by default, because an\n * adornment that swallows a click makes the whole control feel dead just to\n * the left of the caret — the most annoying possible bug. Pass `align=\"end\"`\n * and a real element when the adornment must be clickable.\n */\nexport function InputGroupAddon(props: InputGroupAddonProps) {\n const [local, rest] = splitProps(props, ['class', 'align', 'children'])\n\n return (\n <span\n data-slot=\"input-group-addon\"\n class={cn(\n 'text-muted-foreground flex shrink-0 items-center gap-1.5 text-sm select-none',\n '[&_svg]:pointer-events-none [&_svg]:size-4',\n 'group-data-[size=sm]/input-group:text-xs group-data-[size=sm]/input-group:[&_svg]:size-3.5',\n { 'order-first': local.align !== 'end', 'order-last': local.align === 'end' },\n local.class\n )}\n {...rest}\n >\n {local.children}\n </span>\n )\n}\n\n/** A clickable trailing button, sized to the group's height. */\nexport function InputGroupButton(props: ComponentProps<'button'>) {\n const [local, rest] = splitProps(props, ['class', 'children'])\n\n return (\n <button\n type=\"button\"\n data-slot=\"input-group-button\"\n class={cn(\n 'text-muted-foreground -me-1 flex size-6 shrink-0 items-center justify-center rounded-sm',\n 'transition-colors ease-out outline-none hover:bg-surface-hover hover:text-foreground',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'disabled:pointer-events-none disabled:opacity-50',\n '[&_svg]:size-3.5',\n local.class\n )}\n {...rest}\n >\n {local.children}\n </button>\n )\n}\n\n/** Text that reads as a value but is not an input, e.g. a unit or a suffix. */\nexport function InputGroupText(props: ComponentProps<'span'> & { children?: JSX.Element }) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <span\n class={cn(\n 'text-muted-foreground text-sm group-data-[size=sm]/input-group:text-xs',\n local.class\n )}\n {...rest}\n />\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { ComponentProps } from 'solid-js';
|
|
2
|
-
export type NativeSelectProps = ComponentProps<'select'> & {
|
|
2
|
+
export type NativeSelectProps = Omit<ComponentProps<'select'>, 'size'> & {
|
|
3
|
+
/**
|
|
4
|
+
* The control rung, matching `Input` and `SelectTrigger`: `sm` for a dense
|
|
5
|
+
* toolbar or pane filter, `md` (the default) everywhere else. This replaces the
|
|
6
|
+
* native `size` attribute, which turns a select into a list box — a different
|
|
7
|
+
* control that this styled single-line select is not.
|
|
8
|
+
*/
|
|
9
|
+
size?: 'sm' | 'md' | 'lg';
|
|
3
10
|
/** Render the choices from data instead of raw option children. */
|
|
4
11
|
options?: readonly NativeSelectOption[];
|
|
5
12
|
/** Initialize an uncontrolled selection after its native options mount. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-select.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/native-select/native-select.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAK9C,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG;
|
|
1
|
+
{"version":3,"file":"native-select.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/native-select/native-select.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAK9C,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,GAAG;IACvE;;;;;OAKG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,mEAAmE;IACnE,OAAO,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACvC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAA;CACjD,CAAA;AAkCD;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,kCAuFpD"}
|