@adea-ai/ui 0.94.0 → 0.95.1

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.
Files changed (84) hide show
  1. package/README.md +43 -1
  2. package/dist/NOTICE +10 -0
  3. package/dist/components/composites/action-button/action-button.d.ts.map +1 -1
  4. package/dist/components/composites/action-button/action-button.js +2 -0
  5. package/dist/components/composites/action-button/action-button.js.map +1 -1
  6. package/dist/components/composites/scene-controls/index.d.ts +3 -0
  7. package/dist/components/composites/scene-controls/index.d.ts.map +1 -0
  8. package/dist/components/composites/scene-controls/index.js +2 -0
  9. package/dist/components/composites/scene-controls/scene-controls.d.ts +41 -0
  10. package/dist/components/composites/scene-controls/scene-controls.d.ts.map +1 -0
  11. package/dist/components/composites/scene-controls/scene-controls.js +291 -0
  12. package/dist/components/composites/scene-controls/scene-controls.js.map +1 -0
  13. package/dist/components/ui/button/button.d.ts +2 -1
  14. package/dist/components/ui/button/button.d.ts.map +1 -1
  15. package/dist/components/ui/button/button.js +9 -3
  16. package/dist/components/ui/button/button.js.map +1 -1
  17. package/dist/components/ui/dialog/dialog.d.ts.map +1 -1
  18. package/dist/components/ui/dialog/dialog.js +5 -1
  19. package/dist/components/ui/dialog/dialog.js.map +1 -1
  20. package/dist/components/ui/modal-dialog/modal-dialog.d.ts +6 -0
  21. package/dist/components/ui/modal-dialog/modal-dialog.d.ts.map +1 -1
  22. package/dist/components/ui/modal-dialog/modal-dialog.js +4 -0
  23. package/dist/components/ui/modal-dialog/modal-dialog.js.map +1 -1
  24. package/dist/components/ui/sheet/sheet.d.ts +8 -1
  25. package/dist/components/ui/sheet/sheet.d.ts.map +1 -1
  26. package/dist/components/ui/sheet/sheet.js +43 -19
  27. package/dist/components/ui/sheet/sheet.js.map +1 -1
  28. package/dist/components/ui/toggle/toggle.d.ts +1 -1
  29. package/dist/components/ui/toggle/toggle.d.ts.map +1 -1
  30. package/dist/components/ui/toggle/toggle.js +3 -1
  31. package/dist/components/ui/toggle/toggle.js.map +1 -1
  32. package/dist/components/ui/toggle-group/toggle-group.d.ts.map +1 -1
  33. package/dist/components/ui/toggle-group/toggle-group.js +20 -7
  34. package/dist/components/ui/toggle-group/toggle-group.js.map +1 -1
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +2 -1
  38. package/dist/lib/tokens.d.ts.map +1 -1
  39. package/dist/lib/tokens.js +10 -0
  40. package/dist/lib/tokens.js.map +1 -1
  41. package/dist/lib/utils.d.ts.map +1 -1
  42. package/dist/lib/utils.js +2 -0
  43. package/dist/lib/utils.js.map +1 -1
  44. package/dist/lib/variants.d.ts +5 -2
  45. package/dist/lib/variants.d.ts.map +1 -1
  46. package/dist/lib/variants.js +7 -3
  47. package/dist/lib/variants.js.map +1 -1
  48. package/dist/lint/index.d.ts.map +1 -1
  49. package/dist/lint.js +2 -1
  50. package/dist/lint.js.map +1 -1
  51. package/dist/r/registry.json +24 -0
  52. package/dist/r/scene-controls.json +24 -0
  53. package/dist/r/src/components/composites/action-button/action-button.tsx +2 -0
  54. package/dist/r/src/components/composites/scene-controls/index.ts +7 -0
  55. package/dist/r/src/components/composites/scene-controls/scene-controls.tsx +282 -0
  56. package/dist/r/src/components/ui/button/button.tsx +20 -2
  57. package/dist/r/src/components/ui/dialog/dialog.tsx +6 -1
  58. package/dist/r/src/components/ui/modal-dialog/modal-dialog.tsx +20 -0
  59. package/dist/r/src/components/ui/sheet/sheet.tsx +37 -4
  60. package/dist/r/src/components/ui/toggle/toggle.tsx +2 -0
  61. package/dist/r/src/components/ui/toggle-group/toggle-group.tsx +18 -1
  62. package/dist/r/src/lib/tokens.ts +10 -0
  63. package/dist/r/src/lib/utils.ts +2 -0
  64. package/dist/r/src/lib/variants.ts +5 -2
  65. package/dist/r/src/styles/base.css +29 -9
  66. package/dist/r/src/styles/theme.css +8 -2
  67. package/package.json +2 -1
  68. package/registry.json +24 -0
  69. package/src/components/composites/action-button/action-button.tsx +2 -0
  70. package/src/components/composites/scene-controls/index.ts +7 -0
  71. package/src/components/composites/scene-controls/scene-controls.tsx +282 -0
  72. package/src/components/ui/button/button.tsx +20 -2
  73. package/src/components/ui/dialog/dialog.tsx +6 -1
  74. package/src/components/ui/modal-dialog/modal-dialog.tsx +20 -0
  75. package/src/components/ui/sheet/sheet.tsx +37 -4
  76. package/src/components/ui/toggle/toggle.tsx +2 -0
  77. package/src/components/ui/toggle-group/toggle-group.tsx +18 -1
  78. package/src/index.ts +1 -0
  79. package/src/lib/tokens.ts +10 -0
  80. package/src/lib/utils.ts +2 -0
  81. package/src/lib/variants.ts +5 -2
  82. package/src/lint/index.ts +1 -0
  83. package/src/styles/base.css +29 -9
  84. package/src/styles/theme.css +8 -2
package/README.md CHANGED
@@ -402,7 +402,8 @@ Square icon controls use the control-height tokens through the Tailwind `--size`
402
402
  mapping; `--spacing-control-*` remains the separate inline-padding ladder.
403
403
  Text controls, icon buttons and toggles share the same height in both densities.
404
404
  Dimensions remain rem-based and follow the consumer's root font size. The browser
405
- geometry lane checks all six rungs, heights and padding under both themes/densities.
405
+ geometry lane checks the standard density rungs, heights and padding under both
406
+ themes/densities; the `2xl` touch target remains 48px under compact density.
406
407
 
407
408
  `BusySendButton` translates KiroCrew's split fire/mode-picker composition. Pass
408
409
  controlled `mode`, `onModeChange` and `onFire`. `disabled` prevents firing while
@@ -413,6 +414,47 @@ when the host implements the described keyboard chord. The component adds no
413
414
  keyboard chord, preference storage, runtime command or queue. Persistence and
414
415
  same-session preference synchronization remain application-owned.
415
416
 
417
+ ## Scene controls
418
+
419
+ `SceneControls` composes movement, jump and optional zoom actions for a host
420
+ scene. `onMovementChange(direction, pressed)` and `onJumpChange(pressed)` report
421
+ held state from pointer or keyboard input; zoom callbacks fire once per
422
+ activation. The shared controls capture pointers and release held actions on
423
+ pointer end/cancel, lost capture, window blur and component cleanup. The host
424
+ maps these typed callbacks to its own camera or movement system; the component
425
+ does not synthesize keyboard events or access host globals. Each icon action
426
+ uses the shared tooltip and a `2xl` 48px target that stays that size under
427
+ compact density. Rounded movement and zoom group surfaces use the shared
428
+ scrim treatment, which follows the library's reduced-transparency and fallback
429
+ policy.
430
+
431
+ ```tsx
432
+ import { SceneControls } from '@adea-ai/ui/components/composites/scene-controls'
433
+
434
+ ;<SceneControls
435
+ onMovementChange={(direction, pressed) => setMovement(direction, pressed)}
436
+ onJumpChange={(pressed) => setJumping(pressed)}
437
+ onZoomIn={zoomIn}
438
+ onZoomOut={zoomOut}
439
+ />
440
+ ```
441
+
442
+ Labels default to English and can be supplied through `labels` for a host's
443
+ locale. Hold actions have separate accessible names and explanatory tooltip
444
+ strings so localization can describe the gesture without changing the action
445
+ name. `SceneControls` owns control arrangement and interaction lifecycle;
446
+ the host owns placement, persistence and scene behavior.
447
+
448
+ After building, `bun run check:packed-scene-controls` verifies the installed npm
449
+ archive under both compiled and Solid export conditions. It reuses the
450
+ SceneControls and ActionButton consumer fixtures to check held callback release,
451
+ localized labels, keyboard and pointer cleanup, and the opt-in touch target at
452
+ 320px and 200% text. It also checks packed type declarations, license/NOTICE,
453
+ native Node SSR, module separation, and the existing 40 KiB gzip / 32 KiB CSS
454
+ control budgets. The ActionButton fixture with menus and popovers uses the
455
+ existing 38 KiB gzip / 40 KiB CSS overlay budgets. These packed consumer checks
456
+ do not replace product-level native-device acceptance.
457
+
416
458
  Kobalte owns the menu and focus lifecycle. Its Tab prevention lacks row cycling,
417
459
  so a menu-scoped donor translation cycles enabled rows without a document listener.
418
460
  Stories cover before-typing, working,
package/dist/NOTICE CHANGED
@@ -451,6 +451,16 @@ excluded. Its distinct `/apps/library` core-app launchpad is also excluded:
451
451
  this selected unit is the external verified plugin marketplace adapter, while
452
452
  Adea's #757 App Library remains a separate core-view and rail-management flow.
453
453
 
454
+ ## Scene controls adapted from Adea
455
+
456
+ `packages/ui/src/components/composites/scene-controls/scene-controls.tsx` adapts
457
+ the d-pad, jump and zoom composition, rounded scrim grouping surfaces and held-input lifecycle from
458
+ `packages/ui/src/components/on-screen-controls.tsx` in the Adea application
459
+ repository (https://github.com/adea-ai/adea), licensed under Apache-2.0.
460
+ The grouping uses the shared `glass-scrim` policy and 48px button variant. The
461
+ component reports typed pressed/released callbacks; it does not copy the host's
462
+ synthetic keyboard events, scene placement or camera behavior.
463
+
454
464
  ## Windowed tree row composition translated from Terax
455
465
 
456
466
  `packages/ui/src/components/composites/tree/` translates the file-row hierarchy
@@ -1 +1 @@
1
- {"version":3,"file":"action-button.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/action-button/action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACR,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IACpF,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA+CD,wBAAgB,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAsG5F"}
1
+ {"version":3,"file":"action-button.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/action-button/action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACR,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IACpF,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA+CD,wBAAgB,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAwG5F"}
@@ -40,6 +40,7 @@ function ActionButton(props) {
40
40
  "as",
41
41
  "variant",
42
42
  "size",
43
+ "touchTarget",
43
44
  "class",
44
45
  "children",
45
46
  "disabled",
@@ -61,6 +62,7 @@ function ActionButton(props) {
61
62
  ...rest,
62
63
  variant: local.variant,
63
64
  size: local.size,
65
+ touchTarget: local.touchTarget,
64
66
  class: [local.class, local.tooltip && disabled() && "aria-disabled:pointer-events-auto"].filter(Boolean).join(" "),
65
67
  disabled: disabled() && !local.tooltip,
66
68
  "aria-disabled": disabled() ? true : rest["aria-disabled"],
@@ -1 +1 @@
1
- {"version":3,"file":"action-button.js","names":["Show","createSignal","splitProps","ComponentProps","JSX","ValidComponent","Button","ButtonProps","Spinner","Tooltip","TooltipContent","TooltipTrigger","ActionButtonProps","T","tooltip","tooltipSide","busy","busyLabel","invokeHandler","handler","event","Event","Array","isArray","callback","data","chainedHandler","before","guardedClick","disabled","onActivate","MouseEvent","preventDefault","stopImmediatePropagation","ButtonTargetProps","Omit","actionAs","ButtonTarget","props","local","rest","PolymorphicButton","targetProps","Element","_$createComponent","_$mergeProps","as","ActionButton","busyStatus","tooltipOpen","setTooltipOpen","tooltipSuppression","setTooltipSuppression","onClickCapture","buttonProps","PolymorphicButtonTarget","variant","size","class","filter","Boolean","join","tabIndex","undefined","role","href","onClick","detail","onPointerLeave","onBlur","Record","contents","when","children","label","_$memo","fallback","open","onOpenChange","side","_el$","_tmpl$","_$insert","_$createComponent","PolymorphicButton","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/action-button/action-button.tsx"],"sourcesContent":["import {\n Show,\n createSignal,\n splitProps,\n type ComponentProps,\n type JSX,\n type ValidComponent,\n} from 'solid-js'\nimport { Button, type ButtonProps } from '../../ui/button'\nimport { Spinner } from '../../ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\n/**\n * ActionButton.\n *\n * A Button with optional explanatory tooltip and busy feedback. Use it for a\n * simple action that needs these states; actions with product-specific rules\n * should compose Button directly.\n *\n * The tooltip trigger renders the polymorphic Button itself. A disabled native\n * control cannot receive pointer or keyboard events. When a tooltip is set,\n * disabled actions therefore use focusable `aria-disabled` semantics and guard\n * activation; without a tooltip, native buttons retain native disabling.\n * Custom polymorphic components must forward aria, event, and href props for\n * these guarantees to apply.\n */\nexport type ActionButtonProps<T extends ValidComponent = 'button'> = ButtonProps<T> & {\n /** A short explanation, also shown on keyboard focus. The Button still needs its own name. */\n tooltip?: string\n tooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n /** Disables the action and announces the busy label through a polite status region. */\n busy?: boolean\n /** The activity announced while busy. The Button's accessible name stays unchanged. */\n busyLabel?: string\n}\n\nfunction invokeHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\nfunction chainedHandler(handler: unknown, before: (event: Event) => void) {\n return (event: Event) => {\n before(event)\n invokeHandler(handler, event)\n }\n}\n\nfunction guardedClick(\n handler: unknown,\n disabled: () => boolean,\n onActivate: (event: MouseEvent) => void = () => {}\n) {\n return (event: MouseEvent) => {\n if (disabled()) {\n event.preventDefault()\n event.stopImmediatePropagation()\n return\n }\n\n onActivate(event)\n invokeHandler(handler, event)\n }\n}\n\ntype ButtonTargetProps<T extends ValidComponent = 'button'> = Omit<ButtonProps<T>, 'as'> & {\n actionAs?: T\n}\n\n/** Adapter keeps TooltipTrigger's `as` separate from Button's polymorphic `as`. */\nfunction ButtonTarget<T extends ValidComponent = 'button'>(props: ButtonTargetProps<T>) {\n const [local, rest] = splitProps(props as ButtonTargetProps, ['actionAs'])\n const PolymorphicButton = Button as (targetProps: ButtonProps<T>) => JSX.Element\n return <PolymorphicButton as={(local.actionAs ?? 'button') as T} {...(rest as ButtonProps<T>)} />\n}\n\nexport function ActionButton<T extends ValidComponent = 'button'>(props: ActionButtonProps<T>) {\n const [local, rest] = splitProps(props as ActionButtonProps, [\n 'as',\n 'variant',\n 'size',\n 'class',\n 'children',\n 'disabled',\n 'aria-busy',\n 'tooltip',\n 'tooltipSide',\n 'busy',\n 'busyLabel',\n ])\n const busy = () => local.busy ?? false\n const disabled = () => busy() || !!local.disabled\n const busyStatus = () => local.busyLabel ?? 'Working'\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n const [tooltipSuppression, setTooltipSuppression] = createSignal<'pointer' | 'focus' | null>(null)\n const onClickCapture = (rest as { onClickCapture?: unknown }).onClickCapture\n const PolymorphicButton = Button as (buttonProps: ButtonProps<T>) => JSX.Element\n const PolymorphicButtonTarget = ButtonTarget as (targetProps: ButtonTargetProps<T>) => JSX.Element\n\n const buttonProps = () => ({\n ...rest,\n variant: local.variant,\n size: local.size,\n class: [local.class, local.tooltip && disabled() && 'aria-disabled:pointer-events-auto']\n .filter(Boolean)\n .join(' '),\n disabled: disabled() && !local.tooltip,\n 'aria-disabled': disabled() ? true : rest['aria-disabled'],\n // Make tooltip-bearing native controls explicit tab stops in WebKit configurations that\n // otherwise skip implicit button stops. A caller's tabIndex remains authoritative.\n tabIndex:\n rest.tabIndex ??\n (local.as === 'a' && disabled() ? (local.tooltip ? 0 : -1) : local.tooltip ? 0 : undefined),\n role: local.as === 'a' && disabled() ? 'link' : rest.role,\n href: local.as === 'a' && disabled() ? undefined : (rest as { href?: string }).href,\n 'aria-busy': busy() || local['aria-busy'],\n onClick: guardedClick(rest.onClick, disabled, (event) => {\n if (!local.tooltip) return\n setTooltipSuppression(event.detail > 0 ? 'pointer' : 'focus')\n setTooltipOpen(false)\n }),\n onPointerLeave: chainedHandler(rest.onPointerLeave, () => {\n if (tooltipSuppression() === 'pointer') setTooltipSuppression(null)\n }),\n onBlur: chainedHandler(rest.onBlur, () => {\n if (tooltipSuppression() === 'focus') setTooltipSuppression(null)\n }),\n onClickCapture: onClickCapture ? guardedClick(onClickCapture, disabled) : undefined,\n 'on:click': guardedClick((rest as Record<string, unknown>)['on:click'], disabled),\n 'oncapture:click': guardedClick((rest as Record<string, unknown>)['oncapture:click'], disabled),\n })\n\n const contents = () => (\n <>\n <Show when={busy()}>\n <Spinner size=\"sm\" label={false} aria-hidden=\"true\" data-icon=\"inline-start\" />\n </Show>\n {local.children}\n </>\n )\n\n return (\n <>\n <Show\n when={local.tooltip}\n fallback={\n <PolymorphicButton\n as={(local.as ?? 'button') as T}\n {...(buttonProps() as unknown as ButtonProps<T>)}\n >\n {contents()}\n </PolymorphicButton>\n }\n >\n <Tooltip\n open={tooltipOpen()}\n onOpenChange={(open) => {\n if (open && tooltipSuppression()) return\n setTooltipOpen(open)\n }}\n >\n <TooltipTrigger\n as={PolymorphicButtonTarget}\n {...(buttonProps() as unknown as ComponentProps<typeof PolymorphicButtonTarget>)}\n actionAs={(local.as ?? 'button') as T}\n >\n {contents()}\n </TooltipTrigger>\n <TooltipContent side={local.tooltipSide}>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n <Show when={busy()}>\n <span role=\"status\" aria-live=\"polite\" class=\"visually-hidden\">\n {busyStatus()}\n </span>\n </Show>\n </>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"action-button.js","names":["Show","createSignal","splitProps","ComponentProps","JSX","ValidComponent","Button","ButtonProps","Spinner","Tooltip","TooltipContent","TooltipTrigger","ActionButtonProps","T","tooltip","tooltipSide","busy","busyLabel","invokeHandler","handler","event","Event","Array","isArray","callback","data","chainedHandler","before","guardedClick","disabled","onActivate","MouseEvent","preventDefault","stopImmediatePropagation","ButtonTargetProps","Omit","actionAs","ButtonTarget","props","local","rest","PolymorphicButton","targetProps","Element","_$createComponent","_$mergeProps","as","ActionButton","busyStatus","tooltipOpen","setTooltipOpen","tooltipSuppression","setTooltipSuppression","onClickCapture","buttonProps","PolymorphicButtonTarget","variant","size","touchTarget","class","filter","Boolean","join","tabIndex","undefined","role","href","onClick","detail","onPointerLeave","onBlur","Record","contents","when","children","label","_$memo","fallback","open","onOpenChange","side","_el$","_tmpl$","_$insert","_$createComponent","PolymorphicButton","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/action-button/action-button.tsx"],"sourcesContent":["import {\n Show,\n createSignal,\n splitProps,\n type ComponentProps,\n type JSX,\n type ValidComponent,\n} from 'solid-js'\nimport { Button, type ButtonProps } from '../../ui/button'\nimport { Spinner } from '../../ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\n/**\n * ActionButton.\n *\n * A Button with optional explanatory tooltip and busy feedback. Use it for a\n * simple action that needs these states; actions with product-specific rules\n * should compose Button directly.\n *\n * The tooltip trigger renders the polymorphic Button itself. A disabled native\n * control cannot receive pointer or keyboard events. When a tooltip is set,\n * disabled actions therefore use focusable `aria-disabled` semantics and guard\n * activation; without a tooltip, native buttons retain native disabling.\n * Custom polymorphic components must forward aria, event, and href props for\n * these guarantees to apply.\n */\nexport type ActionButtonProps<T extends ValidComponent = 'button'> = ButtonProps<T> & {\n /** A short explanation, also shown on keyboard focus. The Button still needs its own name. */\n tooltip?: string\n tooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n /** Disables the action and announces the busy label through a polite status region. */\n busy?: boolean\n /** The activity announced while busy. The Button's accessible name stays unchanged. */\n busyLabel?: string\n}\n\nfunction invokeHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\nfunction chainedHandler(handler: unknown, before: (event: Event) => void) {\n return (event: Event) => {\n before(event)\n invokeHandler(handler, event)\n }\n}\n\nfunction guardedClick(\n handler: unknown,\n disabled: () => boolean,\n onActivate: (event: MouseEvent) => void = () => {}\n) {\n return (event: MouseEvent) => {\n if (disabled()) {\n event.preventDefault()\n event.stopImmediatePropagation()\n return\n }\n\n onActivate(event)\n invokeHandler(handler, event)\n }\n}\n\ntype ButtonTargetProps<T extends ValidComponent = 'button'> = Omit<ButtonProps<T>, 'as'> & {\n actionAs?: T\n}\n\n/** Adapter keeps TooltipTrigger's `as` separate from Button's polymorphic `as`. */\nfunction ButtonTarget<T extends ValidComponent = 'button'>(props: ButtonTargetProps<T>) {\n const [local, rest] = splitProps(props as ButtonTargetProps, ['actionAs'])\n const PolymorphicButton = Button as (targetProps: ButtonProps<T>) => JSX.Element\n return <PolymorphicButton as={(local.actionAs ?? 'button') as T} {...(rest as ButtonProps<T>)} />\n}\n\nexport function ActionButton<T extends ValidComponent = 'button'>(props: ActionButtonProps<T>) {\n const [local, rest] = splitProps(props as ActionButtonProps, [\n 'as',\n 'variant',\n 'size',\n 'touchTarget',\n 'class',\n 'children',\n 'disabled',\n 'aria-busy',\n 'tooltip',\n 'tooltipSide',\n 'busy',\n 'busyLabel',\n ])\n const busy = () => local.busy ?? false\n const disabled = () => busy() || !!local.disabled\n const busyStatus = () => local.busyLabel ?? 'Working'\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n const [tooltipSuppression, setTooltipSuppression] = createSignal<'pointer' | 'focus' | null>(null)\n const onClickCapture = (rest as { onClickCapture?: unknown }).onClickCapture\n const PolymorphicButton = Button as (buttonProps: ButtonProps<T>) => JSX.Element\n const PolymorphicButtonTarget = ButtonTarget as (targetProps: ButtonTargetProps<T>) => JSX.Element\n\n const buttonProps = () => ({\n ...rest,\n variant: local.variant,\n size: local.size,\n touchTarget: local.touchTarget,\n class: [local.class, local.tooltip && disabled() && 'aria-disabled:pointer-events-auto']\n .filter(Boolean)\n .join(' '),\n disabled: disabled() && !local.tooltip,\n 'aria-disabled': disabled() ? true : rest['aria-disabled'],\n // Make tooltip-bearing native controls explicit tab stops in WebKit configurations that\n // otherwise skip implicit button stops. A caller's tabIndex remains authoritative.\n tabIndex:\n rest.tabIndex ??\n (local.as === 'a' && disabled() ? (local.tooltip ? 0 : -1) : local.tooltip ? 0 : undefined),\n role: local.as === 'a' && disabled() ? 'link' : rest.role,\n href: local.as === 'a' && disabled() ? undefined : (rest as { href?: string }).href,\n 'aria-busy': busy() || local['aria-busy'],\n onClick: guardedClick(rest.onClick, disabled, (event) => {\n if (!local.tooltip) return\n setTooltipSuppression(event.detail > 0 ? 'pointer' : 'focus')\n setTooltipOpen(false)\n }),\n onPointerLeave: chainedHandler(rest.onPointerLeave, () => {\n if (tooltipSuppression() === 'pointer') setTooltipSuppression(null)\n }),\n onBlur: chainedHandler(rest.onBlur, () => {\n if (tooltipSuppression() === 'focus') setTooltipSuppression(null)\n }),\n onClickCapture: onClickCapture ? guardedClick(onClickCapture, disabled) : undefined,\n 'on:click': guardedClick((rest as Record<string, unknown>)['on:click'], disabled),\n 'oncapture:click': guardedClick((rest as Record<string, unknown>)['oncapture:click'], disabled),\n })\n\n const contents = () => (\n <>\n <Show when={busy()}>\n <Spinner size=\"sm\" label={false} aria-hidden=\"true\" data-icon=\"inline-start\" />\n </Show>\n {local.children}\n </>\n )\n\n return (\n <>\n <Show\n when={local.tooltip}\n fallback={\n <PolymorphicButton\n as={(local.as ?? 'button') as T}\n {...(buttonProps() as unknown as ButtonProps<T>)}\n >\n {contents()}\n </PolymorphicButton>\n }\n >\n <Tooltip\n open={tooltipOpen()}\n onOpenChange={(open) => {\n if (open && tooltipSuppression()) return\n setTooltipOpen(open)\n }}\n >\n <TooltipTrigger\n as={PolymorphicButtonTarget}\n {...(buttonProps() as unknown as ComponentProps<typeof PolymorphicButtonTarget>)}\n actionAs={(local.as ?? 'button') as T}\n >\n {contents()}\n </TooltipTrigger>\n <TooltipContent side={local.tooltipSide}>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n <Show when={busy()}>\n <span role=\"status\" aria-live=\"polite\" class=\"visually-hidden\">\n {busyStatus()}\n </span>\n </Show>\n </>\n )\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Shared host-neutral scene movement, jump and zoom controls. */
2
+ export { SceneControls, type SceneControlLabels, type SceneControlsProps, type SceneMovementDirection, } from './scene-controls';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/scene-controls/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,GAC5B,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { SceneControls } from "./scene-controls.js";
2
+ export { SceneControls };
@@ -0,0 +1,41 @@
1
+ import { type JSX } from 'solid-js';
2
+ /** A host-neutral direction reported while a movement control is held. */
3
+ export type SceneMovementDirection = 'forward' | 'left' | 'backward' | 'right';
4
+ /** Accessible names and tooltip text for the shared scene controls. */
5
+ export type SceneControlLabels = {
6
+ movementGroup: string;
7
+ forward: string;
8
+ forwardTooltip: string;
9
+ left: string;
10
+ leftTooltip: string;
11
+ backward: string;
12
+ backwardTooltip: string;
13
+ right: string;
14
+ rightTooltip: string;
15
+ jump: string;
16
+ jumpTooltip: string;
17
+ zoomGroup: string;
18
+ zoomOut: string;
19
+ zoomIn: string;
20
+ };
21
+ export type SceneControlsProps = {
22
+ /** Called on the transition into and out of each held movement direction. */
23
+ onMovementChange?: (direction: SceneMovementDirection, pressed: boolean) => void;
24
+ /** Called when the jump action becomes pressed or released. */
25
+ onJumpChange?: (pressed: boolean) => void;
26
+ /** Called once when zoom in is activated. */
27
+ onZoomIn?: () => void;
28
+ /** Called once when zoom out is activated. */
29
+ onZoomOut?: () => void;
30
+ /** Override the default English accessible names and tooltip copy. */
31
+ labels?: Partial<SceneControlLabels>;
32
+ };
33
+ /**
34
+ * Shared movement, jump and zoom controls for a host-rendered scene.
35
+ *
36
+ * Movement and jump callbacks receive pressed/released state from pointer and
37
+ * keyboard input. Zoom callbacks fire on activation. The host owns positioning,
38
+ * scene state and camera behavior.
39
+ */
40
+ export declare function SceneControls(props: SceneControlsProps): JSX.Element;
41
+ //# sourceMappingURL=scene-controls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-controls.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/scene-controls/scene-controls.tsx"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAA;AAGlE,0EAA0E;AAC1E,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAA;AAE9E,uEAAuE;AACvE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAsBD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IAChF,+DAA+D;IAC/D,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACzC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;CACrC,CAAA;AAmHD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,eAuGtD"}
@@ -0,0 +1,291 @@
1
+ import { ActionButton } from "../action-button/action-button.js";
2
+ import { createComponent, effect, insert, setAttribute, template } from "solid-js/web";
3
+ import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ZoomIn, ZoomOut } from "lucide-solid";
4
+ import { Show, createSignal, onCleanup } from "solid-js";
5
+ //#region src/components/composites/scene-controls/scene-controls.tsx
6
+ var _tmpl$ = /*#__PURE__*/ template(`<div role=group class="glass-scrim grid min-w-0 max-w-full grid-cols-3 gap-1.5 rounded-3xl p-2"><span aria-hidden=true></span><span aria-hidden=true>`);
7
+ var _tmpl$2 = /*#__PURE__*/ template(`<div role=group class="glass-scrim flex min-w-0 max-w-full flex-wrap gap-1.5 rounded-2xl p-1.5">`);
8
+ var _tmpl$3 = /*#__PURE__*/ template(`<div class="flex min-w-0 max-w-full flex-wrap items-end gap-3"><div class="ml-auto flex min-w-0 max-w-full flex-col items-end gap-2">`);
9
+ var DEFAULT_LABELS = {
10
+ movementGroup: "Scene movement controls",
11
+ forward: "Move forward",
12
+ forwardTooltip: "Hold to move forward",
13
+ left: "Move left",
14
+ leftTooltip: "Hold to move left",
15
+ backward: "Move backward",
16
+ backwardTooltip: "Hold to move backward",
17
+ right: "Move right",
18
+ rightTooltip: "Hold to move right",
19
+ jump: "Jump",
20
+ jumpTooltip: "Hold to jump",
21
+ zoomGroup: "Camera zoom",
22
+ zoomOut: "Zoom out",
23
+ zoomIn: "Zoom in"
24
+ };
25
+ var pointerSource = (pointerId) => `pointer:${pointerId}`;
26
+ var keySource = (key) => `key:${key}`;
27
+ /**
28
+ * A held action that reports one down/up pair across pointer and keyboard input.
29
+ *
30
+ * The arrangement, rounded scrim group surfaces and release policy translate
31
+ * Adea's on-screen scene controls; host key synthesis and scene APIs are replaced
32
+ * by callbacks.
33
+ */
34
+ function HoldAction(props) {
35
+ const [pressed, setPressed] = createSignal(false);
36
+ const sources = /* @__PURE__ */ new Set();
37
+ let activeChangeCallback;
38
+ const press = (source) => {
39
+ if (sources.has(source)) return;
40
+ const wasPressed = sources.size > 0;
41
+ sources.add(source);
42
+ if (!wasPressed) {
43
+ setPressed(true);
44
+ activeChangeCallback = props.createChangeCallback();
45
+ activeChangeCallback(true);
46
+ }
47
+ };
48
+ const release = (source) => {
49
+ if (!sources.delete(source) || sources.size > 0) return;
50
+ setPressed(false);
51
+ const callback = activeChangeCallback;
52
+ activeChangeCallback = void 0;
53
+ callback?.(false);
54
+ };
55
+ const releaseAll = () => {
56
+ if (sources.size === 0) return;
57
+ sources.clear();
58
+ setPressed(false);
59
+ const callback = activeChangeCallback;
60
+ activeChangeCallback = void 0;
61
+ callback?.(false);
62
+ };
63
+ const onWindowPointerUp = (event) => release(pointerSource(event.pointerId));
64
+ const onWindowBlur = () => releaseAll();
65
+ if (typeof window !== "undefined") {
66
+ window.addEventListener("pointerup", onWindowPointerUp);
67
+ window.addEventListener("blur", onWindowBlur);
68
+ }
69
+ onCleanup(() => {
70
+ releaseAll();
71
+ if (typeof window !== "undefined") {
72
+ window.removeEventListener("pointerup", onWindowPointerUp);
73
+ window.removeEventListener("blur", onWindowBlur);
74
+ }
75
+ });
76
+ return createComponent(ActionButton, {
77
+ type: "button",
78
+ variant: "secondary",
79
+ size: "icon-2xl",
80
+ get ["aria-label"]() {
81
+ return props.label;
82
+ },
83
+ get ["aria-pressed"]() {
84
+ return pressed();
85
+ },
86
+ get tooltip() {
87
+ return props.tooltip;
88
+ },
89
+ "class": "touch-none select-none",
90
+ onContextMenu: (event) => event.preventDefault(),
91
+ onPointerDown: (event) => {
92
+ if (event.button !== 0) return;
93
+ event.preventDefault();
94
+ const source = pointerSource(event.pointerId);
95
+ if (sources.has(source)) return;
96
+ try {
97
+ event.currentTarget.setPointerCapture(event.pointerId);
98
+ } catch {}
99
+ press(source);
100
+ },
101
+ onPointerUp: (event) => release(pointerSource(event.pointerId)),
102
+ onPointerCancel: (event) => release(pointerSource(event.pointerId)),
103
+ onLostPointerCapture: (event) => release(pointerSource(event.pointerId)),
104
+ onKeyDown: (event) => {
105
+ if (event.key !== " " && event.key !== "Enter") return;
106
+ event.preventDefault();
107
+ press(keySource(event.key));
108
+ },
109
+ onKeyUp: (event) => {
110
+ if (event.key !== " " && event.key !== "Enter") return;
111
+ event.preventDefault();
112
+ release(keySource(event.key));
113
+ },
114
+ onBlur: releaseAll,
115
+ onClick: (event) => {
116
+ if (event.detail !== 0 || sources.size > 0) return;
117
+ press("activation");
118
+ release("activation");
119
+ },
120
+ get children() {
121
+ return props.children;
122
+ }
123
+ });
124
+ }
125
+ /**
126
+ * Shared movement, jump and zoom controls for a host-rendered scene.
127
+ *
128
+ * Movement and jump callbacks receive pressed/released state from pointer and
129
+ * keyboard input. Zoom callbacks fire on activation. The host owns positioning,
130
+ * scene state and camera behavior.
131
+ */
132
+ function SceneControls(props) {
133
+ const labels = () => ({
134
+ ...DEFAULT_LABELS,
135
+ ...props.labels
136
+ });
137
+ return (() => {
138
+ var _el$ = _tmpl$3(), _el$5 = _el$.firstChild;
139
+ insert(_el$, createComponent(Show, {
140
+ get when() {
141
+ return props.onMovementChange;
142
+ },
143
+ get children() {
144
+ var _el$2 = _tmpl$(), _el$4 = _el$2.firstChild.nextSibling;
145
+ insert(_el$2, createComponent(HoldAction, {
146
+ get label() {
147
+ return labels().forward;
148
+ },
149
+ get tooltip() {
150
+ return labels().forwardTooltip;
151
+ },
152
+ createChangeCallback: () => {
153
+ const callback = props.onMovementChange;
154
+ return (pressed) => callback?.("forward", pressed);
155
+ },
156
+ get children() {
157
+ return createComponent(ArrowUp, { "aria-hidden": "true" });
158
+ }
159
+ }), _el$4);
160
+ insert(_el$2, createComponent(HoldAction, {
161
+ get label() {
162
+ return labels().left;
163
+ },
164
+ get tooltip() {
165
+ return labels().leftTooltip;
166
+ },
167
+ createChangeCallback: () => {
168
+ const callback = props.onMovementChange;
169
+ return (pressed) => callback?.("left", pressed);
170
+ },
171
+ get children() {
172
+ return createComponent(ArrowLeft, { "aria-hidden": "true" });
173
+ }
174
+ }), null);
175
+ insert(_el$2, createComponent(HoldAction, {
176
+ get label() {
177
+ return labels().backward;
178
+ },
179
+ get tooltip() {
180
+ return labels().backwardTooltip;
181
+ },
182
+ createChangeCallback: () => {
183
+ const callback = props.onMovementChange;
184
+ return (pressed) => callback?.("backward", pressed);
185
+ },
186
+ get children() {
187
+ return createComponent(ArrowDown, { "aria-hidden": "true" });
188
+ }
189
+ }), null);
190
+ insert(_el$2, createComponent(HoldAction, {
191
+ get label() {
192
+ return labels().right;
193
+ },
194
+ get tooltip() {
195
+ return labels().rightTooltip;
196
+ },
197
+ createChangeCallback: () => {
198
+ const callback = props.onMovementChange;
199
+ return (pressed) => callback?.("right", pressed);
200
+ },
201
+ get children() {
202
+ return createComponent(ArrowRight, { "aria-hidden": "true" });
203
+ }
204
+ }), null);
205
+ effect(() => setAttribute(_el$2, "aria-label", labels().movementGroup));
206
+ return _el$2;
207
+ }
208
+ }), _el$5);
209
+ insert(_el$5, createComponent(Show, {
210
+ get when() {
211
+ return props.onZoomIn || props.onZoomOut;
212
+ },
213
+ get children() {
214
+ var _el$6 = _tmpl$2();
215
+ insert(_el$6, createComponent(Show, {
216
+ get when() {
217
+ return props.onZoomOut;
218
+ },
219
+ get children() {
220
+ return createComponent(ActionButton, {
221
+ type: "button",
222
+ variant: "secondary",
223
+ size: "icon-2xl",
224
+ get ["aria-label"]() {
225
+ return labels().zoomOut;
226
+ },
227
+ get tooltip() {
228
+ return labels().zoomOut;
229
+ },
230
+ onClick: () => props.onZoomOut?.(),
231
+ get children() {
232
+ return createComponent(ZoomOut, { "aria-hidden": "true" });
233
+ }
234
+ });
235
+ }
236
+ }), null);
237
+ insert(_el$6, createComponent(Show, {
238
+ get when() {
239
+ return props.onZoomIn;
240
+ },
241
+ get children() {
242
+ return createComponent(ActionButton, {
243
+ type: "button",
244
+ variant: "secondary",
245
+ size: "icon-2xl",
246
+ get ["aria-label"]() {
247
+ return labels().zoomIn;
248
+ },
249
+ get tooltip() {
250
+ return labels().zoomIn;
251
+ },
252
+ onClick: () => props.onZoomIn?.(),
253
+ get children() {
254
+ return createComponent(ZoomIn, { "aria-hidden": "true" });
255
+ }
256
+ });
257
+ }
258
+ }), null);
259
+ effect(() => setAttribute(_el$6, "aria-label", labels().zoomGroup));
260
+ return _el$6;
261
+ }
262
+ }), null);
263
+ insert(_el$5, createComponent(Show, {
264
+ get when() {
265
+ return props.onJumpChange;
266
+ },
267
+ get children() {
268
+ return createComponent(HoldAction, {
269
+ get label() {
270
+ return labels().jump;
271
+ },
272
+ get tooltip() {
273
+ return labels().jumpTooltip;
274
+ },
275
+ createChangeCallback: () => {
276
+ const callback = props.onJumpChange;
277
+ return (pressed) => callback?.(pressed);
278
+ },
279
+ get children() {
280
+ return createComponent(ArrowUp, { "aria-hidden": "true" });
281
+ }
282
+ });
283
+ }
284
+ }), null);
285
+ return _el$;
286
+ })();
287
+ }
288
+ //#endregion
289
+ export { SceneControls };
290
+
291
+ //# sourceMappingURL=scene-controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-controls.js","names":["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","ZoomIn","ZoomOut","createSignal","onCleanup","Show","JSX","ActionButton","SceneMovementDirection","SceneControlLabels","movementGroup","forward","forwardTooltip","left","leftTooltip","backward","backwardTooltip","right","rightTooltip","jump","jumpTooltip","zoomGroup","zoomOut","zoomIn","DEFAULT_LABELS","pointerSource","pointerId","keySource","key","SceneControlsProps","onMovementChange","direction","pressed","onJumpChange","onZoomIn","onZoomOut","labels","Partial","HoldActionProps","label","tooltip","createChangeCallback","children","Element","HoldAction","props","setPressed","sources","Set","activeChangeCallback","press","source","has","wasPressed","size","add","release","delete","callback","undefined","releaseAll","clear","onWindowPointerUp","event","PointerEvent","onWindowBlur","window","addEventListener","removeEventListener","_$createComponent","type","variant","aria-label","aria-pressed","onContextMenu","preventDefault","onPointerDown","button","currentTarget","setPointerCapture","onPointerUp","onPointerCancel","onLostPointerCapture","onKeyDown","onKeyUp","onBlur","onClick","detail","SceneControls","_el$","_tmpl$3","_el$5","firstChild","_$insert","when","_el$2","_tmpl$","_el$3","_el$4","nextSibling","_$effect","_$setAttribute","_el$6","_tmpl$2","_$createComponent","_$setAttribute"],"sources":["../../../../src/components/composites/scene-controls/scene-controls.tsx"],"sourcesContent":["import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ZoomIn, ZoomOut } from 'lucide-solid'\nimport { createSignal, onCleanup, Show, type JSX } from 'solid-js'\nimport { ActionButton } from '../action-button'\n\n/** A host-neutral direction reported while a movement control is held. */\nexport type SceneMovementDirection = 'forward' | 'left' | 'backward' | 'right'\n\n/** Accessible names and tooltip text for the shared scene controls. */\nexport type SceneControlLabels = {\n movementGroup: string\n forward: string\n forwardTooltip: string\n left: string\n leftTooltip: string\n backward: string\n backwardTooltip: string\n right: string\n rightTooltip: string\n jump: string\n jumpTooltip: string\n zoomGroup: string\n zoomOut: string\n zoomIn: string\n}\n\nconst DEFAULT_LABELS: SceneControlLabels = {\n movementGroup: 'Scene movement controls',\n forward: 'Move forward',\n forwardTooltip: 'Hold to move forward',\n left: 'Move left',\n leftTooltip: 'Hold to move left',\n backward: 'Move backward',\n backwardTooltip: 'Hold to move backward',\n right: 'Move right',\n rightTooltip: 'Hold to move right',\n jump: 'Jump',\n jumpTooltip: 'Hold to jump',\n zoomGroup: 'Camera zoom',\n zoomOut: 'Zoom out',\n zoomIn: 'Zoom in',\n}\n\nconst pointerSource = (pointerId: number) => `pointer:${pointerId}`\nconst keySource = (key: string) => `key:${key}`\n\nexport type SceneControlsProps = {\n /** Called on the transition into and out of each held movement direction. */\n onMovementChange?: (direction: SceneMovementDirection, pressed: boolean) => void\n /** Called when the jump action becomes pressed or released. */\n onJumpChange?: (pressed: boolean) => void\n /** Called once when zoom in is activated. */\n onZoomIn?: () => void\n /** Called once when zoom out is activated. */\n onZoomOut?: () => void\n /** Override the default English accessible names and tooltip copy. */\n labels?: Partial<SceneControlLabels>\n}\n\ntype HoldActionProps = {\n label: string\n tooltip: string\n createChangeCallback: () => (pressed: boolean) => void\n children: JSX.Element\n}\n\n/**\n * A held action that reports one down/up pair across pointer and keyboard input.\n *\n * The arrangement, rounded scrim group surfaces and release policy translate\n * Adea's on-screen scene controls; host key synthesis and scene APIs are replaced\n * by callbacks.\n */\nfunction HoldAction(props: HoldActionProps) {\n const [pressed, setPressed] = createSignal(false)\n const sources = new Set<string>()\n let activeChangeCallback: ((pressed: boolean) => void) | undefined\n\n const press = (source: string) => {\n if (sources.has(source)) return\n const wasPressed = sources.size > 0\n sources.add(source)\n if (!wasPressed) {\n setPressed(true)\n activeChangeCallback = props.createChangeCallback()\n activeChangeCallback(true)\n }\n }\n\n const release = (source: string) => {\n if (!sources.delete(source) || sources.size > 0) return\n setPressed(false)\n const callback = activeChangeCallback\n activeChangeCallback = undefined\n callback?.(false)\n }\n\n const releaseAll = () => {\n if (sources.size === 0) return\n sources.clear()\n setPressed(false)\n const callback = activeChangeCallback\n activeChangeCallback = undefined\n callback?.(false)\n }\n\n const onWindowPointerUp = (event: PointerEvent) => release(pointerSource(event.pointerId))\n const onWindowBlur = () => releaseAll()\n\n if (typeof window !== 'undefined') {\n window.addEventListener('pointerup', onWindowPointerUp)\n window.addEventListener('blur', onWindowBlur)\n }\n\n onCleanup(() => {\n releaseAll()\n if (typeof window !== 'undefined') {\n window.removeEventListener('pointerup', onWindowPointerUp)\n window.removeEventListener('blur', onWindowBlur)\n }\n })\n\n return (\n <ActionButton\n type=\"button\"\n variant=\"secondary\"\n size=\"icon-2xl\"\n aria-label={props.label}\n aria-pressed={pressed()}\n tooltip={props.tooltip}\n class=\"touch-none select-none\"\n onContextMenu={(event) => event.preventDefault()}\n onPointerDown={(event) => {\n if (event.button !== 0) return\n event.preventDefault()\n const source = pointerSource(event.pointerId)\n if (sources.has(source)) return\n try {\n event.currentTarget.setPointerCapture(event.pointerId)\n } catch {\n // Pointer capture is not available in every embedded browser. The\n // window pointerup fallback still closes this held action.\n }\n press(source)\n }}\n onPointerUp={(event) => release(pointerSource(event.pointerId))}\n onPointerCancel={(event) => release(pointerSource(event.pointerId))}\n onLostPointerCapture={(event) => release(pointerSource(event.pointerId))}\n onKeyDown={(event) => {\n if (event.key !== ' ' && event.key !== 'Enter') return\n event.preventDefault()\n press(keySource(event.key))\n }}\n onKeyUp={(event) => {\n if (event.key !== ' ' && event.key !== 'Enter') return\n event.preventDefault()\n release(keySource(event.key))\n }}\n onBlur={releaseAll}\n onClick={(event) => {\n // Assistive technology can activate a button without pointer or keyboard\n // down/up events. Treat that activation as one short held action.\n if (event.detail !== 0 || sources.size > 0) return\n press('activation')\n release('activation')\n }}\n >\n {props.children}\n </ActionButton>\n )\n}\n\n/**\n * Shared movement, jump and zoom controls for a host-rendered scene.\n *\n * Movement and jump callbacks receive pressed/released state from pointer and\n * keyboard input. Zoom callbacks fire on activation. The host owns positioning,\n * scene state and camera behavior.\n */\nexport function SceneControls(props: SceneControlsProps) {\n const labels = () => ({ ...DEFAULT_LABELS, ...props.labels })\n\n return (\n <div class=\"flex min-w-0 max-w-full flex-wrap items-end gap-3\">\n <Show when={props.onMovementChange}>\n <div\n role=\"group\"\n aria-label={labels().movementGroup}\n class=\"glass-scrim grid min-w-0 max-w-full grid-cols-3 gap-1.5 rounded-3xl p-2\"\n >\n <span aria-hidden=\"true\" />\n <HoldAction\n label={labels().forward}\n tooltip={labels().forwardTooltip}\n createChangeCallback={() => {\n const callback = props.onMovementChange\n return (pressed) => callback?.('forward', pressed)\n }}\n >\n <ArrowUp aria-hidden=\"true\" />\n </HoldAction>\n <span aria-hidden=\"true\" />\n <HoldAction\n label={labels().left}\n tooltip={labels().leftTooltip}\n createChangeCallback={() => {\n const callback = props.onMovementChange\n return (pressed) => callback?.('left', pressed)\n }}\n >\n <ArrowLeft aria-hidden=\"true\" />\n </HoldAction>\n <HoldAction\n label={labels().backward}\n tooltip={labels().backwardTooltip}\n createChangeCallback={() => {\n const callback = props.onMovementChange\n return (pressed) => callback?.('backward', pressed)\n }}\n >\n <ArrowDown aria-hidden=\"true\" />\n </HoldAction>\n <HoldAction\n label={labels().right}\n tooltip={labels().rightTooltip}\n createChangeCallback={() => {\n const callback = props.onMovementChange\n return (pressed) => callback?.('right', pressed)\n }}\n >\n <ArrowRight aria-hidden=\"true\" />\n </HoldAction>\n </div>\n </Show>\n <div class=\"ml-auto flex min-w-0 max-w-full flex-col items-end gap-2\">\n <Show when={props.onZoomIn || props.onZoomOut}>\n <div\n role=\"group\"\n aria-label={labels().zoomGroup}\n class=\"glass-scrim flex min-w-0 max-w-full flex-wrap gap-1.5 rounded-2xl p-1.5\"\n >\n <Show when={props.onZoomOut}>\n <ActionButton\n type=\"button\"\n variant=\"secondary\"\n size=\"icon-2xl\"\n aria-label={labels().zoomOut}\n tooltip={labels().zoomOut}\n onClick={() => props.onZoomOut?.()}\n >\n <ZoomOut aria-hidden=\"true\" />\n </ActionButton>\n </Show>\n <Show when={props.onZoomIn}>\n <ActionButton\n type=\"button\"\n variant=\"secondary\"\n size=\"icon-2xl\"\n aria-label={labels().zoomIn}\n tooltip={labels().zoomIn}\n onClick={() => props.onZoomIn?.()}\n >\n <ZoomIn aria-hidden=\"true\" />\n </ActionButton>\n </Show>\n </div>\n </Show>\n <Show when={props.onJumpChange}>\n <HoldAction\n label={labels().jump}\n tooltip={labels().jumpTooltip}\n createChangeCallback={() => {\n const callback = props.onJumpChange\n return (pressed) => callback?.(pressed)\n }}\n >\n <ArrowUp aria-hidden=\"true\" />\n </HoldAction>\n </Show>\n </div>\n </div>\n )\n}\n"],"mappings":"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"}
@@ -19,7 +19,8 @@ import { type VariantProps } from '#lib/variants';
19
19
  */
20
20
  export declare const buttonVariants: (props?: ({
21
21
  variant?: "link" | "default" | "destructive" | "success" | "secondary" | "outline" | "subtle" | "ghost" | null | undefined;
22
- size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "icon-2xs" | "icon-xs" | "icon-sm" | "icon-md" | "icon-lg" | "icon-xl" | null | undefined;
22
+ size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "icon-2xs" | "icon-xs" | "icon-sm" | "icon-md" | "icon-lg" | "icon-xl" | "icon-2xl" | null | undefined;
23
+ touchTarget?: "comfortable" | null | undefined;
23
24
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
24
25
  type ButtonVariantProps = VariantProps<typeof buttonVariants>;
25
26
  export type ButtonProps<T extends ValidComponent = 'button'> = PolymorphicProps<T, ButtonVariantProps & {
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/button/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/E,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAGvF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;;8EA6C1B,CAAA;AAED,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAA;AAE7D,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,gBAAgB,CAC7E,CAAC,EACD,kBAAkB,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CACF,CAAA;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,kCAWhF"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/button/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/E,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAGvF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;;;8EAmD1B,CAAA;AAED,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAA;AAE7D,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,gBAAgB,CAC7E,CAAC,EACD,kBAAkB,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CACF,CAAA;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,kCAuBhF"}
@@ -44,13 +44,17 @@ var buttonVariants = cva(`${controlInteractive} inline-flex shrink-0 items-cente
44
44
  md: `${controlSize.md} [&_svg]:size-4`,
45
45
  lg: `${controlSize.lg} [&_svg]:size-4`,
46
46
  xl: `${controlSize.xl} [&_svg]:size-5`,
47
+ "2xl": `${controlSize["2xl"]} [&_svg]:size-6`,
47
48
  "icon-2xs": "size-control-2xs p-0 [&_svg]:size-3",
48
49
  "icon-xs": "size-control-xs p-0 [&_svg]:size-3.5",
49
50
  "icon-sm": "size-control-sm p-0 [&_svg]:size-3.5",
50
51
  "icon-md": "size-control-md p-0 [&_svg]:size-4",
51
52
  "icon-lg": "size-control-lg p-0 [&_svg]:size-4",
52
- "icon-xl": "size-control-xl p-0 [&_svg]:size-5"
53
- }
53
+ "icon-xl": "size-control-xl p-0 [&_svg]:size-5",
54
+ "icon-2xl": "size-control-2xl p-0 [&_svg]:size-6"
55
+ },
56
+ /** Opt in to a stable touch target on devices with any coarse pointer. */
57
+ touchTarget: { comfortable: "touch-target-comfortable" }
54
58
  },
55
59
  defaultVariants: {
56
60
  variant: "default",
@@ -61,6 +65,7 @@ function Button(props) {
61
65
  const [local, rest] = splitProps(props, [
62
66
  "variant",
63
67
  "size",
68
+ "touchTarget",
64
69
  "class"
65
70
  ]);
66
71
  return createComponent(Polymorphic, mergeProps({
@@ -69,7 +74,8 @@ function Button(props) {
69
74
  get ["class"]() {
70
75
  return cn(buttonVariants({
71
76
  variant: local.variant,
72
- size: local.size
77
+ size: local.size,
78
+ touchTarget: local.touchTarget
73
79
  }), local.class);
74
80
  }
75
81
  }, rest));
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","names":["Polymorphic","PolymorphicProps","ComponentProps","splitProps","ValidComponent","cva","controlInteractive","controlSize","VariantProps","cn","buttonVariants","variants","variant","default","secondary","destructive","outline","ghost","subtle","success","link","size","xs","sm","md","lg","xl","defaultVariants","ButtonVariantProps","ButtonProps","T","class","Button","props","local","rest","_$createComponent","_$mergeProps","as","type","_$createComponent","_$mergeProps"],"sources":["../../../../src/components/ui/button/button.tsx"],"sourcesContent":["import { Polymorphic, type PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { type ComponentProps, splitProps, type ValidComponent } from 'solid-js'\nimport { cva, controlInteractive, controlSize, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * Button.\n *\n * One appearance ladder shared by every pressable thing in the system: a\n * button, a toolbar control, a dialog action, and a menu row all draw from the\n * same tokens, so a row of them cannot drift apart.\n *\n * The variants answer \"what is this for\", never \"what colour is it\". A caller\n * that wants a red button writes `variant=\"destructive\"`; the red lives here.\n * That is also what lets the design-system linter tell a caller which variant\n * to use instead of only which class was wrong.\n *\n * Polymorphic: pass `as=\"a\"` (or any component) and the button becomes it\n * while keeping the same styling contract. This replaces the React-era\n * `asChild` primitive, which has no Solid equivalent that preserves props.\n */\nexport const buttonVariants = cva(\n `${controlInteractive} inline-flex shrink-0 items-center justify-center rounded-md font-medium whitespace-nowrap select-none [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n {\n variants: {\n variant: {\n /** The one primary action in a view. */\n default: 'bg-primary text-primary-foreground hover:bg-primary-hover',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-surface-hover',\n /** For the action that destroys something. Never the default. */\n destructive:\n 'bg-destructive-action text-destructive-action-foreground hover:bg-destructive-action/90 focus-visible:ring-destructive-subtle',\n /** A bordered button for a surface that already has a fill. */\n outline:\n 'border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input',\n /** No chrome until hover. The default for toolbar and row actions. */\n ghost: 'text-foreground hover:bg-surface-hover',\n /** A tinted primary, for a secondary action inside a primary flow. */\n subtle: 'bg-primary-subtle text-primary hover:bg-primary-subtle/80',\n success: 'bg-success text-success-foreground hover:bg-success/90',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n '2xs': `${controlSize['2xs']} [&_svg]:size-3`,\n xs: `${controlSize.xs} [&_svg]:size-3.5`,\n sm: `${controlSize.sm} [&_svg]:size-3.5`,\n md: `${controlSize.md} [&_svg]:size-4`,\n lg: `${controlSize.lg} [&_svg]:size-4`,\n xl: `${controlSize.xl} [&_svg]:size-5`,\n /* Square, for an icon with no label. The accessible name then has to\n come from `aria-label` or a visually hidden label — an icon-only\n button with neither is the accessibility finding the Storybook lane\n catches on every story. */\n 'icon-2xs': 'size-control-2xs p-0 [&_svg]:size-3',\n 'icon-xs': 'size-control-xs p-0 [&_svg]:size-3.5',\n 'icon-sm': 'size-control-sm p-0 [&_svg]:size-3.5',\n 'icon-md': 'size-control-md p-0 [&_svg]:size-4',\n 'icon-lg': 'size-control-lg p-0 [&_svg]:size-4',\n 'icon-xl': 'size-control-xl p-0 [&_svg]:size-5',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n },\n }\n)\n\ntype ButtonVariantProps = VariantProps<typeof buttonVariants>\n\nexport type ButtonProps<T extends ValidComponent = 'button'> = PolymorphicProps<\n T,\n ButtonVariantProps & {\n class?: string\n }\n>\n\nexport function Button<T extends ValidComponent = 'button'>(props: ButtonProps<T>) {\n const [local, rest] = splitProps(props as ButtonProps, ['variant', 'size', 'class'])\n\n return (\n <Polymorphic\n as=\"button\"\n type=\"button\"\n class={cn(buttonVariants({ variant: local.variant, size: local.size }), local.class)}\n {...(rest as ComponentProps<'button'>)}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,IAAaU,iBAAiBL,IAC5B,GAAGC,mBAAkB,sJACrB;CACEK,UAAU;EACRC,SAAS;;GAEPC,SAAS;GACTC,WAAW;;GAEXC,aACE;;GAEFC,SACE;;GAEFC,OAAO;;GAEPC,QAAQ;GACRC,SAAS;GACTC,MAAM;EACR;EACAC,MAAM;GACJ,OAAO,GAAGd,YAAY,OAAM;GAC5Be,IAAI,GAAGf,YAAYe,GAAE;GACrBC,IAAI,GAAGhB,YAAYgB,GAAE;GACrBC,IAAI,GAAGjB,YAAYiB,GAAE;GACrBC,IAAI,GAAGlB,YAAYkB,GAAE;GACrBC,IAAI,GAAGnB,YAAYmB,GAAE;GAKrB,YAAY;GACZ,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;EACb;CACF;CACAC,iBAAiB;EACff,SAAS;EACTS,MAAM;CACR;AACF,CACF;AAWA,SAAgBW,OAA4CC,OAAuB;CACjF,MAAM,CAACC,OAAOC,QAAQhC,WAAW8B,OAAsB;EAAC;EAAW;EAAQ;CAAO,CAAC;CAEnF,OAAAG,gBACGpC,aAAWqC,WAAA;EACVC,IAAE;EACFC,MAAI;EAAA,KAAA,WAAA;GAAA,OACG9B,GAAGC,eAAe;IAAEE,SAASsB,MAAMtB;IAASS,MAAMa,MAAMb;GAAK,CAAC,GAAGa,MAAMH,KAAK;EAAC;CAAA,GAC/EI,IAAgC,CAAA;AAG3C"}
1
+ {"version":3,"file":"button.js","names":["Polymorphic","PolymorphicProps","ComponentProps","splitProps","ValidComponent","cva","controlInteractive","controlSize","VariantProps","cn","buttonVariants","variants","variant","default","secondary","destructive","outline","ghost","subtle","success","link","size","xs","sm","md","lg","xl","touchTarget","comfortable","defaultVariants","ButtonVariantProps","ButtonProps","T","class","Button","props","local","rest","_$createComponent","_$mergeProps","as","type","_$createComponent","_$mergeProps"],"sources":["../../../../src/components/ui/button/button.tsx"],"sourcesContent":["import { Polymorphic, type PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { type ComponentProps, splitProps, type ValidComponent } from 'solid-js'\nimport { cva, controlInteractive, controlSize, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * Button.\n *\n * One appearance ladder shared by every pressable thing in the system: a\n * button, a toolbar control, a dialog action, and a menu row all draw from the\n * same tokens, so a row of them cannot drift apart.\n *\n * The variants answer \"what is this for\", never \"what colour is it\". A caller\n * that wants a red button writes `variant=\"destructive\"`; the red lives here.\n * That is also what lets the design-system linter tell a caller which variant\n * to use instead of only which class was wrong.\n *\n * Polymorphic: pass `as=\"a\"` (or any component) and the button becomes it\n * while keeping the same styling contract. This replaces the React-era\n * `asChild` primitive, which has no Solid equivalent that preserves props.\n */\nexport const buttonVariants = cva(\n `${controlInteractive} inline-flex shrink-0 items-center justify-center rounded-md font-medium whitespace-nowrap select-none [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n {\n variants: {\n variant: {\n /** The one primary action in a view. */\n default: 'bg-primary text-primary-foreground hover:bg-primary-hover',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-surface-hover',\n /** For the action that destroys something. Never the default. */\n destructive:\n 'bg-destructive-action text-destructive-action-foreground hover:bg-destructive-action/90 focus-visible:ring-destructive-subtle',\n /** A bordered button for a surface that already has a fill. */\n outline:\n 'border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input',\n /** No chrome until hover. The default for toolbar and row actions. */\n ghost: 'text-foreground hover:bg-surface-hover',\n /** A tinted primary, for a secondary action inside a primary flow. */\n subtle: 'bg-primary-subtle text-primary hover:bg-primary-subtle/80',\n success: 'bg-success text-success-foreground hover:bg-success/90',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n '2xs': `${controlSize['2xs']} [&_svg]:size-3`,\n xs: `${controlSize.xs} [&_svg]:size-3.5`,\n sm: `${controlSize.sm} [&_svg]:size-3.5`,\n md: `${controlSize.md} [&_svg]:size-4`,\n lg: `${controlSize.lg} [&_svg]:size-4`,\n xl: `${controlSize.xl} [&_svg]:size-5`,\n '2xl': `${controlSize['2xl']} [&_svg]:size-6`,\n /* Square, for an icon with no label. The accessible name then has to\n come from `aria-label` or a visually hidden label — an icon-only\n button with neither is the accessibility finding the Storybook lane\n catches on every story. */\n 'icon-2xs': 'size-control-2xs p-0 [&_svg]:size-3',\n 'icon-xs': 'size-control-xs p-0 [&_svg]:size-3.5',\n 'icon-sm': 'size-control-sm p-0 [&_svg]:size-3.5',\n 'icon-md': 'size-control-md p-0 [&_svg]:size-4',\n 'icon-lg': 'size-control-lg p-0 [&_svg]:size-4',\n 'icon-xl': 'size-control-xl p-0 [&_svg]:size-5',\n 'icon-2xl': 'size-control-2xl p-0 [&_svg]:size-6',\n },\n /** Opt in to a stable touch target on devices with any coarse pointer. */\n touchTarget: {\n comfortable: 'touch-target-comfortable',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n },\n }\n)\n\ntype ButtonVariantProps = VariantProps<typeof buttonVariants>\n\nexport type ButtonProps<T extends ValidComponent = 'button'> = PolymorphicProps<\n T,\n ButtonVariantProps & {\n class?: string\n }\n>\n\nexport function Button<T extends ValidComponent = 'button'>(props: ButtonProps<T>) {\n const [local, rest] = splitProps(props as ButtonProps, [\n 'variant',\n 'size',\n 'touchTarget',\n 'class',\n ])\n\n return (\n <Polymorphic\n as=\"button\"\n type=\"button\"\n class={cn(\n buttonVariants({\n variant: local.variant,\n size: local.size,\n touchTarget: local.touchTarget,\n }),\n local.class\n )}\n {...(rest as ComponentProps<'button'>)}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,IAAaU,iBAAiBL,IAC5B,GAAGC,mBAAkB,sJACrB;CACEK,UAAU;EACRC,SAAS;;GAEPC,SAAS;GACTC,WAAW;;GAEXC,aACE;;GAEFC,SACE;;GAEFC,OAAO;;GAEPC,QAAQ;GACRC,SAAS;GACTC,MAAM;EACR;EACAC,MAAM;GACJ,OAAO,GAAGd,YAAY,OAAM;GAC5Be,IAAI,GAAGf,YAAYe,GAAE;GACrBC,IAAI,GAAGhB,YAAYgB,GAAE;GACrBC,IAAI,GAAGjB,YAAYiB,GAAE;GACrBC,IAAI,GAAGlB,YAAYkB,GAAE;GACrBC,IAAI,GAAGnB,YAAYmB,GAAE;GACrB,OAAO,GAAGnB,YAAY,OAAM;GAK5B,YAAY;GACZ,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,YAAY;EACd;;EAEAoB,aAAa,EACXC,aAAa,2BACf;CACF;CACAC,iBAAiB;EACfjB,SAAS;EACTS,MAAM;CACR;AACF,CACF;AAWA,SAAgBa,OAA4CC,OAAuB;CACjF,MAAM,CAACC,OAAOC,QAAQlC,WAAWgC,OAAsB;EACrD;EACA;EACA;EACA;CAAO,CACR;CAED,OAAAG,gBACGtC,aAAWuC,WAAA;EACVC,IAAE;EACFC,MAAI;EAAA,KAAA,WAAA;GAAA,OACGhC,GACLC,eAAe;IACbE,SAASwB,MAAMxB;IACfS,MAAMe,MAAMf;IACZM,aAAaS,MAAMT;GACrB,CAAC,GACDS,MAAMH,KACR;EAAC;CAAA,GACII,IAAgC,CAAA;AAG3C"}