@photon-ai/pho-ui 2.1.1 → 2.2.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.
Files changed (113) hide show
  1. package/dist/chunks/IconAlertCircleFilled-VxKU8TYK.js.map +1 -1
  2. package/dist/chunks/IconArrowUpRight-DGgKzQwV.js.map +1 -1
  3. package/dist/chunks/IconCheck-D2WuculQ.js.map +1 -1
  4. package/dist/chunks/IconChevronLeft-CSWMKQ4C.js.map +1 -1
  5. package/dist/chunks/IconInfoCircle-L0zfhg7R.js.map +1 -1
  6. package/dist/chunks/IconX-pZ9vrtSr.js.map +1 -1
  7. package/dist/chunks/animated-height-C2eQstGy.js.map +1 -1
  8. package/dist/chunks/{avatar-CiAvJNNs.js → avatar-BkmGDIqf.js} +3 -3
  9. package/dist/chunks/{avatar-CiAvJNNs.js.map → avatar-BkmGDIqf.js.map} +1 -1
  10. package/dist/chunks/basic-page-CB36yrpL.js +643 -0
  11. package/dist/chunks/basic-page-CB36yrpL.js.map +1 -0
  12. package/dist/chunks/{button-X5wsWvRa.js → button-BmhyLgy5.js} +3 -3
  13. package/dist/chunks/{button-X5wsWvRa.js.map → button-BmhyLgy5.js.map} +1 -1
  14. package/dist/chunks/{card-9cGnv-VD.js → card-DSW3Uhag.js} +2 -2
  15. package/dist/chunks/{card-9cGnv-VD.js.map → card-DSW3Uhag.js.map} +1 -1
  16. package/dist/chunks/{close-button-xadxp0j8.js → close-button-GvqWbLl0.js} +2 -2
  17. package/dist/chunks/{close-button-xadxp0j8.js.map → close-button-GvqWbLl0.js.map} +1 -1
  18. package/dist/chunks/{cn-DTiB6ek_.js → cn-ChIgwEl3.js} +99 -96
  19. package/dist/chunks/{cn-DTiB6ek_.js.map → cn-ChIgwEl3.js.map} +1 -1
  20. package/dist/chunks/{combobox-rLdS6fl-.js → combobox-Dj5m_dDd.js} +2 -2
  21. package/dist/chunks/{combobox-rLdS6fl-.js.map → combobox-Dj5m_dDd.js.map} +1 -1
  22. package/dist/chunks/createReactComponent-BqCmnqfX.js.map +1 -1
  23. package/dist/chunks/{dialog-BC23YRUq.js → dialog-DtFO7oy0.js} +5 -5
  24. package/dist/chunks/{dialog-BC23YRUq.js.map → dialog-DtFO7oy0.js.map} +1 -1
  25. package/dist/chunks/{error-DR6G2LmG.js → error-Da7P5WZi.js} +11 -10
  26. package/dist/chunks/{error-DR6G2LmG.js.map → error-Da7P5WZi.js.map} +1 -1
  27. package/dist/chunks/{input-D3XQcC4J.js → input-QSAUO30c.js} +2 -2
  28. package/dist/chunks/{input-D3XQcC4J.js.map → input-QSAUO30c.js.map} +1 -1
  29. package/dist/chunks/{input-group-D6dlma8k.js → input-group-5AtpIhC_.js} +2 -2
  30. package/dist/chunks/{input-group-D6dlma8k.js.map → input-group-5AtpIhC_.js.map} +1 -1
  31. package/dist/chunks/{menu-BC-9IP29.js → menu-Cgj3lq9z.js} +3 -3
  32. package/dist/chunks/{menu-BC-9IP29.js.map → menu-Cgj3lq9z.js.map} +1 -1
  33. package/dist/chunks/{popover-EL1SE1kj.js → popover-BhBJO346.js} +2 -2
  34. package/dist/chunks/{popover-EL1SE1kj.js.map → popover-BhBJO346.js.map} +1 -1
  35. package/dist/chunks/{scroll-area-CNZVwe7v.js → scroll-area-Cw4JFqNG.js} +2 -2
  36. package/dist/chunks/{scroll-area-CNZVwe7v.js.map → scroll-area-Cw4JFqNG.js.map} +1 -1
  37. package/dist/chunks/{sidebar-DDJC1MeD.js → sidebar-BETMObNj.js} +25 -24
  38. package/dist/chunks/{sidebar-DDJC1MeD.js.map → sidebar-BETMObNj.js.map} +1 -1
  39. package/dist/chunks/{spinner-Cy8bkyJf.js → spinner-BzLUo4Xk.js} +2 -2
  40. package/dist/chunks/{spinner-Cy8bkyJf.js.map → spinner-BzLUo4Xk.js.map} +1 -1
  41. package/dist/chunks/{status-view-CcbctPqR.js → status-view-C8tabjDu.js} +2 -2
  42. package/dist/chunks/{status-view-CcbctPqR.js.map → status-view-C8tabjDu.js.map} +1 -1
  43. package/dist/components/accordion.js +1 -1
  44. package/dist/components/autocomplete.js +1 -1
  45. package/dist/components/avatar.js +1 -1
  46. package/dist/components/badge.js +1 -1
  47. package/dist/components/button.js +2 -2
  48. package/dist/components/card.js +1 -1
  49. package/dist/components/checkbox.js +1 -1
  50. package/dist/components/checkbox.js.map +1 -1
  51. package/dist/components/collapsible.js +1 -1
  52. package/dist/components/combobox.js +1 -1
  53. package/dist/components/command.js +2 -2
  54. package/dist/components/command.js.map +1 -1
  55. package/dist/components/context-menu.js +2 -2
  56. package/dist/components/context-menu.js.map +1 -1
  57. package/dist/components/dialog.js +1 -1
  58. package/dist/components/drawer.js +1 -1
  59. package/dist/components/error.js +1 -1
  60. package/dist/components/field.js +1 -1
  61. package/dist/components/fieldset.js +1 -1
  62. package/dist/components/form.js +1 -1
  63. package/dist/components/input-group.js +1 -1
  64. package/dist/components/input.js +1 -1
  65. package/dist/components/kbd.js +1 -1
  66. package/dist/components/kbd.js.map +1 -1
  67. package/dist/components/menu.js +1 -1
  68. package/dist/components/menubar.js +1 -1
  69. package/dist/components/meter.js +1 -1
  70. package/dist/components/navigation-menu.js +1 -1
  71. package/dist/components/notification.js +1 -1
  72. package/dist/components/notification.js.map +1 -1
  73. package/dist/components/number-field.js +1 -1
  74. package/dist/components/otp-field.js +1 -1
  75. package/dist/components/otp-field.js.map +1 -1
  76. package/dist/components/phone-input.js +2064 -2050
  77. package/dist/components/phone-input.js.map +1 -1
  78. package/dist/components/popover.js +1 -1
  79. package/dist/components/preview-card.js +1 -1
  80. package/dist/components/progress.js +1 -1
  81. package/dist/components/radio-group.js +1 -1
  82. package/dist/components/radio-group.js.map +1 -1
  83. package/dist/components/scroll-area.js +1 -1
  84. package/dist/components/select.js +1 -1
  85. package/dist/components/select.js.map +1 -1
  86. package/dist/components/separator.js +1 -1
  87. package/dist/components/skeleton.js +1 -1
  88. package/dist/components/slider.js +1 -1
  89. package/dist/components/spinner.js +1 -1
  90. package/dist/components/status-view.js +1 -1
  91. package/dist/components/switch.js +1 -1
  92. package/dist/components/switch.js.map +1 -1
  93. package/dist/components/tabs.js +1 -1
  94. package/dist/components/theme-toggle.js +1 -1
  95. package/dist/components/theme-toggle.js.map +1 -1
  96. package/dist/components/toast.js +1 -1
  97. package/dist/components/toggle-group.js +1 -1
  98. package/dist/components/toggle.js +1 -1
  99. package/dist/components/toolbar.js +1 -1
  100. package/dist/components/tooltip.js +1 -1
  101. package/dist/icons.js.map +1 -1
  102. package/dist/index.js +11 -11
  103. package/dist/primitives.js +1 -3
  104. package/dist/sections/basic-page.js +1 -1
  105. package/dist/sections/sidebar.js +1 -1
  106. package/dist/src/components/toast/toast.d.ts +1 -1
  107. package/dist/src/sections/basic-page/basic-page.d.ts +57 -21
  108. package/dist/src/sections/basic-page/index.d.ts +1 -1
  109. package/dist/utils.js +1 -1
  110. package/package.json +21 -20
  111. package/dist/chunks/basic-page-x3aFcSVs.js +0 -482
  112. package/dist/chunks/basic-page-x3aFcSVs.js.map +0 -1
  113. package/dist/primitives.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as o } from "./cn-DTiB6ek_.js";
2
+ import { t as o } from "./cn-ChIgwEl3.js";
3
3
  import "react";
4
4
  import { jsx as n } from "react/jsx-runtime";
5
5
  import { Combobox as r } from "@base-ui/react/combobox";
@@ -114,4 +114,4 @@ export {
114
114
  R as t
115
115
  };
116
116
 
117
- //# sourceMappingURL=combobox-rLdS6fl-.js.map
117
+ //# sourceMappingURL=combobox-Dj5m_dDd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"combobox-rLdS6fl-.js","names":[],"sources":["../../src/components/combobox/combobox.tsx"],"sourcesContent":["import { type ComponentProps, type ElementType } from \"react\";\nimport { Combobox as BaseCombobox } from \"@base-ui/react/combobox\";\nimport { cn } from \"../../utils/cn\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\nconst Root = BaseCombobox.Root;\nconst Value = BaseCombobox.Value;\nconst Portal = BaseCombobox.Portal;\nconst Group = BaseCombobox.Group;\nconst Collection = BaseCombobox.Collection;\n\nfunction InputGroup({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.InputGroup>) {\n return (\n <BaseCombobox.InputGroup\n className={cn(\"relative flex items-center\", className)}\n {...props}\n />\n );\n}\n\nfunction Input({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Input>) {\n return (\n <BaseCombobox.Input\n className={cn(\n // text-md on small viewports — iOS zooms into fields under 16px.\n \"bg-pho-primary ring-pho-primary text-pho-primary placeholder:text-pho-placeholder focus-visible:ring-pho-brand text-md rounded-base w-full px-3 py-2 ring-1 transition-shadow duration-100 ease-linear outline-none ring-inset focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-base\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Clear({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Clear>) {\n return (\n <BaseCombobox.Clear\n className={cn(\n \"combobox-clear text-pho-secondary hover:text-pho-secondary-hover absolute right-2.5 flex cursor-pointer items-center [&>svg]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Trigger({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Trigger>) {\n return (\n <BaseCombobox.Trigger\n className={cn(\n \"text-pho-secondary hover:text-pho-secondary-hover absolute right-2.5 flex cursor-pointer items-center [&>svg]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Positioner({\n className,\n sideOffset = 6,\n ...props\n}: StyledProps<typeof BaseCombobox.Positioner>) {\n return (\n <BaseCombobox.Positioner\n sideOffset={sideOffset}\n className={cn(\"z-50 outline-none\", className)}\n {...props}\n />\n );\n}\n\nfunction Popup({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Popup>) {\n return (\n <BaseCombobox.Popup\n className={cn(\n \"bg-pho-primary text-pho-primary shadow-pho-lg ring-pho-secondary rounded-base w-[var(--anchor-width)] max-w-[var(--available-width)] origin-[var(--transform-origin)] p-1 ring-1 transition-[transform,opacity] duration-150 ease-out outline-none ring-inset\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction List({ className, ...props }: StyledProps<typeof BaseCombobox.List>) {\n return (\n <BaseCombobox.List\n className={cn(\n \"max-h-[min(20rem,var(--available-height))] overflow-y-auto overscroll-contain\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Empty({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Empty>) {\n return (\n <BaseCombobox.Empty\n className={cn(\n \"text-pho-description px-2.5 py-6 text-center text-base empty:m-0 empty:p-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Item({ className, ...props }: StyledProps<typeof BaseCombobox.Item>) {\n return (\n <BaseCombobox.Item\n className={cn(\n \"text-pho-secondary grid cursor-pointer grid-cols-[1rem_1fr] items-center gap-2 rounded-[calc(var(--radius-base)-4px)] py-1.5 pr-2.5 pl-2 text-base outline-none select-none\",\n \"data-[highlighted]:bg-pho-ghost-hover data-[highlighted]:text-pho-primary\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ItemIndicator({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.ItemIndicator>) {\n return (\n <BaseCombobox.ItemIndicator\n className={cn(\n \"text-pho-brand col-start-1 flex items-center [&>svg]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction GroupLabel({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.GroupLabel>) {\n return (\n <BaseCombobox.GroupLabel\n className={cn(\n \"text-pho-secondary px-2.5 py-1.5 text-xs font-medium\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Chips({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Chips>) {\n return (\n <BaseCombobox.Chips\n className={cn(\n \"bg-pho-primary ring-pho-primary focus-within:ring-pho-brand rounded-base flex flex-wrap items-center gap-1.5 p-1.5 ring-1 ring-inset focus-within:ring-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Chip({ className, ...props }: StyledProps<typeof BaseCombobox.Chip>) {\n return (\n <BaseCombobox.Chip\n className={cn(\n // Keyboard-highlighted chip flips to the inverse chip surface.\n \"bg-pho-secondary text-pho-secondary data-[highlighted]:bg-pho-inverse data-[highlighted]:text-pho-inverse flex items-center gap-1 rounded-sm py-0.5 pr-1 pl-2 text-base\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ChipRemove({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.ChipRemove>) {\n return (\n <BaseCombobox.ChipRemove\n className={cn(\n \"text-pho-secondary hover:text-pho-secondary-hover in-data-[highlighted]:text-pho-inverse flex cursor-pointer items-center rounded-sm [&>svg]:size-3.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Combobox built on Base UI `Combobox` — a text input that filters a list as\n * you type and commits to a value from it. Pass `items` to `Combobox.Root`;\n * `Combobox.List` takes a render function mapping each (filtered) item to a\n * `Combobox.Item`. Add `Combobox.Chips` for multi-select. For free-form text\n * with suggestions, use `Autocomplete`; for a small fixed set, use `Select`.\n */\nexport const Combobox = {\n Root,\n Value,\n InputGroup,\n Input,\n Trigger,\n Clear,\n Portal,\n Positioner,\n Popup,\n List,\n Collection,\n Empty,\n Item,\n ItemIndicator,\n Group,\n GroupLabel,\n Chips,\n Chip,\n ChipRemove,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"combobox-Dj5m_dDd.js","names":[],"sources":["../../src/components/combobox/combobox.tsx"],"sourcesContent":["import { type ComponentProps, type ElementType } from \"react\";\nimport { Combobox as BaseCombobox } from \"@base-ui/react/combobox\";\nimport { cn } from \"../../utils/cn\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\nconst Root = BaseCombobox.Root;\nconst Value = BaseCombobox.Value;\nconst Portal = BaseCombobox.Portal;\nconst Group = BaseCombobox.Group;\nconst Collection = BaseCombobox.Collection;\n\nfunction InputGroup({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.InputGroup>) {\n return (\n <BaseCombobox.InputGroup\n className={cn(\"relative flex items-center\", className)}\n {...props}\n />\n );\n}\n\nfunction Input({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Input>) {\n return (\n <BaseCombobox.Input\n className={cn(\n // text-md on small viewports — iOS zooms into fields under 16px.\n \"bg-pho-primary ring-pho-primary text-pho-primary placeholder:text-pho-placeholder focus-visible:ring-pho-brand text-md rounded-base w-full px-3 py-2 ring-1 transition-shadow duration-100 ease-linear outline-none ring-inset focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-base\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Clear({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Clear>) {\n return (\n <BaseCombobox.Clear\n className={cn(\n \"combobox-clear text-pho-secondary hover:text-pho-secondary-hover absolute right-2.5 flex cursor-pointer items-center [&>svg]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Trigger({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Trigger>) {\n return (\n <BaseCombobox.Trigger\n className={cn(\n \"text-pho-secondary hover:text-pho-secondary-hover absolute right-2.5 flex cursor-pointer items-center [&>svg]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Positioner({\n className,\n sideOffset = 6,\n ...props\n}: StyledProps<typeof BaseCombobox.Positioner>) {\n return (\n <BaseCombobox.Positioner\n sideOffset={sideOffset}\n className={cn(\"z-50 outline-none\", className)}\n {...props}\n />\n );\n}\n\nfunction Popup({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Popup>) {\n return (\n <BaseCombobox.Popup\n className={cn(\n \"bg-pho-primary text-pho-primary shadow-pho-lg ring-pho-secondary rounded-base w-[var(--anchor-width)] max-w-[var(--available-width)] origin-[var(--transform-origin)] p-1 ring-1 transition-[transform,opacity] duration-150 ease-out outline-none ring-inset\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction List({ className, ...props }: StyledProps<typeof BaseCombobox.List>) {\n return (\n <BaseCombobox.List\n className={cn(\n \"max-h-[min(20rem,var(--available-height))] overflow-y-auto overscroll-contain\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Empty({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Empty>) {\n return (\n <BaseCombobox.Empty\n className={cn(\n \"text-pho-description px-2.5 py-6 text-center text-base empty:m-0 empty:p-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Item({ className, ...props }: StyledProps<typeof BaseCombobox.Item>) {\n return (\n <BaseCombobox.Item\n className={cn(\n \"text-pho-secondary grid cursor-pointer grid-cols-[1rem_1fr] items-center gap-2 rounded-[calc(var(--radius-base)-4px)] py-1.5 pr-2.5 pl-2 text-base outline-none select-none\",\n \"data-[highlighted]:bg-pho-ghost-hover data-[highlighted]:text-pho-primary\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ItemIndicator({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.ItemIndicator>) {\n return (\n <BaseCombobox.ItemIndicator\n className={cn(\n \"text-pho-brand col-start-1 flex items-center [&>svg]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction GroupLabel({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.GroupLabel>) {\n return (\n <BaseCombobox.GroupLabel\n className={cn(\n \"text-pho-secondary px-2.5 py-1.5 text-xs font-medium\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Chips({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.Chips>) {\n return (\n <BaseCombobox.Chips\n className={cn(\n \"bg-pho-primary ring-pho-primary focus-within:ring-pho-brand rounded-base flex flex-wrap items-center gap-1.5 p-1.5 ring-1 ring-inset focus-within:ring-2\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Chip({ className, ...props }: StyledProps<typeof BaseCombobox.Chip>) {\n return (\n <BaseCombobox.Chip\n className={cn(\n // Keyboard-highlighted chip flips to the inverse chip surface.\n \"bg-pho-secondary text-pho-secondary data-[highlighted]:bg-pho-inverse data-[highlighted]:text-pho-inverse flex items-center gap-1 rounded-sm py-0.5 pr-1 pl-2 text-base\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction ChipRemove({\n className,\n ...props\n}: StyledProps<typeof BaseCombobox.ChipRemove>) {\n return (\n <BaseCombobox.ChipRemove\n className={cn(\n \"text-pho-secondary hover:text-pho-secondary-hover in-data-[highlighted]:text-pho-inverse flex cursor-pointer items-center rounded-sm [&>svg]:size-3.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Combobox built on Base UI `Combobox` — a text input that filters a list as\n * you type and commits to a value from it. Pass `items` to `Combobox.Root`;\n * `Combobox.List` takes a render function mapping each (filtered) item to a\n * `Combobox.Item`. Add `Combobox.Chips` for multi-select. For free-form text\n * with suggestions, use `Autocomplete`; for a small fixed set, use `Select`.\n */\nexport const Combobox = {\n Root,\n Value,\n InputGroup,\n Input,\n Trigger,\n Clear,\n Portal,\n Positioner,\n Popup,\n List,\n Collection,\n Empty,\n Item,\n ItemIndicator,\n Group,\n GroupLabel,\n Chips,\n Chip,\n ChipRemove,\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"createReactComponent-BqCmnqfX.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n outline: {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n },\n filled: {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n stroke: \"none\"\n }\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n","/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\n\nconst createReactComponent = (type, iconName, iconNamePascal, iconNode) => {\n const Component = forwardRef(\n ({ color = \"currentColor\", size = 24, stroke = 2, title, className, children, ...rest }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes[type],\n width: size,\n height: size,\n className: [`tabler-icon`, `tabler-icon-${iconName}`, className].join(\" \"),\n ...type === \"filled\" ? {\n fill: color\n } : {\n strokeWidth: stroke,\n stroke: color\n },\n ...rest\n },\n [\n title && createElement(\"title\", { key: \"svg-title\" }, title),\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n );\n Component.displayName = `${iconNamePascal}`;\n return Component;\n};\n\nexport { createReactComponent as default };\n//# sourceMappingURL=createReactComponent.mjs.map\n"],"x_google_ignoreList":[0,1],"mappings":";;AAOA,IAAI,IAAoB;AAAA,EACtB,SAAS;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AACF,GCjBM,IAAA,CAAwB,GAAM,GAAU,GAAgB,MAAa;AACzE,QAAM,IAAY,EAAA,CACf,EAAE,OAAA,IAAQ,gBAAgB,MAAA,IAAO,IAAI,QAAA,IAAS,GAAG,OAAA,GAAO,WAAA,GAAW,UAAA,GAAU,GAAG,EAAA,GAAQ,MAAQ,EAC/F,OACA;AAAA,IACE,KAAA;AAAA,IACA,GAAG,EAAkB,CAAA;AAAA,IACrB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,MAAC;AAAA,MAAe,eAAe,CAAA;AAAA,MAAY;AAAA,IAAS,EAAE,KAAK,GAAG;AAAA,IACzE,GAAG,MAAS,WAAW,EACrB,MAAM,EACR,IAAI;AAAA,MACF,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EACL,GACA;AAAA,IACE,KAAS,EAAc,SAAS,EAAE,KAAK,YAAY,GAAG,CAAK;AAAA,IAC3D,GAAG,EAAS,IAAA,CAAK,CAAC,GAAK,CAAA,MAAW,EAAc,GAAK,CAAK,CAAC;AAAA,IAC3D,GAAG,MAAM,QAAQ,CAAQ,IAAI,IAAW,CAAC,CAAQ;AAAA,EACnD,CACF,CACF;AACA,SAAA,EAAU,cAAc,GAAG,CAAA,IACpB;AACT"}
1
+ {"version":3,"file":"createReactComponent-BqCmnqfX.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/createReactComponent.mjs"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n outline: {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n },\n filled: {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\",\n stroke: \"none\"\n }\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.mjs';\n\nconst createReactComponent = (type, iconName, iconNamePascal, iconNode) => {\n const Component = forwardRef(\n ({ color = \"currentColor\", size = 24, stroke = 2, title, className, children, ...rest }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes[type],\n width: size,\n height: size,\n className: [`tabler-icon`, `tabler-icon-${iconName}`, className].join(\" \"),\n ...type === \"filled\" ? {\n fill: color\n } : {\n strokeWidth: stroke,\n stroke: color\n },\n ...rest\n },\n [\n title && createElement(\"title\", { key: \"svg-title\" }, title),\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n );\n Component.displayName = `${iconNamePascal}`;\n return Component;\n};\n\nexport { createReactComponent as default };\n//# sourceMappingURL=createReactComponent.mjs.map\n"],"x_google_ignoreList":[0,1],"mappings":";;AAOA,IAAI,IAAoB;AAAA,EACtB,SAAS;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,eAAe;AAAA,IACf,gBAAgB;AAAA,EAClB;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AACF,GCjBM,IAAA,CAAwB,GAAM,GAAU,GAAgB,MAAa;AACzE,QAAM,IAAY,EAAA,CACf,EAAE,OAAA,IAAQ,gBAAgB,MAAA,IAAO,IAAI,QAAA,IAAS,GAAG,OAAA,GAAO,WAAA,GAAW,UAAA,GAAU,GAAG,EAAA,GAAQ,MAAQ,EAC/F,OACA;AAAA,IACE,KAAA;AAAA,IACA,GAAG,EAAkB,CAAA;AAAA,IACrB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,MAAC;AAAA,MAAe,eAAe,CAAA;AAAA,MAAY;AAAA,IAAS,EAAE,KAAK,GAAG;AAAA,IACzE,GAAG,MAAS,WAAW,EACrB,MAAM,EACR,IAAI;AAAA,MACF,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EACL,GACA;AAAA,IACE,KAAS,EAAc,SAAS,EAAE,KAAK,YAAY,GAAG,CAAK;AAAA,IAC3D,GAAG,EAAS,IAAA,CAAK,CAAC,GAAK,CAAA,MAAW,EAAc,GAAK,CAAK,CAAC;AAAA,IAC3D,GAAG,MAAM,QAAQ,CAAQ,IAAI,IAAW,CAAC,CAAQ;AAAA,EACnD,CACF,CACF;AACA,SAAA,EAAU,cAAc,GAAG,CAAA,IACpB;AACT"}
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { t as m } from "./cn-DTiB6ek_.js";
3
- import { a as E } from "./button-X5wsWvRa.js";
4
- import { t as P } from "./close-button-xadxp0j8.js";
2
+ import { t as m } from "./cn-ChIgwEl3.js";
3
+ import { a as E } from "./button-BmhyLgy5.js";
4
+ import { t as P } from "./close-button-GvqWbLl0.js";
5
5
  import { t as I } from "./animated-height-C2eQstGy.js";
6
- import { t as p } from "./scroll-area-CNZVwe7v.js";
6
+ import { t as p } from "./scroll-area-Cw4JFqNG.js";
7
7
  import { createContext as _, useCallback as F, useContext as D, useEffect as j, useMemo as O, useRef as C, useState as T } from "react";
8
8
  import { jsx as e, jsxs as o } from "react/jsx-runtime";
9
9
  import { Dialog as f } from "@base-ui/react/dialog";
@@ -259,4 +259,4 @@ export {
259
259
  re as t
260
260
  };
261
261
 
262
- //# sourceMappingURL=dialog-BC23YRUq.js.map
262
+ //# sourceMappingURL=dialog-DtFO7oy0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialog-BC23YRUq.js","names":[],"sources":["../../src/components/dialog/dialog.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type ElementType,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from \"react\";\nimport { Dialog as BaseDialog } from \"@base-ui/react/dialog\";\nimport { AnimatedHeight } from \"../../utils/animated-height\";\nimport { cn } from \"../../utils/cn\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Button, type ButtonProps } from \"../button/button\";\nimport { CloseButton } from \"../button/close-button\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\n/* ========================== Async pending context ========================== */\n\n/** Imperative actions exposed by Base UI's `actionsRef`. */\ninterface RootActions {\n unmount: () => void;\n close: () => void;\n}\n\ninterface DialogPendingContextValue {\n /** True while a `Dialog.Action` promise is in flight. */\n pending: boolean;\n beginPending: () => void;\n endPending: () => void;\n /** Close the dialog imperatively (used by `Dialog.Action` on resolve). */\n close: () => void;\n}\n\nconst DialogPendingContext = createContext<DialogPendingContextValue | null>(\n null,\n);\n\n/**\n * Whether the surrounding dialog has a `Dialog.Action` promise in flight —\n * use it to disable secondary actions (Cancel etc.) while work is pending.\n * Returns `false` outside a `Dialog.Root`.\n */\nexport function useDialogPending(): boolean {\n return useContext(DialogPendingContext)?.pending ?? false;\n}\n\ntype RootProps = ComponentProps<typeof BaseDialog.Root>;\n\n/**\n * `Dialog.Root` with async awareness: while a `Dialog.Action` promise is\n * pending, every close request (outside press, Escape, `Dialog.Close`) is\n * cancelled so the dialog stays open until the work settles. Props pass\n * through to Base UI's `Dialog.Root` unchanged.\n */\nfunction Root({ onOpenChange, actionsRef, ...props }: RootProps) {\n const [pending, setPending] = useState(false);\n // Guard reads a ref so a resolve → close() in the same tick isn't blocked\n // by a not-yet-flushed state update.\n const pendingRef = useRef(false);\n const internalActionsRef = useRef<RootActions | null>(null);\n\n // Keep a caller-supplied actionsRef working alongside our internal one.\n useEffect(() => {\n if (!actionsRef) return;\n actionsRef.current = internalActionsRef.current;\n return () => {\n actionsRef.current = null;\n };\n }, [actionsRef]);\n\n const handleOpenChange = useCallback<NonNullable<RootProps[\"onOpenChange\"]>>(\n (open, eventDetails) => {\n if (!open && pendingRef.current) {\n eventDetails.cancel();\n return;\n }\n onOpenChange?.(open, eventDetails);\n },\n [onOpenChange],\n );\n\n const contextValue = useMemo<DialogPendingContextValue>(\n () => ({\n pending,\n beginPending: () => {\n pendingRef.current = true;\n setPending(true);\n },\n endPending: () => {\n pendingRef.current = false;\n setPending(false);\n },\n close: () => internalActionsRef.current?.close(),\n }),\n [pending],\n );\n\n return (\n <DialogPendingContext.Provider value={contextValue}>\n <BaseDialog.Root\n actionsRef={internalActionsRef}\n onOpenChange={handleOpenChange}\n {...props}\n />\n </DialogPendingContext.Provider>\n );\n}\n\nconst Trigger = BaseDialog.Trigger;\nconst Portal = BaseDialog.Portal;\nconst Close = BaseDialog.Close;\n\n/* ============================== Dialog.Action ============================== */\n\nexport interface DialogActionProps extends Omit<ButtonProps, \"onClick\"> {\n /**\n * Confirm handler. Return a promise to keep the dialog open while it runs:\n * the button shows `loading`, all dismissal is locked, and the dialog\n * closes when the promise resolves. On rejection the dialog stays open —\n * surface errors inside the handler. A non-promise return closes\n * immediately, like `Dialog.Close`.\n */\n onClick?: (\n event: ReactMouseEvent<HTMLButtonElement>,\n ) => void | Promise<unknown>;\n}\n\nfunction isThenable(value: unknown): value is Promise<unknown> {\n return (\n value != null && typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * The confirm button of an action row, with native promise support — a\n * `Button` that runs its (possibly async) `onClick` and closes the dialog\n * when the work settles successfully.\n */\nfunction Action({ onClick, loading, disabled, ...props }: DialogActionProps) {\n const pendingContext = useContext(DialogPendingContext);\n const [busy, setBusy] = useState(false);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n function handleClick(event: ReactMouseEvent<HTMLButtonElement>) {\n if (busy || loading) return;\n const result = onClick?.(event);\n if (!isThenable(result)) {\n pendingContext?.close();\n return;\n }\n setBusy(true);\n pendingContext?.beginPending();\n result.then(\n () => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n pendingContext?.close();\n },\n (error: unknown) => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.error(\"Dialog.Action: async onClick rejected —\", error);\n }\n },\n );\n }\n\n const inert = busy || loading;\n return (\n <Button\n {...props}\n disabled={disabled || inert}\n loading={inert}\n onClick={handleClick}\n />\n );\n}\n\nfunction Backdrop({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Backdrop>) {\n return (\n <BaseDialog.Backdrop\n className={cn(\n \"bg-pho-overlay fixed inset-0 z-50 transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Popup({ className, ...props }: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n // Floating layer: bg-pho-primary + border-pho-secondary hairline, elevation kept.\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed top-1/2 left-1/2 z-50 w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border outline-none\",\n // Global height cap — the inset panel's footprint (inset-4 /\n // sm:inset-8). A flex column so the body region can shrink and\n // scroll while header and actions stay pinned.\n \"flex max-h-[calc(100dvh-2rem)] flex-col sm:max-h-[calc(100dvh-4rem)]\",\n // Opacity + scale only — leave translate centering alone (no transition-all).\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Title({ className, ...props }: StyledProps<typeof BaseDialog.Title>) {\n return (\n <BaseDialog.Title\n className={cn(\n \"text-pho-primary font-display text-display-sm font-medium text-balance\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Description({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Description>) {\n return (\n <BaseDialog.Description\n className={cn(\n \"text-pho-description text-display-xs font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Header icon chrome: secondary ink, a hair of extra air before the title.\n * Panel dialogs use 32px (`size-8`); fullscreen gates step up to 48px\n * (`size-12`) so the glyph reads at viewport scale.\n */\nfunction DialogHeaderIcon({\n children,\n size = \"md\",\n}: {\n children: ReactNode;\n size?: \"md\" | \"lg\";\n}) {\n return (\n <span\n aria-hidden\n className={cn(\n \"text-pho-secondary mb-1\",\n size === \"lg\" ? \"[&>svg]:size-12\" : \"[&>svg]:size-8\",\n )}\n >\n {children}\n </span>\n );\n}\n\ninterface ContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — typically a Tabler outline icon.\n * Rendered aria-hidden in secondary ink at 32px (`[&>svg]:size-8`). Pass a\n * styled node to override the ink; the size is owned by the slot.\n */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Consequence bullets rendered as a list at the top of the body — one item\n * per outcome (what is deleted, what survives, who loses access). Use on\n * destructive confirms where the one-line description undersells the\n * impact; keep each item to a single short sentence. Wrap the load-bearing\n * figure in `<strong>` (\"<strong>3 members</strong> lose access\") — the\n * list styles it (secondary ink, medium weight); no classes needed.\n */\n consequences?: ReactNode[];\n /**\n * Final cautionary line under `consequences` — error ink at description\n * size (e.g. \"It cannot be undone. Please be certain.\"). Reserve it for\n * irreversible actions; keep it short.\n */\n warning?: ReactNode;\n /**\n * Footer action row (Cancel / Confirm, etc.). Iron rule: when `actions` is\n * set, the header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience panel: renders the portal, backdrop, and styled popup with an\n * optional header (title/description + close) and optional action row. For\n * full control, compose the parts directly (`Dialog.Portal` /\n * `Dialog.Backdrop` / `Dialog.Popup`).\n */\nfunction Content({\n icon,\n title,\n description,\n consequences,\n warning,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: ContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n const hasConsequences = consequences != null && consequences.length > 0;\n // The scrollable middle region — actions stay pinned below it.\n const hasScrollBody = hasConsequences || warning != null || children != null;\n\n return (\n <Portal>\n <Backdrop />\n <Popup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n // Title row height = title only. Close is out of flow, centered\n // on the row, and may paint outside it (no clip, no stretch).\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {hasScrollBody && (\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"flex flex-col gap-5 px-6 py-5\">\n {hasConsequences && (\n <ul className=\"text-pho-description text-md [&_strong]:text-pho-secondary space-y-1 [&_strong]:font-medium\">\n {consequences.map((item, index) => (\n // Hand-drawn marker: a 4px dot on the first line's center —\n // quieter than the browser disc, ink tracks the text.\n <li\n key={index}\n className=\"relative pl-4 before:absolute before:top-2.5 before:left-1 before:size-1 before:rounded-full before:bg-current\"\n >\n {item}\n </li>\n ))}\n </ul>\n )}\n {warning != null && (\n <p className=\"text-pho-error text-display-xs font-medium\">\n {warning}\n </p>\n )}\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n )}\n {actions != null && (\n <div\n className={cn(\n \"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\",\n !hasScrollBody && \"pt-5\",\n )}\n >\n {actions}\n </div>\n )}\n </Popup>\n </Portal>\n );\n}\n\n/* =========================== Dialog.InsetContent =========================== */\n\n/**\n * Near-fullscreen popup — the viewport minus a breathing ring, floating over\n * a backdrop (the page stays visible through the gap, so it dims like any\n * floating layer). Still a card: border, elevation, rounded corners; the\n * scale gesture stays but shrinks to 98% — at this size 95% reads like a jump.\n */\nfunction InsetPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed inset-4 z-50 flex flex-col overflow-hidden rounded-lg border outline-none sm:inset-8\",\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface InsetContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /** Decorative icon above the title — same treatment as `Content`. */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Bottom action row. Iron rule as `Content`: when `actions` is set, the\n * header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience near-fullscreen panel: header pinned on top, body filling and\n * scrolling on its own, optional action row pinned at the bottom. Sits\n * between `Content` (a focused card) and `FullscreenContent` (a page\n * takeover): use it for roomy working surfaces — pickers, editors, previews —\n * that still want the page peeking through an edge.\n */\nfunction InsetContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: InsetContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n\n return (\n <Portal>\n <Backdrop />\n <InsetPopup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"px-6 py-5\">\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n {actions != null && (\n <div className=\"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\">\n {actions}\n </div>\n )}\n </InsetPopup>\n </Portal>\n );\n}\n\n/* ========================= Dialog.FullscreenContent ======================== */\n\n/**\n * Full-viewport popup — a page-surface takeover instead of a floating card.\n * No backdrop: the popup itself is the layer. Fade only; scale is a floating-\n * card gesture and reads wrong at viewport size.\n */\nfunction FullscreenPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"bg-pho-page fixed inset-0 z-50 overflow-y-auto outline-none\",\n \"transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface FullscreenContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — same chrome as `Content`, but 48px\n * (`size-12`) for viewport-scale gates.\n */\n icon?: ReactNode;\n /** Heading of the takeover. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Action row under the body. Iron rule as `Content`: when `actions` is set,\n * the corner close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Corner close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n /**\n * Classes on the viewport-centering frame (the `min-h-full` flex host).\n * Use to drop the default optical `pb-20` when the stack grows (e.g. a\n * captcha) so true center stays put: `frameClassName=\"pb-6\"`.\n */\n frameClassName?: string;\n children?: ReactNode;\n}\n\n/**\n * Convenience full-screen panel: the whole viewport becomes the dialog, with\n * a centered column at the standalone-flow width (28rem — the same measure as\n * onboarding / invite cards). Column height follows its content through\n * `AnimatedHeight` (same spring as the Card shell), so step swaps — phone →\n * OTP → captcha — glide instead of jumping. Use for gates the visitor must\n * deal with before the page behind makes sense (e.g. binding a phone number);\n * prefer `Content` for everything conversational.\n */\nfunction FullscreenContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n frameClassName,\n children,\n className,\n ...props\n}: FullscreenContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a corner X.\n const showCloseButton = actions == null && showClose;\n\n return (\n <Portal>\n <FullscreenPopup className={className} {...props}>\n {showCloseButton && (\n <Close\n render={<CloseButton className=\"fixed top-4 right-4 z-10\" />}\n />\n )}\n {/* Default `pb-20` optically lifts the column above true center. */}\n <div\n className={cn(\n \"flex min-h-full items-center justify-center px-6 pt-6 pb-20\",\n frameClassName,\n )}\n >\n {/* Width stays on the outer host; AnimatedHeight measures the\n section stack and springs its own height on content changes. */}\n <div className=\"w-full max-w-md\">\n <AnimatedHeight className=\"flex flex-col gap-5\">\n {(icon || title || description) && (\n <div className=\"flex flex-col gap-1\">\n {icon && (\n <DialogHeaderIcon size=\"lg\">{icon}</DialogHeaderIcon>\n )}\n {title && <Title>{title}</Title>}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {children}\n {actions != null && (\n <div className=\"flex items-center justify-end gap-2\">\n {actions}\n </div>\n )}\n </AnimatedHeight>\n </div>\n </div>\n </FullscreenPopup>\n </Portal>\n );\n}\n\n/**\n * Modal dialog built on Base UI `Dialog`. Controlled or uncontrolled via\n * `Dialog.Root` (`open` / `onOpenChange` / `defaultOpen`). `Dialog.Action`\n * adds native promise support: an async confirm keeps the dialog open and\n * undismissable until the work resolves.\n */\nexport const Dialog = {\n Root,\n Trigger,\n Portal,\n Backdrop,\n Popup,\n InsetPopup,\n FullscreenPopup,\n Title,\n Description,\n Close,\n Action,\n Content,\n InsetContent,\n FullscreenContent,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"dialog-DtFO7oy0.js","names":[],"sources":["../../src/components/dialog/dialog.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type ElementType,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from \"react\";\nimport { Dialog as BaseDialog } from \"@base-ui/react/dialog\";\nimport { AnimatedHeight } from \"../../utils/animated-height\";\nimport { cn } from \"../../utils/cn\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Button, type ButtonProps } from \"../button/button\";\nimport { CloseButton } from \"../button/close-button\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\n/* ========================== Async pending context ========================== */\n\n/** Imperative actions exposed by Base UI's `actionsRef`. */\ninterface RootActions {\n unmount: () => void;\n close: () => void;\n}\n\ninterface DialogPendingContextValue {\n /** True while a `Dialog.Action` promise is in flight. */\n pending: boolean;\n beginPending: () => void;\n endPending: () => void;\n /** Close the dialog imperatively (used by `Dialog.Action` on resolve). */\n close: () => void;\n}\n\nconst DialogPendingContext = createContext<DialogPendingContextValue | null>(\n null,\n);\n\n/**\n * Whether the surrounding dialog has a `Dialog.Action` promise in flight —\n * use it to disable secondary actions (Cancel etc.) while work is pending.\n * Returns `false` outside a `Dialog.Root`.\n */\nexport function useDialogPending(): boolean {\n return useContext(DialogPendingContext)?.pending ?? false;\n}\n\ntype RootProps = ComponentProps<typeof BaseDialog.Root>;\n\n/**\n * `Dialog.Root` with async awareness: while a `Dialog.Action` promise is\n * pending, every close request (outside press, Escape, `Dialog.Close`) is\n * cancelled so the dialog stays open until the work settles. Props pass\n * through to Base UI's `Dialog.Root` unchanged.\n */\nfunction Root({ onOpenChange, actionsRef, ...props }: RootProps) {\n const [pending, setPending] = useState(false);\n // Guard reads a ref so a resolve → close() in the same tick isn't blocked\n // by a not-yet-flushed state update.\n const pendingRef = useRef(false);\n const internalActionsRef = useRef<RootActions | null>(null);\n\n // Keep a caller-supplied actionsRef working alongside our internal one.\n useEffect(() => {\n if (!actionsRef) return;\n actionsRef.current = internalActionsRef.current;\n return () => {\n actionsRef.current = null;\n };\n }, [actionsRef]);\n\n const handleOpenChange = useCallback<NonNullable<RootProps[\"onOpenChange\"]>>(\n (open, eventDetails) => {\n if (!open && pendingRef.current) {\n eventDetails.cancel();\n return;\n }\n onOpenChange?.(open, eventDetails);\n },\n [onOpenChange],\n );\n\n const contextValue = useMemo<DialogPendingContextValue>(\n () => ({\n pending,\n beginPending: () => {\n pendingRef.current = true;\n setPending(true);\n },\n endPending: () => {\n pendingRef.current = false;\n setPending(false);\n },\n close: () => internalActionsRef.current?.close(),\n }),\n [pending],\n );\n\n return (\n <DialogPendingContext.Provider value={contextValue}>\n <BaseDialog.Root\n actionsRef={internalActionsRef}\n onOpenChange={handleOpenChange}\n {...props}\n />\n </DialogPendingContext.Provider>\n );\n}\n\nconst Trigger = BaseDialog.Trigger;\nconst Portal = BaseDialog.Portal;\nconst Close = BaseDialog.Close;\n\n/* ============================== Dialog.Action ============================== */\n\nexport interface DialogActionProps extends Omit<ButtonProps, \"onClick\"> {\n /**\n * Confirm handler. Return a promise to keep the dialog open while it runs:\n * the button shows `loading`, all dismissal is locked, and the dialog\n * closes when the promise resolves. On rejection the dialog stays open —\n * surface errors inside the handler. A non-promise return closes\n * immediately, like `Dialog.Close`.\n */\n onClick?: (\n event: ReactMouseEvent<HTMLButtonElement>,\n ) => void | Promise<unknown>;\n}\n\nfunction isThenable(value: unknown): value is Promise<unknown> {\n return (\n value != null && typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * The confirm button of an action row, with native promise support — a\n * `Button` that runs its (possibly async) `onClick` and closes the dialog\n * when the work settles successfully.\n */\nfunction Action({ onClick, loading, disabled, ...props }: DialogActionProps) {\n const pendingContext = useContext(DialogPendingContext);\n const [busy, setBusy] = useState(false);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n function handleClick(event: ReactMouseEvent<HTMLButtonElement>) {\n if (busy || loading) return;\n const result = onClick?.(event);\n if (!isThenable(result)) {\n pendingContext?.close();\n return;\n }\n setBusy(true);\n pendingContext?.beginPending();\n result.then(\n () => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n pendingContext?.close();\n },\n (error: unknown) => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.error(\"Dialog.Action: async onClick rejected —\", error);\n }\n },\n );\n }\n\n const inert = busy || loading;\n return (\n <Button\n {...props}\n disabled={disabled || inert}\n loading={inert}\n onClick={handleClick}\n />\n );\n}\n\nfunction Backdrop({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Backdrop>) {\n return (\n <BaseDialog.Backdrop\n className={cn(\n \"bg-pho-overlay fixed inset-0 z-50 transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Popup({ className, ...props }: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n // Floating layer: bg-pho-primary + border-pho-secondary hairline, elevation kept.\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed top-1/2 left-1/2 z-50 w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border outline-none\",\n // Global height cap — the inset panel's footprint (inset-4 /\n // sm:inset-8). A flex column so the body region can shrink and\n // scroll while header and actions stay pinned.\n \"flex max-h-[calc(100dvh-2rem)] flex-col sm:max-h-[calc(100dvh-4rem)]\",\n // Opacity + scale only — leave translate centering alone (no transition-all).\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Title({ className, ...props }: StyledProps<typeof BaseDialog.Title>) {\n return (\n <BaseDialog.Title\n className={cn(\n \"text-pho-primary font-display text-display-sm font-medium text-balance\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Description({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Description>) {\n return (\n <BaseDialog.Description\n className={cn(\n \"text-pho-description text-display-xs font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Header icon chrome: secondary ink, a hair of extra air before the title.\n * Panel dialogs use 32px (`size-8`); fullscreen gates step up to 48px\n * (`size-12`) so the glyph reads at viewport scale.\n */\nfunction DialogHeaderIcon({\n children,\n size = \"md\",\n}: {\n children: ReactNode;\n size?: \"md\" | \"lg\";\n}) {\n return (\n <span\n aria-hidden\n className={cn(\n \"text-pho-secondary mb-1\",\n size === \"lg\" ? \"[&>svg]:size-12\" : \"[&>svg]:size-8\",\n )}\n >\n {children}\n </span>\n );\n}\n\ninterface ContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — typically a Tabler outline icon.\n * Rendered aria-hidden in secondary ink at 32px (`[&>svg]:size-8`). Pass a\n * styled node to override the ink; the size is owned by the slot.\n */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Consequence bullets rendered as a list at the top of the body — one item\n * per outcome (what is deleted, what survives, who loses access). Use on\n * destructive confirms where the one-line description undersells the\n * impact; keep each item to a single short sentence. Wrap the load-bearing\n * figure in `<strong>` (\"<strong>3 members</strong> lose access\") — the\n * list styles it (secondary ink, medium weight); no classes needed.\n */\n consequences?: ReactNode[];\n /**\n * Final cautionary line under `consequences` — error ink at description\n * size (e.g. \"It cannot be undone. Please be certain.\"). Reserve it for\n * irreversible actions; keep it short.\n */\n warning?: ReactNode;\n /**\n * Footer action row (Cancel / Confirm, etc.). Iron rule: when `actions` is\n * set, the header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience panel: renders the portal, backdrop, and styled popup with an\n * optional header (title/description + close) and optional action row. For\n * full control, compose the parts directly (`Dialog.Portal` /\n * `Dialog.Backdrop` / `Dialog.Popup`).\n */\nfunction Content({\n icon,\n title,\n description,\n consequences,\n warning,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: ContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n const hasConsequences = consequences != null && consequences.length > 0;\n // The scrollable middle region — actions stay pinned below it.\n const hasScrollBody = hasConsequences || warning != null || children != null;\n\n return (\n <Portal>\n <Backdrop />\n <Popup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n // Title row height = title only. Close is out of flow, centered\n // on the row, and may paint outside it (no clip, no stretch).\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {hasScrollBody && (\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"flex flex-col gap-5 px-6 py-5\">\n {hasConsequences && (\n <ul className=\"text-pho-description text-md [&_strong]:text-pho-secondary space-y-1 [&_strong]:font-medium\">\n {consequences.map((item, index) => (\n // Hand-drawn marker: a 4px dot on the first line's center —\n // quieter than the browser disc, ink tracks the text.\n <li\n key={index}\n className=\"relative pl-4 before:absolute before:top-2.5 before:left-1 before:size-1 before:rounded-full before:bg-current\"\n >\n {item}\n </li>\n ))}\n </ul>\n )}\n {warning != null && (\n <p className=\"text-pho-error text-display-xs font-medium\">\n {warning}\n </p>\n )}\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n )}\n {actions != null && (\n <div\n className={cn(\n \"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\",\n !hasScrollBody && \"pt-5\",\n )}\n >\n {actions}\n </div>\n )}\n </Popup>\n </Portal>\n );\n}\n\n/* =========================== Dialog.InsetContent =========================== */\n\n/**\n * Near-fullscreen popup — the viewport minus a breathing ring, floating over\n * a backdrop (the page stays visible through the gap, so it dims like any\n * floating layer). Still a card: border, elevation, rounded corners; the\n * scale gesture stays but shrinks to 98% — at this size 95% reads like a jump.\n */\nfunction InsetPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed inset-4 z-50 flex flex-col overflow-hidden rounded-lg border outline-none sm:inset-8\",\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface InsetContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /** Decorative icon above the title — same treatment as `Content`. */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Bottom action row. Iron rule as `Content`: when `actions` is set, the\n * header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience near-fullscreen panel: header pinned on top, body filling and\n * scrolling on its own, optional action row pinned at the bottom. Sits\n * between `Content` (a focused card) and `FullscreenContent` (a page\n * takeover): use it for roomy working surfaces — pickers, editors, previews —\n * that still want the page peeking through an edge.\n */\nfunction InsetContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: InsetContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n\n return (\n <Portal>\n <Backdrop />\n <InsetPopup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"px-6 py-5\">\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n {actions != null && (\n <div className=\"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\">\n {actions}\n </div>\n )}\n </InsetPopup>\n </Portal>\n );\n}\n\n/* ========================= Dialog.FullscreenContent ======================== */\n\n/**\n * Full-viewport popup — a page-surface takeover instead of a floating card.\n * No backdrop: the popup itself is the layer. Fade only; scale is a floating-\n * card gesture and reads wrong at viewport size.\n */\nfunction FullscreenPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"bg-pho-page fixed inset-0 z-50 overflow-y-auto outline-none\",\n \"transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface FullscreenContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — same chrome as `Content`, but 48px\n * (`size-12`) for viewport-scale gates.\n */\n icon?: ReactNode;\n /** Heading of the takeover. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Action row under the body. Iron rule as `Content`: when `actions` is set,\n * the corner close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Corner close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n /**\n * Classes on the viewport-centering frame (the `min-h-full` flex host).\n * Use to drop the default optical `pb-20` when the stack grows (e.g. a\n * captcha) so true center stays put: `frameClassName=\"pb-6\"`.\n */\n frameClassName?: string;\n children?: ReactNode;\n}\n\n/**\n * Convenience full-screen panel: the whole viewport becomes the dialog, with\n * a centered column at the standalone-flow width (28rem — the same measure as\n * onboarding / invite cards). Column height follows its content through\n * `AnimatedHeight` (same spring as the Card shell), so step swaps — phone →\n * OTP → captcha — glide instead of jumping. Use for gates the visitor must\n * deal with before the page behind makes sense (e.g. binding a phone number);\n * prefer `Content` for everything conversational.\n */\nfunction FullscreenContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n frameClassName,\n children,\n className,\n ...props\n}: FullscreenContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a corner X.\n const showCloseButton = actions == null && showClose;\n\n return (\n <Portal>\n <FullscreenPopup className={className} {...props}>\n {showCloseButton && (\n <Close\n render={<CloseButton className=\"fixed top-4 right-4 z-10\" />}\n />\n )}\n {/* Default `pb-20` optically lifts the column above true center. */}\n <div\n className={cn(\n \"flex min-h-full items-center justify-center px-6 pt-6 pb-20\",\n frameClassName,\n )}\n >\n {/* Width stays on the outer host; AnimatedHeight measures the\n section stack and springs its own height on content changes. */}\n <div className=\"w-full max-w-md\">\n <AnimatedHeight className=\"flex flex-col gap-5\">\n {(icon || title || description) && (\n <div className=\"flex flex-col gap-1\">\n {icon && (\n <DialogHeaderIcon size=\"lg\">{icon}</DialogHeaderIcon>\n )}\n {title && <Title>{title}</Title>}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {children}\n {actions != null && (\n <div className=\"flex items-center justify-end gap-2\">\n {actions}\n </div>\n )}\n </AnimatedHeight>\n </div>\n </div>\n </FullscreenPopup>\n </Portal>\n );\n}\n\n/**\n * Modal dialog built on Base UI `Dialog`. Controlled or uncontrolled via\n * `Dialog.Root` (`open` / `onOpenChange` / `defaultOpen`). `Dialog.Action`\n * adds native promise support: an async confirm keeps the dialog open and\n * undismissable until the work resolves.\n */\nexport const Dialog = {\n Root,\n Trigger,\n Portal,\n Backdrop,\n Popup,\n InsetPopup,\n FullscreenPopup,\n Title,\n Description,\n Close,\n Action,\n Content,\n InsetContent,\n FullscreenContent,\n};\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { t as h } from "./cn-DTiB6ek_.js";
3
- import { a as x, o as R } from "./button-X5wsWvRa.js";
2
+ import { t as h } from "./cn-ChIgwEl3.js";
3
+ import { a as x, o as R } from "./button-BmhyLgy5.js";
4
4
  import { t as C } from "./createReactComponent-BqCmnqfX.js";
5
5
  import { t as S } from "./IconInfoCircle-L0zfhg7R.js";
6
6
  import { t as g } from "./IconAlertCircleFilled-VxKU8TYK.js";
7
- import { i as _ } from "./status-view-CcbctPqR.js";
8
- import { t as l } from "./popover-EL1SE1kj.js";
7
+ import { i as _ } from "./status-view-C8tabjDu.js";
8
+ import { t as l } from "./popover-BhBJO346.js";
9
9
  import { useEffect as A, useRef as P, useState as L } from "react";
10
10
  import { Fragment as c, jsx as n, jsxs as s } from "react/jsx-runtime";
11
11
  var k = [
@@ -141,11 +141,12 @@ function O({ copy: t }) {
141
141
  const { problem: e, requestId: r } = t;
142
142
  if (e == null && r == null) return null;
143
143
  let i = null;
144
- if (e != null) if (e.code) i = `${e.status} ${e.code}`;
145
- else {
146
- const o = v(e.status, e.title);
147
- i = o ? `${e.status} ${o}` : String(e.status);
148
- }
144
+ if (e != null)
145
+ if (e.code) i = `${e.status} ${e.code}`;
146
+ else {
147
+ const o = v(e.status, e.title);
148
+ i = o ? `${e.status} ${o}` : String(e.status);
149
+ }
149
150
  return /* @__PURE__ */ s(l.Root, { children: [/* @__PURE__ */ n(l.Trigger, {
150
151
  openOnHover: !0,
151
152
  delay: 150,
@@ -248,4 +249,4 @@ export {
248
249
  M as t
249
250
  };
250
251
 
251
- //# sourceMappingURL=error-DR6G2LmG.js.map
252
+ //# sourceMappingURL=error-Da7P5WZi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-DR6G2LmG.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertTriangle.mjs","../../src/components/error/problem.ts","../../src/components/error/error.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 9v4\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M12 16h.01\", \"key\": \"svg-2\" }]];\nconst IconAlertTriangle = createReactComponent(\"outline\", \"alert-triangle\", \"AlertTriangle\", __iconNode);\n\nexport { __iconNode, IconAlertTriangle as default };\n//# sourceMappingURL=IconAlertTriangle.mjs.map\n","/**\n * Client-side mirror of the `@photon-hq/error` response contract — the\n * RFC 9457 Problem Details body every Photon service returns for 4xx / 5xx.\n * Machine logic branches on `code`; `title` / `detail` / `remediation` are\n * the human-readable copy, already reviewed server-side and safe to render.\n *\n * Fetch layers may also hand us a thin status-only shape when the response\n * was not ok but the body was not a contract problem — `title` + `status`\n * still count so the UI can disclose the HTTP code we already know.\n */\n\nexport interface ProblemRemediation {\n /** What the user can do about it — a full sentence. */\n action?: string;\n /** Docs URL explaining the problem. */\n documentation?: string;\n}\n\nexport interface Problem {\n /** Stable machine-readable key (`RATE_LIMITED`) — the field to branch on. */\n code?: string;\n /** Human summary of the problem type (\"Too Many Requests\"). */\n title: string;\n /** HTTP status (4xx / 5xx). */\n status: number;\n /** Problem type URI (`urn:photon:problem:*` or an https URL). */\n type?: string;\n /** Occurrence-specific human sentence. */\n detail?: string;\n /** Correlation id for support (`X-Request-ID`). */\n requestId?: string;\n remediation?: ProblemRemediation;\n /** RFC 9457 extensions (`issues`, `actualVersion`, …). */\n [extension: string]: unknown;\n}\n\n/** Structural check: `title` + a 4xx/5xx status. `code` is optional. */\nexport function isProblem(value: unknown): value is Problem {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.title === \"string\" &&\n typeof v.status === \"number\" &&\n Number.isInteger(v.status) &&\n v.status >= 400 &&\n v.status <= 599 &&\n (v.code === undefined || typeof v.code === \"string\")\n );\n}\n\n/**\n * Find the problem a caught value carries — the value itself, one typed onto\n * an error as a `problem` field (dashboard's `ApiError` shape), or one\n * wrapped in an `Error` `cause` chain (how fetch layers usually rethrow a\n * parsed body). Returns `null` when there is none.\n */\nexport function parseProblem(error: unknown): Problem | null {\n let current: unknown = error;\n for (\n let depth = 0;\n depth < 8 && typeof current === \"object\" && current !== null;\n depth++\n ) {\n if (isProblem(current)) return current;\n const carried = (current as { problem?: unknown }).problem;\n if (isProblem(carried)) return carried;\n current = (current as { cause?: unknown }).cause;\n }\n return null;\n}\n\nexport interface ErrorDescription {\n /** Short name of the failure — the problem `title`, or a generic fallback. */\n title: string;\n /** Sentence(s) to show — `detail` and `remediation.action` joined. */\n description?: string;\n /** Docs URL from `remediation.documentation`. */\n documentation?: string;\n /** Correlation id for support. */\n requestId?: string;\n /** The matched problem, when the input carried one. */\n problem?: Problem;\n}\n\n/**\n * Anything that isn't a problem renders as this — raw `Error` messages are\n * not contract copy and never shown (the same fail-closed stance as the\n * server side of `@photon-hq/error`). Always a full sentence (trailing\n * period).\n */\nexport const GENERIC_ERROR_TITLE = \"Something went wrong.\";\n\n/** Standard reason phrases for statuses we commonly surface without a body. */\nconst HTTP_REASON_PHRASE: Record<number, string> = {\n 400: \"Bad Request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not Found\",\n 408: \"Request Timeout\",\n 409: \"Conflict\",\n 410: \"Gone\",\n 413: \"Payload Too Large\",\n 415: \"Unsupported Media Type\",\n 422: \"Unprocessable Entity\",\n 429: \"Too Many Requests\",\n 500: \"Internal Server Error\",\n 501: \"Not Implemented\",\n 502: \"Bad Gateway\",\n 503: \"Service Unavailable\",\n 504: \"Gateway Timeout\",\n};\n\n/** One-sentence explanations when the server gave a status but no problem copy. */\nconst HTTP_STATUS_EXPLANATION: Record<number, string> = {\n 400: \"The request was malformed or incomplete.\",\n 401: \"You need to sign in again.\",\n 403: \"You don't have permission to do that.\",\n 404: \"The requested resource was not found.\",\n 408: \"The request timed out before the server responded.\",\n 409: \"The request conflicts with the current state.\",\n 410: \"That resource is no longer available.\",\n 413: \"The request was too large for the server to accept.\",\n 415: \"That media type isn't supported.\",\n 422: \"The request was understood but couldn't be processed.\",\n 429: \"Request rate limit exceeded. Wait a moment before trying again.\",\n 500: \"The server hit an unexpected error.\",\n 501: \"The server doesn't support that operation.\",\n 502: \"The gateway got an invalid response from an upstream server.\",\n 503: \"The service is temporarily unavailable.\",\n 504: \"The gateway timed out waiting for an upstream server.\",\n};\n\nfunction hasContractCode(problem: Problem): boolean {\n return typeof problem.code === \"string\" && problem.code !== \"\";\n}\n\n/** Reason phrase for a status — map first, then a non-generic `problem.title`. */\nexport function httpReasonPhrase(\n status: number,\n fallbackTitle?: string,\n): string | undefined {\n if (HTTP_REASON_PHRASE[status]) return HTTP_REASON_PHRASE[status];\n if (\n fallbackTitle &&\n fallbackTitle !== GENERIC_ERROR_TITLE &&\n fallbackTitle !== \"Request failed\"\n ) {\n return fallbackTitle.replace(/\\.$/, \"\");\n }\n return undefined;\n}\n\n/** Human sentence for a bare HTTP status, when the body carried no copy. */\nexport function httpStatusExplanation(status: number): string {\n return (\n HTTP_STATUS_EXPLANATION[status] ??\n \"The request failed with an unexpected status.\"\n );\n}\n\n/**\n * Sentence-case the first character. Server `detail` / `title` sometimes\n * arrive fully lowercase; UI copy always leads with a capital.\n */\nexport function capitalizeFirst(text: string): string {\n if (!text) return text;\n const first = text.charAt(0);\n const upper = first.toUpperCase();\n if (first === upper) return text;\n return upper + text.slice(1);\n}\n\n/**\n * Turn a caught value into displayable copy. `Error` and `ErrorView` call\n * this internally; use it directly for other surfaces (a toast, a banner).\n *\n * Status-only failures (HTTP not ok, but no contract `code` / copy) still\n * keep `problem` so the details panel can show the status. Title becomes the\n * reason phrase (e.g. \"Bad Gateway\"); description is a short explanation —\n * not just the numeric code.\n */\nexport function describeError(error: unknown): ErrorDescription {\n const problem = parseProblem(error);\n if (problem == null) return { title: GENERIC_ERROR_TITLE };\n\n const description =\n [problem.detail, problem.remediation?.action]\n .filter((part): part is string => typeof part === \"string\" && part !== \"\")\n .join(\" \") || undefined;\n\n if (!hasContractCode(problem) && description == null) {\n const reason = httpReasonPhrase(problem.status, problem.title);\n return {\n title: capitalizeFirst(reason ?? GENERIC_ERROR_TITLE),\n description: httpStatusExplanation(problem.status),\n requestId: problem.requestId,\n problem,\n };\n }\n\n return {\n title: capitalizeFirst(problem.title || GENERIC_ERROR_TITLE),\n description: description ? capitalizeFirst(description) : undefined,\n documentation: problem.remediation?.documentation,\n requestId: problem.requestId,\n problem,\n };\n}\n","import {\n useEffect,\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n} from \"react\";\nimport {\n IconAlertCircleFilled,\n IconAlertTriangle,\n IconInfoCircle,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button, ButtonLink } from \"../button/button\";\nimport { Popover } from \"../popover/popover\";\nimport { StatusView, type StatusViewSize } from \"../status-view/status-view\";\nimport {\n capitalizeFirst,\n describeError,\n httpReasonPhrase,\n type ErrorDescription,\n} from \"./problem\";\n\n/** Capitalize string copy; leave custom ReactNode overrides alone. */\nfunction displayCopy(value: ReactNode): ReactNode {\n return typeof value === \"string\" ? capitalizeFirst(value) : value;\n}\n\n/**\n * Design notes:\n * - ONE input: `error` is the caught value, whatever it is — a Problem\n * Details body from `@photon-hq/error`, an `Error` carrying one as\n * `cause`, or something unknown. The component derives its copy via\n * `describeError`; unknowns fall back to a generic line rather than\n * leaking raw messages.\n * - TWO presentations, one per altitude: `Error` is the inline line for\n * forms, cards, and action rows; `ErrorView` is the region / page state\n * built on StatusView (same `sm` / `base` size axis).\n * - Both render `null` when there is nothing to show, so they can sit\n * unconditionally in JSX (`<Error error={mutation.error} />`).\n * - Client-side *validation* is not this component's job — that belongs to\n * `Field.Error`, wired to control validity.\n */\n\nconst DOC_LINK_LABEL = \"Learn more\";\nconst RETRY_LABEL = \"Try again\";\n\ninterface ErrorBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived message. */\n children?: ReactNode;\n}\n\nexport interface ErrorProps\n extends ErrorBaseProps, Omit<ComponentProps<\"div\">, keyof ErrorBaseProps> {}\n\n/**\n * Error — one line of red ink naming a server failure (4xx / 5xx), placed\n * inline: under a form, in a card, beside the action that failed. Give it the\n * caught value and it renders the problem's `detail` (falling back to `title`,\n * then to a generic line), plus a docs link when the problem carries one.\n * Renders nothing while `error` is nullish, so it can stay mounted.\n *\n * For a region or page that failed to load, use {@link ErrorView}.\n */\nexport function Error({ error, children, className, ...props }: ErrorProps) {\n if (error == null && children == null) return null;\n const copy = describeError(error);\n return (\n <div\n role=\"alert\"\n className={cn(\n \"text-pho-error flex min-w-0 items-start gap-1.5 text-base\",\n className,\n )}\n {...props}\n >\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n <span className=\"min-w-0\">\n {displayCopy(children ?? copy.description ?? copy.title)}\n {copy.documentation != null && (\n <>\n {\" \"}\n <a\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-medium underline underline-offset-2\"\n >\n {DOC_LINK_LABEL}\n </a>\n </>\n )}\n {/* Trailing whitespace collapses when the details render null. */}{\" \"}\n <ErrorDetails copy={copy} />\n </span>\n </div>\n );\n}\n\nError.displayName = \"Error\";\n\n/**\n * Hover / focus disclosure on the inline line — the request's fuller story:\n * problem `title` (with the same alert icon + `text-pho-error` ink as the\n * inline line), the untruncated description, then `status` + `code` and the\n * copyable request id grouped below for a support handoff. Renders only when\n * the caught value actually carried a problem (or at least a request id); a\n * generic unknown has nothing more to disclose. Built on `Popover` rather\n * than `Tooltip` because the panel holds an interactive control (the copy\n * button) — `openOnHover` keeps the tooltip-like gesture.\n */\nfunction ErrorDetails({ copy }: { copy: ErrorDescription }) {\n const { problem, requestId } = copy;\n if (problem == null && requestId == null) return null;\n\n // Contract problems show `status CODE`; status-only shows `status Reason`.\n let statusLine: string | null = null;\n if (problem != null) {\n if (problem.code) {\n statusLine = `${problem.status} ${problem.code}`;\n } else {\n const reason = httpReasonPhrase(problem.status, problem.title);\n statusLine = reason\n ? `${problem.status} ${reason}`\n : String(problem.status);\n }\n }\n\n return (\n <Popover.Root>\n <Popover.Trigger\n openOnHover\n delay={150}\n aria-label=\"Error details\"\n className=\"outline-pho-brand inline-flex size-4 shrink-0 translate-y-[3px] cursor-help items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2\"\n >\n <IconInfoCircle className=\"size-3.5\" />\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner align=\"start\">\n <Popover.Popup className=\"text-pho-error\">\n <Popover.Title className=\"text-pho-error flex items-start gap-1.5\">\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n {copy.title}\n </Popover.Title>\n {copy.description != null && (\n <Popover.Description className=\"text-pho-error\">\n {copy.description}\n </Popover.Description>\n )}\n {(statusLine != null || requestId != null) && (\n <div className=\"text-pho-error mt-1 font-mono text-[10px] leading-snug\">\n {statusLine != null && <p>{statusLine}</p>}\n {requestId != null && (\n <RequestId requestId={requestId} className=\"mt-0\" />\n )}\n </div>\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\n/** Request-id footnote — click copies the id for support handoff. */\nfunction RequestId({\n requestId,\n className,\n}: {\n requestId: string;\n className?: string;\n}) {\n const [copied, setCopied] = useState(false);\n const copiedTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n },\n [],\n );\n\n return (\n <span\n className={cn(\"mt-1 block font-mono text-[10px] leading-snug\", className)}\n >\n Request ID:{\" \"}\n <button\n type=\"button\"\n className=\"outline-pho-brand inline cursor-pointer underline-offset-2 select-all hover:underline focus-visible:underline focus-visible:outline-2 focus-visible:-outline-offset-1\"\n aria-label={\n copied ? \"Request ID copied\" : `Copy request ID ${requestId}`\n }\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(requestId);\n } catch {\n return;\n }\n setCopied(true);\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n copiedTimer.current = setTimeout(() => setCopied(false), 1500);\n }}\n >\n {requestId}\n </button>\n <output className=\"sr-only\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </output>\n </span>\n );\n}\n\ninterface ErrorViewBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived title. */\n title?: ReactNode;\n /** Override the derived description. */\n description?: ReactNode;\n /** Override the warning glyph. */\n icon?: ReactNode;\n /** Offer a retry — renders a \"Try again\" button. */\n onRetry?: () => void;\n /** Replace the built-in action row entirely. */\n actions?: ReactNode;\n /** Size variant — StatusView's axis. @default \"base\" */\n size?: StatusViewSize;\n}\n\nexport interface ErrorViewProps\n extends\n ErrorViewBaseProps,\n Omit<ComponentProps<\"div\">, keyof ErrorViewBaseProps | \"children\"> {}\n\n/**\n * ErrorView — the failed state of a region or page, built on StatusView:\n * warning icon over the problem's `title`, its `detail` and remediation\n * below, an action row (`onRetry` and the problem's docs link), and the\n * request id as a footnote for support. Announces via `role=\"alert\"`.\n *\n * Use `size=\"sm\"` inside cards and panels, the default `base` for whole\n * pages. Renders nothing while `error` is nullish (unless given a static\n * `title`), so it can sit unconditionally next to a query.\n */\nexport function ErrorView({\n error,\n title,\n description,\n icon,\n onRetry,\n actions,\n size = \"base\",\n ...props\n}: ErrorViewProps) {\n if (error == null && title == null) return null;\n const copy = describeError(error);\n\n const resolvedDescription = displayCopy(description ?? copy.description);\n const body =\n resolvedDescription != null || copy.requestId != null ? (\n <>\n {resolvedDescription}\n {copy.requestId != null && <RequestId requestId={copy.requestId} />}\n </>\n ) : undefined;\n\n const resolvedActions =\n actions ??\n (onRetry != null || copy.documentation != null ? (\n <>\n {onRetry != null && (\n <Button size=\"sm\" onClick={onRetry}>\n {RETRY_LABEL}\n </Button>\n )}\n {copy.documentation != null && (\n <ButtonLink\n size=\"sm\"\n variant=\"outlined\"\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {DOC_LINK_LABEL}\n </ButtonLink>\n )}\n </>\n ) : undefined);\n\n return (\n <StatusView\n role=\"alert\"\n size={size}\n icon={icon ?? <IconAlertTriangle />}\n title={displayCopy(title ?? copy.title)}\n description={body}\n actions={resolvedActions}\n {...props}\n />\n );\n}\n\nErrorView.displayName = \"ErrorView\";\n"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;;AASA,IAAM,IAAa;AAAA,EAAC,CAAC,QAAQ;AAAA,IAAE,GAAK;AAAA,IAAW,KAAO;AAAA,EAAQ,CAAC;AAAA,EAAG,CAAC,QAAQ;AAAA,IAAE,GAAK;AAAA,IAA4I,KAAO;AAAA,EAAQ,CAAC;AAAA,EAAG,CAAC,QAAQ;AAAA,IAAE,GAAK;AAAA,IAAc,KAAO;AAAA,EAAQ,CAAC;AAAC,GAC1R,IAAoB,EAAqB,WAAW,kBAAkB,iBAAiB,CAAU;AC2BvG,SAAgB,EAAU,GAAkC;AAC1D,MAAI,OAAO,KAAU,YAAY,MAAU,KAAM,QAAO;AACxD,QAAM,IAAI;AACV,SACE,OAAO,EAAE,SAAU,YACnB,OAAO,EAAE,UAAW,YACpB,OAAO,UAAU,EAAE,MAAM,KACzB,EAAE,UAAU,OACZ,EAAE,UAAU,QACX,EAAE,SAAS,UAAa,OAAO,EAAE,QAAS;AAE/C;AAQA,SAAgB,EAAa,GAAgC;AAC3D,MAAI,IAAmB;AACvB,WACM,IAAQ,GACZ,IAAQ,KAAK,OAAO,KAAY,YAAY,MAAY,MACxD,KACA;AACA,QAAI,EAAU,CAAO,EAAG,QAAO;AAC/B,UAAM,IAAW,EAAkC;AACnD,QAAI,EAAU,CAAO,EAAG,QAAO;AAC/B,IAAA,IAAW,EAAgC;AAAA,EAC7C;AACA,SAAO;AACT;AAqBA,IAAa,IAAsB,yBAG7B,IAA6C;AAAA,EACjD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP,GAGM,IAAkD;AAAA,EACtD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAEA,SAAS,EAAgB,GAA2B;AAClD,SAAO,OAAO,EAAQ,QAAS,YAAY,EAAQ,SAAS;AAC9D;AAGA,SAAgB,EACd,GACA,GACoB;AACpB,MAAI,EAAmB,CAAA,EAAS,QAAO,EAAmB,CAAA;AAC1D,MACE,KACA,MAAA,2BACA,MAAkB,iBAElB,QAAO,EAAc,QAAQ,OAAO,EAAE;AAG1C;AAGA,SAAgB,EAAsB,GAAwB;AAC5D,SACE,EAAwB,CAAA,KACxB;AAEJ;AAMA,SAAgB,EAAgB,GAAsB;AACpD,MAAI,CAAC,EAAM,QAAO;AAClB,QAAM,IAAQ,EAAK,OAAO,CAAC,GACrB,IAAQ,EAAM,YAAY;AAChC,SAAI,MAAU,IAAc,IACrB,IAAQ,EAAK,MAAM,CAAC;AAC7B;AAWA,SAAgB,EAAc,GAAkC;AAC9D,QAAM,IAAU,EAAa,CAAK;AAClC,MAAI,KAAW,KAAM,QAAO,EAAE,OAAO,EAAoB;AAEzD,QAAM,IACJ,CAAC,EAAQ,QAAQ,EAAQ,aAAa,MAAM,EACzC,OAAA,CAAQ,MAAyB,OAAO,KAAS,YAAY,MAAS,EAAE,EACxE,KAAK,GAAG,KAAK;AAElB,SAAI,CAAC,EAAgB,CAAO,KAAK,KAAe,OAEvC;AAAA,IACL,OAAO,EAFM,EAAiB,EAAQ,QAAQ,EAAQ,KAE/B,KAAA,uBAA6B;AAAA,IACpD,aAAa,EAAsB,EAAQ,MAAM;AAAA,IACjD,WAAW,EAAQ;AAAA,IACnB,SAAA;AAAA,EACF,IAGK;AAAA,IACL,OAAO,EAAgB,EAAQ,SAAA,uBAA4B;AAAA,IAC3D,aAAa,IAAc,EAAgB,CAAW,IAAI;AAAA,IAC1D,eAAe,EAAQ,aAAa;AAAA,IACpC,WAAW,EAAQ;AAAA,IACnB,SAAA;AAAA,EACF;AACF;ACvLA,SAAS,EAAY,GAA6B;AAChD,SAAO,OAAO,KAAU,WAAW,EAAgB,CAAK,IAAI;AAC9D;AAkBA,IAAM,IAAiB,cACjB,IAAc;AAqBpB,SAAgB,EAAM,EAAE,OAAA,GAAO,UAAA,GAAU,WAAA,GAAW,GAAG,EAAA,GAAqB;AAC1E,MAAI,KAAS,QAAQ,KAAY,KAAM,QAAO;AAC9C,QAAM,IAAO,EAAc,CAAK;AAChC,SACE,gBAAA,EAAC,OAAD;AAAA,IACE,MAAK;AAAA,IACL,WAAW,EACT,6DACA,CACF;AAAA,IACA,GAAI;AAAA,cANN,CAQE,gBAAA,EAAC,QAAD;AAAA,MAAM,eAAA;AAAA,MAAY,WAAU;AAAA,gBAC1B,gBAAA,EAAC,GAAD,EAAuB,WAAU,SAAU,CAAA;AAAA,IACvC,CAAA,GACN,gBAAA,EAAC,QAAD;AAAA,MAAM,WAAU;AAAA,gBAAhB;AAAA,QACG,EAAY,KAAY,EAAK,eAAe,EAAK,KAAK;AAAA,QACtD,EAAK,iBAAiB,QACrB,gBAAA,EAAA,GAAA,EAAA,UAAA,CACG,KACD,gBAAA,EAAC,KAAD;AAAA,UACE,MAAM,EAAK;AAAA,UACX,QAAO;AAAA,UACP,KAAI;AAAA,UACJ,WAAU;AAAA,oBAET;AAAA,QACA,CAAA,CACH,EAAA,CAAA;AAAA,QAEgE;AAAA,QACpE,gBAAA,EAAC,GAAD,EAAoB,MAAA,EAAO,CAAA;AAAA,MACvB;AAAA,MACH;AAAA;AAET;AAEA,EAAM,cAAc;AAYpB,SAAS,EAAa,EAAE,MAAA,EAAA,GAAoC;AAC1D,QAAM,EAAE,SAAA,GAAS,WAAA,EAAA,IAAc;AAC/B,MAAI,KAAW,QAAQ,KAAa,KAAM,QAAO;AAGjD,MAAI,IAA4B;AAChC,MAAI,KAAW,KACb,KAAI,EAAQ,KACV,CAAA,IAAa,GAAG,EAAQ,MAAA,IAAU,EAAQ,IAAA;AAAA,OACrC;AACL,UAAM,IAAS,EAAiB,EAAQ,QAAQ,EAAQ,KAAK;AAC7D,IAAA,IAAa,IACT,GAAG,EAAQ,MAAA,IAAU,CAAA,KACrB,OAAO,EAAQ,MAAM;AAAA,EAC3B;AAGF,SACE,gBAAA,EAAC,EAAQ,MAAT,EAAA,UAAA,CACE,gBAAA,EAAC,EAAQ,SAAT;AAAA,IACE,aAAA;AAAA,IACA,OAAO;AAAA,IACP,cAAW;AAAA,IACX,WAAU;AAAA,cAEV,gBAAA,EAAC,GAAD,EAAgB,WAAU,WAAY,CAAA;AAAA,EACvB,CAAA,GACjB,gBAAA,EAAC,EAAQ,QAAT,EAAA,UACE,gBAAA,EAAC,EAAQ,YAAT;AAAA,IAAoB,OAAM;AAAA,cACxB,gBAAA,EAAC,EAAQ,OAAT;AAAA,MAAe,WAAU;AAAA,gBAAzB;AAAA,QACE,gBAAA,EAAC,EAAQ,OAAT;AAAA,UAAe,WAAU;AAAA,oBAAzB,CACE,gBAAA,EAAC,QAAD;AAAA,YAAM,eAAA;AAAA,YAAY,WAAU;AAAA,sBAC1B,gBAAA,EAAC,GAAD,EAAuB,WAAU,SAAU,CAAA;AAAA,UACvC,CAAA,GACL,EAAK,KACO;AAAA;QACd,EAAK,eAAe,QACnB,gBAAA,EAAC,EAAQ,aAAT;AAAA,UAAqB,WAAU;AAAA,oBAC5B,EAAK;AAAA,QACa,CAAA;AAAA,SAErB,KAAc,QAAQ,KAAa,SACnC,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBAAf,CACG,KAAc,QAAQ,gBAAA,EAAC,KAAD,EAAA,UAAI,EAAc,CAAA,GACxC,KAAa,QACZ,gBAAA,EAAC,GAAD;AAAA,YAAsB,WAAA;AAAA,YAAW,WAAU;AAAA,UAAQ,CAAA,CAElD;AAAA;MAEM;AAAA;EACG,CAAA,EACN,CAAA,CACJ,EAAA,CAAA;AAElB;AAGA,SAAS,EAAU,EACjB,WAAA,GACA,WAAA,EAAA,GAIC;AACD,QAAM,CAAC,GAAQ,CAAA,IAAa,EAAS,EAAK,GACpC,IAAc,EAA6C,IAAI;AAErE,SAAA,EAAA,MAAA,MACc;AACV,IAAI,EAAY,WAAS,aAAa,EAAY,OAAO;AAAA,EAC3D,GACA,CAAC,CACH,GAGE,gBAAA,EAAC,QAAD;AAAA,IACE,WAAW,EAAG,iDAAiD,CAAS;AAAA,cAD1E;AAAA,MAEC;AAAA,MACa;AAAA,MACZ,gBAAA,EAAC,UAAD;AAAA,QACE,MAAK;AAAA,QACL,WAAU;AAAA,QACV,cACE,IAAS,sBAAsB,mBAAmB,CAAA;AAAA,QAEpD,SAAS,YAAY;AACnB,cAAI;AACF,kBAAM,UAAU,UAAU,UAAU,CAAS;AAAA,UAC/C,QAAQ;AACN;AAAA,UACF;AACA,UAAA,EAAU,EAAI,GACV,EAAY,WAAS,aAAa,EAAY,OAAO,GACzD,EAAY,UAAU,WAAA,MAAiB,EAAU,EAAK,GAAG,IAAI;AAAA,QAC/D;AAAA,kBAEC;AAAA,MACK,CAAA;AAAA,MACR,gBAAA,EAAC,UAAD;AAAA,QAAQ,WAAU;AAAA,QAAU,aAAU;AAAA,kBACnC,IAAS,WAAW;AAAA,MACf,CAAA;AAAA,IACJ;AAAA;AAEV;AAkCA,SAAgB,EAAU,EACxB,OAAA,GACA,OAAA,GACA,aAAA,GACA,MAAA,GACA,SAAA,GACA,SAAA,GACA,MAAA,IAAO,QACP,GAAG,EAAA,GACc;AACjB,MAAI,KAAS,QAAQ,KAAS,KAAM,QAAO;AAC3C,QAAM,IAAO,EAAc,CAAK,GAE1B,IAAsB,EAAY,KAAe,EAAK,WAAW,GACjE,IACJ,KAAuB,QAAQ,EAAK,aAAa,OAC/C,gBAAA,EAAA,GAAA,EAAA,UAAA,CACG,GACA,EAAK,aAAa,QAAQ,gBAAA,EAAC,GAAD,EAAW,WAAW,EAAK,UAAY,CAAA,CAClE,EAAA,CAAA,IACA,QAEA,IACJ,MACC,KAAW,QAAQ,EAAK,iBAAiB,OACxC,gBAAA,EAAA,GAAA,EAAA,UAAA,CACG,KAAW,QACV,gBAAA,EAAC,GAAD;AAAA,IAAQ,MAAK;AAAA,IAAK,SAAS;AAAA,cACxB;AAAA,EACK,CAAA,GAET,EAAK,iBAAiB,QACrB,gBAAA,EAAC,GAAD;AAAA,IACE,MAAK;AAAA,IACL,SAAQ;AAAA,IACR,MAAM,EAAK;AAAA,IACX,QAAO;AAAA,IACP,KAAI;AAAA,cAEH;AAAA,EACS,CAAA,CAEd,EAAA,CAAA,IACA;AAEN,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,MAAK;AAAA,IACC,MAAA;AAAA,IACN,MAAM,KAAQ,gBAAA,EAAC,GAAD,CAAoB,CAAA;AAAA,IAClC,OAAO,EAAY,KAAS,EAAK,KAAK;AAAA,IACtC,aAAa;AAAA,IACb,SAAS;AAAA,IACT,GAAI;AAAA,EACL,CAAA;AAEL;AAEA,EAAU,cAAc"}
1
+ {"version":3,"file":"error-Da7P5WZi.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertTriangle.mjs","../../src/components/error/problem.ts","../../src/components/error/error.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 9v4\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M12 16h.01\", \"key\": \"svg-2\" }]];\nconst IconAlertTriangle = createReactComponent(\"outline\", \"alert-triangle\", \"AlertTriangle\", __iconNode);\n\nexport { __iconNode, IconAlertTriangle as default };\n//# sourceMappingURL=IconAlertTriangle.mjs.map\n","/**\n * Client-side mirror of the `@photon-hq/error` response contract — the\n * RFC 9457 Problem Details body every Photon service returns for 4xx / 5xx.\n * Machine logic branches on `code`; `title` / `detail` / `remediation` are\n * the human-readable copy, already reviewed server-side and safe to render.\n *\n * Fetch layers may also hand us a thin status-only shape when the response\n * was not ok but the body was not a contract problem — `title` + `status`\n * still count so the UI can disclose the HTTP code we already know.\n */\n\nexport interface ProblemRemediation {\n /** What the user can do about it — a full sentence. */\n action?: string;\n /** Docs URL explaining the problem. */\n documentation?: string;\n}\n\nexport interface Problem {\n /** Stable machine-readable key (`RATE_LIMITED`) — the field to branch on. */\n code?: string;\n /** Human summary of the problem type (\"Too Many Requests\"). */\n title: string;\n /** HTTP status (4xx / 5xx). */\n status: number;\n /** Problem type URI (`urn:photon:problem:*` or an https URL). */\n type?: string;\n /** Occurrence-specific human sentence. */\n detail?: string;\n /** Correlation id for support (`X-Request-ID`). */\n requestId?: string;\n remediation?: ProblemRemediation;\n /** RFC 9457 extensions (`issues`, `actualVersion`, …). */\n [extension: string]: unknown;\n}\n\n/** Structural check: `title` + a 4xx/5xx status. `code` is optional. */\nexport function isProblem(value: unknown): value is Problem {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.title === \"string\" &&\n typeof v.status === \"number\" &&\n Number.isInteger(v.status) &&\n v.status >= 400 &&\n v.status <= 599 &&\n (v.code === undefined || typeof v.code === \"string\")\n );\n}\n\n/**\n * Find the problem a caught value carries — the value itself, one typed onto\n * an error as a `problem` field (dashboard's `ApiError` shape), or one\n * wrapped in an `Error` `cause` chain (how fetch layers usually rethrow a\n * parsed body). Returns `null` when there is none.\n */\nexport function parseProblem(error: unknown): Problem | null {\n let current: unknown = error;\n for (\n let depth = 0;\n depth < 8 && typeof current === \"object\" && current !== null;\n depth++\n ) {\n if (isProblem(current)) return current;\n const carried = (current as { problem?: unknown }).problem;\n if (isProblem(carried)) return carried;\n current = (current as { cause?: unknown }).cause;\n }\n return null;\n}\n\nexport interface ErrorDescription {\n /** Short name of the failure — the problem `title`, or a generic fallback. */\n title: string;\n /** Sentence(s) to show — `detail` and `remediation.action` joined. */\n description?: string;\n /** Docs URL from `remediation.documentation`. */\n documentation?: string;\n /** Correlation id for support. */\n requestId?: string;\n /** The matched problem, when the input carried one. */\n problem?: Problem;\n}\n\n/**\n * Anything that isn't a problem renders as this — raw `Error` messages are\n * not contract copy and never shown (the same fail-closed stance as the\n * server side of `@photon-hq/error`). Always a full sentence (trailing\n * period).\n */\nexport const GENERIC_ERROR_TITLE = \"Something went wrong.\";\n\n/** Standard reason phrases for statuses we commonly surface without a body. */\nconst HTTP_REASON_PHRASE: Record<number, string> = {\n 400: \"Bad Request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not Found\",\n 408: \"Request Timeout\",\n 409: \"Conflict\",\n 410: \"Gone\",\n 413: \"Payload Too Large\",\n 415: \"Unsupported Media Type\",\n 422: \"Unprocessable Entity\",\n 429: \"Too Many Requests\",\n 500: \"Internal Server Error\",\n 501: \"Not Implemented\",\n 502: \"Bad Gateway\",\n 503: \"Service Unavailable\",\n 504: \"Gateway Timeout\",\n};\n\n/** One-sentence explanations when the server gave a status but no problem copy. */\nconst HTTP_STATUS_EXPLANATION: Record<number, string> = {\n 400: \"The request was malformed or incomplete.\",\n 401: \"You need to sign in again.\",\n 403: \"You don't have permission to do that.\",\n 404: \"The requested resource was not found.\",\n 408: \"The request timed out before the server responded.\",\n 409: \"The request conflicts with the current state.\",\n 410: \"That resource is no longer available.\",\n 413: \"The request was too large for the server to accept.\",\n 415: \"That media type isn't supported.\",\n 422: \"The request was understood but couldn't be processed.\",\n 429: \"Request rate limit exceeded. Wait a moment before trying again.\",\n 500: \"The server hit an unexpected error.\",\n 501: \"The server doesn't support that operation.\",\n 502: \"The gateway got an invalid response from an upstream server.\",\n 503: \"The service is temporarily unavailable.\",\n 504: \"The gateway timed out waiting for an upstream server.\",\n};\n\nfunction hasContractCode(problem: Problem): boolean {\n return typeof problem.code === \"string\" && problem.code !== \"\";\n}\n\n/** Reason phrase for a status — map first, then a non-generic `problem.title`. */\nexport function httpReasonPhrase(\n status: number,\n fallbackTitle?: string,\n): string | undefined {\n if (HTTP_REASON_PHRASE[status]) return HTTP_REASON_PHRASE[status];\n if (\n fallbackTitle &&\n fallbackTitle !== GENERIC_ERROR_TITLE &&\n fallbackTitle !== \"Request failed\"\n ) {\n return fallbackTitle.replace(/\\.$/, \"\");\n }\n return undefined;\n}\n\n/** Human sentence for a bare HTTP status, when the body carried no copy. */\nexport function httpStatusExplanation(status: number): string {\n return (\n HTTP_STATUS_EXPLANATION[status] ??\n \"The request failed with an unexpected status.\"\n );\n}\n\n/**\n * Sentence-case the first character. Server `detail` / `title` sometimes\n * arrive fully lowercase; UI copy always leads with a capital.\n */\nexport function capitalizeFirst(text: string): string {\n if (!text) return text;\n const first = text.charAt(0);\n const upper = first.toUpperCase();\n if (first === upper) return text;\n return upper + text.slice(1);\n}\n\n/**\n * Turn a caught value into displayable copy. `Error` and `ErrorView` call\n * this internally; use it directly for other surfaces (a toast, a banner).\n *\n * Status-only failures (HTTP not ok, but no contract `code` / copy) still\n * keep `problem` so the details panel can show the status. Title becomes the\n * reason phrase (e.g. \"Bad Gateway\"); description is a short explanation —\n * not just the numeric code.\n */\nexport function describeError(error: unknown): ErrorDescription {\n const problem = parseProblem(error);\n if (problem == null) return { title: GENERIC_ERROR_TITLE };\n\n const description =\n [problem.detail, problem.remediation?.action]\n .filter((part): part is string => typeof part === \"string\" && part !== \"\")\n .join(\" \") || undefined;\n\n if (!hasContractCode(problem) && description == null) {\n const reason = httpReasonPhrase(problem.status, problem.title);\n return {\n title: capitalizeFirst(reason ?? GENERIC_ERROR_TITLE),\n description: httpStatusExplanation(problem.status),\n requestId: problem.requestId,\n problem,\n };\n }\n\n return {\n title: capitalizeFirst(problem.title || GENERIC_ERROR_TITLE),\n description: description ? capitalizeFirst(description) : undefined,\n documentation: problem.remediation?.documentation,\n requestId: problem.requestId,\n problem,\n };\n}\n","import {\n useEffect,\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n} from \"react\";\nimport {\n IconAlertCircleFilled,\n IconAlertTriangle,\n IconInfoCircle,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button, ButtonLink } from \"../button/button\";\nimport { Popover } from \"../popover/popover\";\nimport { StatusView, type StatusViewSize } from \"../status-view/status-view\";\nimport {\n capitalizeFirst,\n describeError,\n httpReasonPhrase,\n type ErrorDescription,\n} from \"./problem\";\n\n/** Capitalize string copy; leave custom ReactNode overrides alone. */\nfunction displayCopy(value: ReactNode): ReactNode {\n return typeof value === \"string\" ? capitalizeFirst(value) : value;\n}\n\n/**\n * Design notes:\n * - ONE input: `error` is the caught value, whatever it is — a Problem\n * Details body from `@photon-hq/error`, an `Error` carrying one as\n * `cause`, or something unknown. The component derives its copy via\n * `describeError`; unknowns fall back to a generic line rather than\n * leaking raw messages.\n * - TWO presentations, one per altitude: `Error` is the inline line for\n * forms, cards, and action rows; `ErrorView` is the region / page state\n * built on StatusView (same `sm` / `base` size axis).\n * - Both render `null` when there is nothing to show, so they can sit\n * unconditionally in JSX (`<Error error={mutation.error} />`).\n * - Client-side *validation* is not this component's job — that belongs to\n * `Field.Error`, wired to control validity.\n */\n\nconst DOC_LINK_LABEL = \"Learn more\";\nconst RETRY_LABEL = \"Try again\";\n\ninterface ErrorBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived message. */\n children?: ReactNode;\n}\n\nexport interface ErrorProps\n extends ErrorBaseProps, Omit<ComponentProps<\"div\">, keyof ErrorBaseProps> {}\n\n/**\n * Error — one line of red ink naming a server failure (4xx / 5xx), placed\n * inline: under a form, in a card, beside the action that failed. Give it the\n * caught value and it renders the problem's `detail` (falling back to `title`,\n * then to a generic line), plus a docs link when the problem carries one.\n * Renders nothing while `error` is nullish, so it can stay mounted.\n *\n * For a region or page that failed to load, use {@link ErrorView}.\n */\nexport function Error({ error, children, className, ...props }: ErrorProps) {\n if (error == null && children == null) return null;\n const copy = describeError(error);\n return (\n <div\n role=\"alert\"\n className={cn(\n \"text-pho-error flex min-w-0 items-start gap-1.5 text-base\",\n className,\n )}\n {...props}\n >\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n <span className=\"min-w-0\">\n {displayCopy(children ?? copy.description ?? copy.title)}\n {copy.documentation != null && (\n <>\n {\" \"}\n <a\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-medium underline underline-offset-2\"\n >\n {DOC_LINK_LABEL}\n </a>\n </>\n )}\n {/* Trailing whitespace collapses when the details render null. */}{\" \"}\n <ErrorDetails copy={copy} />\n </span>\n </div>\n );\n}\n\nError.displayName = \"Error\";\n\n/**\n * Hover / focus disclosure on the inline line — the request's fuller story:\n * problem `title` (with the same alert icon + `text-pho-error` ink as the\n * inline line), the untruncated description, then `status` + `code` and the\n * copyable request id grouped below for a support handoff. Renders only when\n * the caught value actually carried a problem (or at least a request id); a\n * generic unknown has nothing more to disclose. Built on `Popover` rather\n * than `Tooltip` because the panel holds an interactive control (the copy\n * button) — `openOnHover` keeps the tooltip-like gesture.\n */\nfunction ErrorDetails({ copy }: { copy: ErrorDescription }) {\n const { problem, requestId } = copy;\n if (problem == null && requestId == null) return null;\n\n // Contract problems show `status CODE`; status-only shows `status Reason`.\n let statusLine: string | null = null;\n if (problem != null) {\n if (problem.code) {\n statusLine = `${problem.status} ${problem.code}`;\n } else {\n const reason = httpReasonPhrase(problem.status, problem.title);\n statusLine = reason\n ? `${problem.status} ${reason}`\n : String(problem.status);\n }\n }\n\n return (\n <Popover.Root>\n <Popover.Trigger\n openOnHover\n delay={150}\n aria-label=\"Error details\"\n className=\"outline-pho-brand inline-flex size-4 shrink-0 translate-y-[3px] cursor-help items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2\"\n >\n <IconInfoCircle className=\"size-3.5\" />\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner align=\"start\">\n <Popover.Popup className=\"text-pho-error\">\n <Popover.Title className=\"text-pho-error flex items-start gap-1.5\">\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n {copy.title}\n </Popover.Title>\n {copy.description != null && (\n <Popover.Description className=\"text-pho-error\">\n {copy.description}\n </Popover.Description>\n )}\n {(statusLine != null || requestId != null) && (\n <div className=\"text-pho-error mt-1 font-mono text-[10px] leading-snug\">\n {statusLine != null && <p>{statusLine}</p>}\n {requestId != null && (\n <RequestId requestId={requestId} className=\"mt-0\" />\n )}\n </div>\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\n/** Request-id footnote — click copies the id for support handoff. */\nfunction RequestId({\n requestId,\n className,\n}: {\n requestId: string;\n className?: string;\n}) {\n const [copied, setCopied] = useState(false);\n const copiedTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n },\n [],\n );\n\n return (\n <span\n className={cn(\"mt-1 block font-mono text-[10px] leading-snug\", className)}\n >\n Request ID:{\" \"}\n <button\n type=\"button\"\n className=\"outline-pho-brand inline cursor-pointer underline-offset-2 select-all hover:underline focus-visible:underline focus-visible:outline-2 focus-visible:-outline-offset-1\"\n aria-label={\n copied ? \"Request ID copied\" : `Copy request ID ${requestId}`\n }\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(requestId);\n } catch {\n return;\n }\n setCopied(true);\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n copiedTimer.current = setTimeout(() => setCopied(false), 1500);\n }}\n >\n {requestId}\n </button>\n <output className=\"sr-only\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </output>\n </span>\n );\n}\n\ninterface ErrorViewBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived title. */\n title?: ReactNode;\n /** Override the derived description. */\n description?: ReactNode;\n /** Override the warning glyph. */\n icon?: ReactNode;\n /** Offer a retry — renders a \"Try again\" button. */\n onRetry?: () => void;\n /** Replace the built-in action row entirely. */\n actions?: ReactNode;\n /** Size variant — StatusView's axis. @default \"base\" */\n size?: StatusViewSize;\n}\n\nexport interface ErrorViewProps\n extends\n ErrorViewBaseProps,\n Omit<ComponentProps<\"div\">, keyof ErrorViewBaseProps | \"children\"> {}\n\n/**\n * ErrorView — the failed state of a region or page, built on StatusView:\n * warning icon over the problem's `title`, its `detail` and remediation\n * below, an action row (`onRetry` and the problem's docs link), and the\n * request id as a footnote for support. Announces via `role=\"alert\"`.\n *\n * Use `size=\"sm\"` inside cards and panels, the default `base` for whole\n * pages. Renders nothing while `error` is nullish (unless given a static\n * `title`), so it can sit unconditionally next to a query.\n */\nexport function ErrorView({\n error,\n title,\n description,\n icon,\n onRetry,\n actions,\n size = \"base\",\n ...props\n}: ErrorViewProps) {\n if (error == null && title == null) return null;\n const copy = describeError(error);\n\n const resolvedDescription = displayCopy(description ?? copy.description);\n const body =\n resolvedDescription != null || copy.requestId != null ? (\n <>\n {resolvedDescription}\n {copy.requestId != null && <RequestId requestId={copy.requestId} />}\n </>\n ) : undefined;\n\n const resolvedActions =\n actions ??\n (onRetry != null || copy.documentation != null ? (\n <>\n {onRetry != null && (\n <Button size=\"sm\" onClick={onRetry}>\n {RETRY_LABEL}\n </Button>\n )}\n {copy.documentation != null && (\n <ButtonLink\n size=\"sm\"\n variant=\"outlined\"\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {DOC_LINK_LABEL}\n </ButtonLink>\n )}\n </>\n ) : undefined);\n\n return (\n <StatusView\n role=\"alert\"\n size={size}\n icon={icon ?? <IconAlertTriangle />}\n title={displayCopy(title ?? copy.title)}\n description={body}\n actions={resolvedActions}\n {...props}\n />\n );\n}\n\nErrorView.displayName = \"ErrorView\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as r } from "./cn-DTiB6ek_.js";
2
+ import { t as r } from "./cn-ChIgwEl3.js";
3
3
  import { t as f } from "./createReactComponent-BqCmnqfX.js";
4
4
  import { t as A } from "./IconAlertCircleFilled-VxKU8TYK.js";
5
5
  import { useState as S } from "react";
@@ -101,4 +101,4 @@ export {
101
101
  j as t
102
102
  };
103
103
 
104
- //# sourceMappingURL=input-D3XQcC4J.js.map
104
+ //# sourceMappingURL=input-QSAUO30c.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-D3XQcC4J.js","names":["__iconNode"],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconEyeOff.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.44.0_react@19.2.7/node_modules/@tabler/icons-react/dist/esm/icons/IconEye.mjs","../../src/components/input/input.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M10.585 10.587a2 2 0 0 0 2.829 2.828\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M3 3l18 18\", \"key\": \"svg-2\" }]];\nconst IconEyeOff = createReactComponent(\"outline\", \"eye-off\", \"EyeOff\", __iconNode);\n\nexport { __iconNode, IconEyeOff as default };\n//# sourceMappingURL=IconEyeOff.mjs.map\n","/**\n * @license @tabler/icons-react v3.44.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\", \"key\": \"svg-1\" }]];\nconst IconEye = createReactComponent(\"outline\", \"eye\", \"Eye\", __iconNode);\n\nexport { __iconNode, IconEye as default };\n//# sourceMappingURL=IconEye.mjs.map\n","import {\n useState,\n type ComponentType,\n type InputHTMLAttributes,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n IconAlertCircleFilled,\n IconEye,\n IconEyeOff,\n} from \"@tabler/icons-react\";\nimport { Field } from \"@base-ui/react/field\";\nimport { cn } from \"../../utils/cn\";\n\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\n\n// Control padding per size. The wrapper carries a 2px inset (`p-0.5`) so the\n// control's border box — and the browser's autofill fill it paints — sits\n// inside the ring instead of over it; these paddings are the documented\n// effective padding (sm/md 12/8px, lg 14/10px) minus that 2px inset, so the\n// text position and total field height are unchanged.\nconst SIZE_PAD: Record<InputSize, string> = {\n // 16px on small viewports — iOS zooms into any focused field under 16px.\n sm: \"px-2.5 py-1.5 text-md md:text-base\",\n md: \"px-2.5 py-1.5 text-md\",\n lg: \"px-3 py-2 text-md\",\n};\n// Effective icon clearance minus the wrapper's 2px inset.\nconst LEADING_PAD: Record<InputSize, string> = {\n sm: \"pl-8.5\",\n md: \"pl-9.5\",\n lg: \"pl-10\",\n};\n// Icons are absolutely positioned, so they're placed from the wrapper's\n// padding edge — which, with no border, is the visible field edge; the\n// wrapper's `p-0.5` does not offset them.\nconst LEADING_ICON_POS: Record<InputSize, string> = {\n sm: \"left-3 size-4\",\n md: \"left-3 size-5\",\n lg: \"left-3.5 size-5\",\n};\n// Wrapper corner radius — `rounded-base` (12px) at every size; `lg` also gets\n// `squircle` superellipse smoothing (the ring is a box-shadow on this wrapper,\n// so it follows the border-radius automatically).\nconst SIZE_RADIUS: Record<InputSize, string> = {\n sm: \"rounded-base\",\n md: \"rounded-base\",\n lg: \"squircle rounded-base\",\n};\n// Concentric inner-curve cover, `lg` only. Nested corner radii must follow\n// innerRadius = outerRadius − inset, so the hairline's inner edge at a 12px\n// outer radius is 11px at rest (ring-1) and 10px when focused (ring-2).\n// Browsers derive that automatically for plain round corners, but with\n// `corner-shape: superellipse(...)` shipping engines still scale (rather than\n// offset) the inner shadow curve, which renders the ring visibly thicker at\n// the four corners (see w3c/csswg-drafts#12961). This ::before repaints the\n// field surface over everything inside the correct concentric curve — a round\n// radius is the right parallel-offset approximation of the mild superellipse —\n// so the ring reads as a uniform hairline in every engine. `isolate` +\n// `-z-10` slot the cover above the wrapper's background/ring but below the\n// control's text, icons, and autofill fill. `sm`/`md` have no corner-shape,\n// so the native (already concentric) rendering is kept there.\n// The ::before is absolutely positioned, so its inset is measured from the\n// wrapper's border box (border 0): 1px in at rest, 2px in when focused.\nconst SIZE_RING_COVER: Record<InputSize, string> = {\n sm: \"\",\n md: \"\",\n lg: cn(\n \"isolate before:pointer-events-none before:absolute before:-z-10 before:content-['']\",\n \"before:bg-pho-primary before:inset-px before:rounded-[calc(var(--radius-base)-1px)]\",\n // Invalid sits between rest (1px) and focus (2px) — keep the cover concentric.\n \"data-[invalid]:before:inset-[1.5px] data-[invalid]:before:rounded-[calc(var(--radius-base)-1.5px)]\",\n \"has-[input:focus-visible]:before:inset-0.5 has-[input:focus-visible]:before:rounded-[calc(var(--radius-base)-2px)]\",\n \"before:transition-[inset,border-radius] before:duration-100 before:ease-linear\",\n ),\n};\n// The control's border box sits 2px inside the wrapper (its `p-0.5` inset),\n// clear of both ring widths, so the browser's autofill fill paints inside the\n// hairline instead of over it. Rounding follows inner = outer − gap, derived\n// from the token with calc. Round (not squircle) — the parallel offset of\n// the wrapper's mild superellipse is effectively circular.\nconst SIZE_AUTOFILL_RADIUS: Record<InputSize, string> = {\n sm: \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n md: \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n lg: \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n};\n\nexport interface InputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n /** Field label (associated for accessibility). */\n label?: ReactNode;\n /** Helper text below the field; rendered in the error color when `invalid`. */\n hint?: ReactNode;\n /** Size variant. @default \"md\" */\n size?: InputSize;\n /** Render the invalid state (ring + icon + error-colored hint). */\n invalid?: boolean;\n /** Leading icon component (e.g. a Tabler icon). */\n icon?: ComponentType<{ className?: string }>;\n /** Node rendered at the right edge of the label row (e.g. \"Forgot?\"). */\n labelTrailing?: ReactNode;\n /** Class applied to the input wrapper. */\n wrapperClassName?: string;\n ref?: Ref<HTMLInputElement>;\n}\n\n/**\n * Text input built on Base UI `Field` (label/description a11y wiring) with\n * Pho's bordered surface, leading icon, invalid state, and a built-in password\n * reveal toggle.\n */\nexport function Input({\n label,\n hint,\n size = \"md\",\n invalid,\n icon: Icon,\n labelTrailing,\n disabled,\n required,\n type = \"text\",\n className,\n wrapperClassName,\n id,\n ref,\n ...props\n}: InputProps) {\n const [reveal, setReveal] = useState(false);\n const isPassword = type === \"password\";\n const resolvedType = isPassword && reveal ? \"text\" : type;\n const hasLeadingIcon = Boolean(Icon);\n const hasTrailingIcon = isPassword || invalid;\n\n return (\n <Field.Root\n disabled={disabled}\n className=\"group/field flex w-full flex-col gap-1.5\"\n >\n {label && (\n <div className=\"flex items-center justify-between gap-2\">\n <Field.Label className=\"text-pho-secondary flex cursor-default items-center gap-0.5 text-base font-medium\">\n {label}\n {required && <span className=\"text-pho-brand\">*</span>}\n </Field.Label>\n {labelTrailing}\n </div>\n )}\n\n <div\n data-invalid={invalid || undefined}\n className={cn(\n // Flat field surface — hairline ring only; elevation shadows are\n // reserved for floating layers (menus/popovers/dialogs). `p-0.5`\n // insets the control 2px (the focused ring width) so its background\n // and the browser's autofill fill nest inside the ring; the size\n // maps compensate so effective padding/height are unchanged.\n \"bg-pho-primary ring-pho-primary relative flex w-full items-center p-0.5 ring-1 transition-shadow duration-100 ease-linear ring-inset\",\n SIZE_RADIUS[size],\n SIZE_RING_COVER[size],\n \"has-[input:focus-visible]:ring-pho-brand has-[input:focus-visible]:ring-2\",\n // Invalid is mid-weight: thicker than the 1px rest hairline, thinner\n // than the 2px focus ring. Rest uses the subtle error ink; focus\n // steps up to the solid error (same hue, full opacity).\n \"data-[invalid]:ring-pho-error-subtle data-[invalid]:has-[input:focus-visible]:ring-pho-error data-[invalid]:ring-[1.5px]\",\n \"group-data-[disabled]/field:cursor-not-allowed group-data-[disabled]/field:opacity-50\",\n wrapperClassName,\n )}\n >\n {Icon && (\n <Icon\n className={cn(\n \"text-pho-secondary pointer-events-none absolute\",\n LEADING_ICON_POS[size],\n )}\n />\n )}\n\n <Field.Control\n ref={ref}\n id={id}\n type={resolvedType}\n required={required}\n {...props}\n className={cn(\n \"text-pho-primary placeholder:text-pho-placeholder m-0 w-full bg-transparent outline-none disabled:cursor-not-allowed\",\n SIZE_PAD[size],\n SIZE_AUTOFILL_RADIUS[size],\n hasLeadingIcon && LEADING_PAD[size],\n // 34px + the wrapper's 2px inset = the previous 36px clearance.\n hasTrailingIcon && \"pr-8.5\",\n className,\n )}\n />\n\n {invalid && !isPassword && (\n <IconAlertCircleFilled className=\"text-pho-error pointer-events-none absolute right-3 size-4\" />\n )}\n\n {isPassword && (\n <button\n type=\"button\"\n // Reachable by click but skipped in tab order so Tab moves field→field.\n tabIndex={-1}\n aria-label=\"Toggle password visibility\"\n onClick={() => setReveal((v) => !v)}\n className=\"text-pho-secondary hover:text-pho-secondary-hover absolute right-3 flex cursor-pointer items-center transition duration-100 ease-linear focus:outline-none\"\n >\n {reveal ? (\n <IconEyeOff className=\"size-4\" />\n ) : (\n <IconEye className=\"size-4\" />\n )}\n </button>\n )}\n </div>\n\n {hint && (\n <Field.Description\n className={cn(\n \"text-pho-description text-base\",\n invalid && \"text-pho-error\",\n )}\n >\n {hint}\n </Field.Description>\n )}\n </Field.Root>\n );\n}\n\nInput.displayName = \"Input\";\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"input-QSAUO30c.js","names":["__iconNode"],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconEyeOff.mjs","../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconEye.mjs","../../src/components/input/input.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M10.585 10.587a2 2 0 0 0 2.829 2.828\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M3 3l18 18\", \"key\": \"svg-2\" }]];\nconst IconEyeOff = createReactComponent(\"outline\", \"eye-off\", \"EyeOff\", __iconNode);\n\nexport { __iconNode, IconEyeOff as default };\n//# sourceMappingURL=IconEyeOff.mjs.map\n","/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6\", \"key\": \"svg-1\" }]];\nconst IconEye = createReactComponent(\"outline\", \"eye\", \"Eye\", __iconNode);\n\nexport { __iconNode, IconEye as default };\n//# sourceMappingURL=IconEye.mjs.map\n","import {\n useState,\n type ComponentType,\n type InputHTMLAttributes,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n IconAlertCircleFilled,\n IconEye,\n IconEyeOff,\n} from \"@tabler/icons-react\";\nimport { Field } from \"@base-ui/react/field\";\nimport { cn } from \"../../utils/cn\";\n\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\n\n// Control padding per size. The wrapper carries a 2px inset (`p-0.5`) so the\n// control's border box — and the browser's autofill fill it paints — sits\n// inside the ring instead of over it; these paddings are the documented\n// effective padding (sm/md 12/8px, lg 14/10px) minus that 2px inset, so the\n// text position and total field height are unchanged.\nconst SIZE_PAD: Record<InputSize, string> = {\n // 16px on small viewports — iOS zooms into any focused field under 16px.\n sm: \"px-2.5 py-1.5 text-md md:text-base\",\n md: \"px-2.5 py-1.5 text-md\",\n lg: \"px-3 py-2 text-md\",\n};\n// Effective icon clearance minus the wrapper's 2px inset.\nconst LEADING_PAD: Record<InputSize, string> = {\n sm: \"pl-8.5\",\n md: \"pl-9.5\",\n lg: \"pl-10\",\n};\n// Icons are absolutely positioned, so they're placed from the wrapper's\n// padding edge — which, with no border, is the visible field edge; the\n// wrapper's `p-0.5` does not offset them.\nconst LEADING_ICON_POS: Record<InputSize, string> = {\n sm: \"left-3 size-4\",\n md: \"left-3 size-5\",\n lg: \"left-3.5 size-5\",\n};\n// Wrapper corner radius — `rounded-base` (12px) at every size; `lg` also gets\n// `squircle` superellipse smoothing (the ring is a box-shadow on this wrapper,\n// so it follows the border-radius automatically).\nconst SIZE_RADIUS: Record<InputSize, string> = {\n sm: \"rounded-base\",\n md: \"rounded-base\",\n lg: \"squircle rounded-base\",\n};\n// Concentric inner-curve cover, `lg` only. Nested corner radii must follow\n// innerRadius = outerRadius − inset, so the hairline's inner edge at a 12px\n// outer radius is 11px at rest (ring-1) and 10px when focused (ring-2).\n// Browsers derive that automatically for plain round corners, but with\n// `corner-shape: superellipse(...)` shipping engines still scale (rather than\n// offset) the inner shadow curve, which renders the ring visibly thicker at\n// the four corners (see w3c/csswg-drafts#12961). This ::before repaints the\n// field surface over everything inside the correct concentric curve — a round\n// radius is the right parallel-offset approximation of the mild superellipse —\n// so the ring reads as a uniform hairline in every engine. `isolate` +\n// `-z-10` slot the cover above the wrapper's background/ring but below the\n// control's text, icons, and autofill fill. `sm`/`md` have no corner-shape,\n// so the native (already concentric) rendering is kept there.\n// The ::before is absolutely positioned, so its inset is measured from the\n// wrapper's border box (border 0): 1px in at rest, 2px in when focused.\nconst SIZE_RING_COVER: Record<InputSize, string> = {\n sm: \"\",\n md: \"\",\n lg: cn(\n \"isolate before:pointer-events-none before:absolute before:-z-10 before:content-['']\",\n \"before:bg-pho-primary before:inset-px before:rounded-[calc(var(--radius-base)-1px)]\",\n // Invalid sits between rest (1px) and focus (2px) — keep the cover concentric.\n \"data-[invalid]:before:inset-[1.5px] data-[invalid]:before:rounded-[calc(var(--radius-base)-1.5px)]\",\n \"has-[input:focus-visible]:before:inset-0.5 has-[input:focus-visible]:before:rounded-[calc(var(--radius-base)-2px)]\",\n \"before:transition-[inset,border-radius] before:duration-100 before:ease-linear\",\n ),\n};\n// The control's border box sits 2px inside the wrapper (its `p-0.5` inset),\n// clear of both ring widths, so the browser's autofill fill paints inside the\n// hairline instead of over it. Rounding follows inner = outer − gap, derived\n// from the token with calc. Round (not squircle) — the parallel offset of\n// the wrapper's mild superellipse is effectively circular.\nconst SIZE_AUTOFILL_RADIUS: Record<InputSize, string> = {\n sm: \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n md: \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n lg: \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n};\n\nexport interface InputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n /** Field label (associated for accessibility). */\n label?: ReactNode;\n /** Helper text below the field; rendered in the error color when `invalid`. */\n hint?: ReactNode;\n /** Size variant. @default \"md\" */\n size?: InputSize;\n /** Render the invalid state (ring + icon + error-colored hint). */\n invalid?: boolean;\n /** Leading icon component (e.g. a Tabler icon). */\n icon?: ComponentType<{ className?: string }>;\n /** Node rendered at the right edge of the label row (e.g. \"Forgot?\"). */\n labelTrailing?: ReactNode;\n /** Class applied to the input wrapper. */\n wrapperClassName?: string;\n ref?: Ref<HTMLInputElement>;\n}\n\n/**\n * Text input built on Base UI `Field` (label/description a11y wiring) with\n * Pho's bordered surface, leading icon, invalid state, and a built-in password\n * reveal toggle.\n */\nexport function Input({\n label,\n hint,\n size = \"md\",\n invalid,\n icon: Icon,\n labelTrailing,\n disabled,\n required,\n type = \"text\",\n className,\n wrapperClassName,\n id,\n ref,\n ...props\n}: InputProps) {\n const [reveal, setReveal] = useState(false);\n const isPassword = type === \"password\";\n const resolvedType = isPassword && reveal ? \"text\" : type;\n const hasLeadingIcon = Boolean(Icon);\n const hasTrailingIcon = isPassword || invalid;\n\n return (\n <Field.Root\n disabled={disabled}\n className=\"group/field flex w-full flex-col gap-1.5\"\n >\n {label && (\n <div className=\"flex items-center justify-between gap-2\">\n <Field.Label className=\"text-pho-secondary flex cursor-default items-center gap-0.5 text-base font-medium\">\n {label}\n {required && <span className=\"text-pho-brand\">*</span>}\n </Field.Label>\n {labelTrailing}\n </div>\n )}\n\n <div\n data-invalid={invalid || undefined}\n className={cn(\n // Flat field surface — hairline ring only; elevation shadows are\n // reserved for floating layers (menus/popovers/dialogs). `p-0.5`\n // insets the control 2px (the focused ring width) so its background\n // and the browser's autofill fill nest inside the ring; the size\n // maps compensate so effective padding/height are unchanged.\n \"bg-pho-primary ring-pho-primary relative flex w-full items-center p-0.5 ring-1 transition-shadow duration-100 ease-linear ring-inset\",\n SIZE_RADIUS[size],\n SIZE_RING_COVER[size],\n \"has-[input:focus-visible]:ring-pho-brand has-[input:focus-visible]:ring-2\",\n // Invalid is mid-weight: thicker than the 1px rest hairline, thinner\n // than the 2px focus ring. Rest uses the subtle error ink; focus\n // steps up to the solid error (same hue, full opacity).\n \"data-[invalid]:ring-pho-error-subtle data-[invalid]:has-[input:focus-visible]:ring-pho-error data-[invalid]:ring-[1.5px]\",\n \"group-data-[disabled]/field:cursor-not-allowed group-data-[disabled]/field:opacity-50\",\n wrapperClassName,\n )}\n >\n {Icon && (\n <Icon\n className={cn(\n \"text-pho-secondary pointer-events-none absolute\",\n LEADING_ICON_POS[size],\n )}\n />\n )}\n\n <Field.Control\n ref={ref}\n id={id}\n type={resolvedType}\n required={required}\n {...props}\n className={cn(\n \"text-pho-primary placeholder:text-pho-placeholder m-0 w-full bg-transparent outline-none disabled:cursor-not-allowed\",\n SIZE_PAD[size],\n SIZE_AUTOFILL_RADIUS[size],\n hasLeadingIcon && LEADING_PAD[size],\n // 34px + the wrapper's 2px inset = the previous 36px clearance.\n hasTrailingIcon && \"pr-8.5\",\n className,\n )}\n />\n\n {invalid && !isPassword && (\n <IconAlertCircleFilled className=\"text-pho-error pointer-events-none absolute right-3 size-4\" />\n )}\n\n {isPassword && (\n <button\n type=\"button\"\n // Reachable by click but skipped in tab order so Tab moves field→field.\n tabIndex={-1}\n aria-label=\"Toggle password visibility\"\n onClick={() => setReveal((v) => !v)}\n className=\"text-pho-secondary hover:text-pho-secondary-hover absolute right-3 flex cursor-pointer items-center transition duration-100 ease-linear focus:outline-none\"\n >\n {reveal ? (\n <IconEyeOff className=\"size-4\" />\n ) : (\n <IconEye className=\"size-4\" />\n )}\n </button>\n )}\n </div>\n\n {hint && (\n <Field.Description\n className={cn(\n \"text-pho-description text-base\",\n invalid && \"text-pho-error\",\n )}\n >\n {hint}\n </Field.Description>\n )}\n </Field.Root>\n );\n}\n\nInput.displayName = \"Input\";\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as i } from "./cn-DTiB6ek_.js";
2
+ import { t as i } from "./cn-ChIgwEl3.js";
3
3
  import { createContext as b, useContext as p } from "react";
4
4
  import { jsx as n } from "react/jsx-runtime";
5
5
  import { Field as f } from "@base-ui/react/field";
@@ -82,4 +82,4 @@ export {
82
82
  R as t
83
83
  };
84
84
 
85
- //# sourceMappingURL=input-group-D6dlma8k.js.map
85
+ //# sourceMappingURL=input-group-5AtpIhC_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-group-D6dlma8k.js","names":[],"sources":["../../src/components/input-group/input-group.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n type ComponentProps,\n type ElementType,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type PointerEvent,\n type Ref,\n} from \"react\";\nimport { Field } from \"@base-ui/react/field\";\nimport { Separator as BaseSeparator } from \"@base-ui/react/separator\";\nimport { cn } from \"../../utils/cn\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\nexport type InputGroupSize = \"sm\" | \"md\" | \"lg\";\n\n/** Lets `Addon` and the control read the Root's size/invalid state. */\nconst InputGroupContext = createContext<{\n size: InputGroupSize;\n invalid: boolean;\n}>({ size: \"md\", invalid: false });\n\n// Mirrors Input's size math (see input.tsx): the group surface carries the\n// horizontal padding and text scale, the control carries the vertical\n// padding. Effective metrics — sm/md 12/8px, lg 14/10px — land the same\n// 36/40/44px field heights, so grouped and plain inputs align in a form.\nconst SIZE_ROOT: Record<InputGroupSize, string> = {\n // 16px on small viewports — iOS zooms into any focused field under 16px.\n sm: \"gap-2 px-3 text-md md:text-base\",\n md: \"gap-2 px-3 text-md\",\n lg: \"gap-2 px-3.5 text-md\",\n};\n// `my-0.5` insets the control 2px (the focused ring width) so the browser's\n// autofill fill nests inside the ring; `py` makes up the rest of the height.\nconst SIZE_CONTROL: Record<InputGroupSize, string> = {\n sm: \"my-0.5 py-1.5\",\n md: \"my-0.5 py-1.5\",\n lg: \"my-0.5 py-2\",\n};\n// In-field icon size per group size — same scale as Input's leading icon.\nconst SIZE_ADDON_ICON: Record<InputGroupSize, string> = {\n sm: \"[&_svg]:size-4\",\n md: \"[&_svg]:size-5\",\n lg: \"[&_svg]:size-5\",\n};\n// `lg` gets the squircle treatment like Input; sm/md stay plain round.\nconst SIZE_RADIUS: Record<InputGroupSize, string> = {\n sm: \"rounded-base\",\n md: \"rounded-base\",\n lg: \"squircle rounded-base\",\n};\n// Concentric inner-curve cover for the `lg` squircle — same engine workaround\n// as Input (see input.tsx `SIZE_RING_COVER` for the full story).\nconst SIZE_RING_COVER: Record<InputGroupSize, string> = {\n sm: \"\",\n md: \"\",\n lg: cn(\n \"isolate before:pointer-events-none before:absolute before:-z-10 before:content-['']\",\n \"before:bg-pho-primary before:inset-px before:rounded-[calc(var(--radius-base)-1px)]\",\n // Invalid sits between rest (1px) and focus (2px) — keep the cover concentric.\n \"data-[invalid]:before:inset-[1.5px] data-[invalid]:before:rounded-[calc(var(--radius-base)-1.5px)]\",\n \"has-[:focus-visible]:before:inset-0.5 has-[:focus-visible]:before:rounded-[calc(var(--radius-base)-2px)]\",\n \"before:transition-[inset,border-radius] before:duration-100 before:ease-linear\",\n ),\n};\n\nexport interface InputGroupRootProps extends HTMLAttributes<HTMLDivElement> {\n /** Size variant, matching Input's scale. @default \"md\" */\n size?: InputGroupSize;\n /** Render the invalid state (error ring; `aria-invalid` on the control). */\n invalid?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * The shared field surface: one hairline ring around the control and its\n * addons, with the same focus / invalid / disabled treatment as `Input`.\n * Clicking anywhere on the surface (addon text, icons, blank space) focuses\n * the control, so the whole group reads as a single field.\n */\nfunction Root({\n size = \"md\",\n invalid,\n className,\n onPointerDown,\n ref,\n ...props\n}: InputGroupRootProps) {\n const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n if (event.defaultPrevented) return;\n // Interactive children keep their own pointer behavior (and the control\n // itself keeps native caret placement).\n const target = event.target as HTMLElement;\n if (target.closest(\"input, button, a, select, textarea, label\")) return;\n const input = event.currentTarget.querySelector(\"input\");\n if (!input || input.disabled) return;\n // Focus the control instead of the wrapper — and don't blur it again.\n event.preventDefault();\n input.focus();\n };\n\n return (\n <InputGroupContext.Provider value={{ size, invalid: Boolean(invalid) }}>\n <div\n ref={ref}\n data-invalid={invalid || undefined}\n onPointerDown={handlePointerDown}\n className={cn(\n // Flat field surface — hairline ring only, same as Input; elevation\n // shadows are reserved for floating layers.\n \"bg-pho-primary ring-pho-primary relative flex w-full cursor-text items-center ring-1 transition-shadow duration-100 ease-linear ring-inset\",\n SIZE_ROOT[size],\n SIZE_RADIUS[size],\n SIZE_RING_COVER[size],\n // Any focusable child (input, a Select trigger, an addon button)\n // lights the shared ring — including an open Select popup.\n \"has-[:focus-visible]:ring-pho-brand has-[:focus-visible]:ring-2\",\n \"has-[button[data-popup-open]]:ring-pho-brand has-[button[data-popup-open]]:ring-2\",\n // Invalid is mid-weight: thicker than the 1px rest hairline, thinner\n // than the 2px focus / open ring. Rest uses the subtle error ink;\n // focus / open steps up to the solid error.\n \"data-[invalid]:ring-pho-error-subtle data-[invalid]:has-[:focus-visible]:ring-pho-error data-[invalid]:has-[button[data-popup-open]]:ring-pho-error data-[invalid]:ring-[1.5px]\",\n \"has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50\",\n className,\n )}\n {...props}\n />\n </InputGroupContext.Provider>\n );\n}\n\nexport interface InputGroupInputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n ref?: Ref<HTMLInputElement>;\n}\n\n/**\n * The text control. Rendered as Base UI `Field.Control`, so inside a\n * `Field.Root` it picks up the label and description wiring automatically;\n * standalone it behaves as a plain `<input>` (pass `aria-label` then).\n */\nfunction GroupInput({ className, ref, ...props }: InputGroupInputProps) {\n const { size, invalid } = useContext(InputGroupContext);\n return (\n <Field.Control\n ref={ref}\n aria-invalid={invalid || undefined}\n {...props}\n className={cn(\n \"text-pho-primary placeholder:text-pho-placeholder m-0 w-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed\",\n // Rounding for the autofill fill nested 2px inside the ring.\n \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n SIZE_CONTROL[size],\n className,\n )}\n />\n );\n}\n\n/**\n * Inline content beside the control — prefix/suffix text, an icon, a `Kbd`\n * hint, or a small button. Text and icons render in the secondary tone so the\n * value stays the loudest thing on the surface.\n */\nfunction Addon({\n className,\n ref,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { ref?: Ref<HTMLDivElement> }) {\n const { size } = useContext(InputGroupContext);\n return (\n <div\n ref={ref}\n className={cn(\n \"text-pho-secondary flex shrink-0 items-center gap-1 select-none\",\n \"[&_svg]:shrink-0\",\n SIZE_ADDON_ICON[size],\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * A hairline between segments — turns an addon into a boxed section\n * (`https:// │ workspace │ .photon.dev`).\n */\nfunction GroupSeparator({\n className,\n orientation = \"vertical\",\n ...props\n}: StyledProps<typeof BaseSeparator>) {\n return (\n <BaseSeparator\n orientation={orientation}\n className={cn(\n // `my-0.5` keeps the line 2px clear of the ring (children paint over\n // the inset box-shadow, so a full-bleed line would notch it) — the\n // same inset the control itself uses, covering the focused 2px ring.\n \"my-0.5 w-px shrink-0 self-stretch bg-[var(--border-color-pho-secondary)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Input Group — one field surface shared by a text control and its addons:\n * prefix/suffix text, icons, keyboard hints, or a trailing button. Same\n * ring, sizes, and focus / invalid / disabled behavior as `Input`, so grouped\n * and plain fields align in the same form. For a leading icon alone, plain\n * `Input` with `icon` is enough.\n */\nexport const InputGroup = {\n Root,\n Input: GroupInput,\n Addon,\n Separator: GroupSeparator,\n};\n"],"mappings":";;;;;;AAyBA,IAAM,IAAoB,EAGvB;AAAA,EAAE,MAAM;AAAA,EAAM,SAAS;AAAM,CAAC,GAM3B,IAA4C;AAAA,EAEhD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAGM,IAA+C;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEM,IAAkD;AAAA,EACtD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEM,IAA8C;AAAA,EAClD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAGM,IAAkD;AAAA,EACtD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,EACF,uFACA,uFAEA,sGACA,4GACA,gFACF;AACF;AAgBA,SAAS,EAAK,EACZ,MAAA,IAAO,MACP,SAAA,GACA,WAAA,GACA,eAAA,GACA,KAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAA,CAAqB,MAAwC;AAMjE,QALA,IAAgB,CAAK,GACjB,EAAM,oBAGK,EAAM,OACV,QAAQ,2CAA2C,EAAG;AACjE,UAAM,IAAQ,EAAM,cAAc,cAAc,OAAO;AACvD,IAAI,CAAC,KAAS,EAAM,aAEpB,EAAM,eAAe,GACrB,EAAM,MAAM;AAAA,EACd;AAEA,SACE,gBAAA,EAAC,EAAkB,UAAnB;AAAA,IAA4B,OAAO;AAAA,MAAE,MAAA;AAAA,MAAM,SAAS,EAAQ;AAAA,IAAS;AAAA,cACnE,gBAAA,EAAC,OAAD;AAAA,MACO,KAAA;AAAA,MACL,gBAAc,KAAW;AAAA,MACzB,eAAe;AAAA,MACf,WAAW,EAGT,8IACA,EAAU,CAAA,GACV,EAAY,CAAA,GACZ,EAAgB,CAAA,GAGhB,mEACA,qFAIA,mLACA,2EACA,CACF;AAAA,MACA,GAAI;AAAA,IACL,CAAA;AAAA,EACyB,CAAA;AAEhC;AAcA,SAAS,EAAW,EAAE,WAAA,GAAW,KAAA,GAAK,GAAG,EAAA,GAA+B;AACtE,QAAM,EAAE,MAAA,GAAM,SAAA,EAAA,IAAY,EAAW,CAAiB;AACtD,SACE,gBAAA,EAAC,EAAM,SAAP;AAAA,IACO,KAAA;AAAA,IACL,gBAAc,KAAW;AAAA,IACzB,GAAI;AAAA,IACJ,WAAW,EACT,uIAEA,mDACA,EAAa,CAAA,GACb,CACF;AAAA,EACD,CAAA;AAEL;AAOA,SAAS,EAAM,EACb,WAAA,GACA,KAAA,GACA,GAAG,EAAA,GAC8D;AACjE,QAAM,EAAE,MAAA,EAAA,IAAS,EAAW,CAAiB;AAC7C,SACE,gBAAA,EAAC,OAAD;AAAA,IACO,KAAA;AAAA,IACL,WAAW,EACT,mEACA,oBACA,EAAgB,CAAA,GAChB,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAMA,SAAS,EAAe,EACtB,WAAA,GACA,aAAA,IAAc,YACd,GAAG,EAAA,GACiC;AACpC,SACE,gBAAA,EAAC,GAAD;AAAA,IACe,aAAA;AAAA,IACb,WAAW,EAIT,4EACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AASA,IAAa,IAAa;AAAA,EACxB,MAAA;AAAA,EACA,OAAO;AAAA,EACP,OAAA;AAAA,EACA,WAAW;AACb"}
1
+ {"version":3,"file":"input-group-5AtpIhC_.js","names":[],"sources":["../../src/components/input-group/input-group.tsx"],"sourcesContent":["import {\n createContext,\n useContext,\n type ComponentProps,\n type ElementType,\n type HTMLAttributes,\n type InputHTMLAttributes,\n type PointerEvent,\n type Ref,\n} from \"react\";\nimport { Field } from \"@base-ui/react/field\";\nimport { Separator as BaseSeparator } from \"@base-ui/react/separator\";\nimport { cn } from \"../../utils/cn\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\nexport type InputGroupSize = \"sm\" | \"md\" | \"lg\";\n\n/** Lets `Addon` and the control read the Root's size/invalid state. */\nconst InputGroupContext = createContext<{\n size: InputGroupSize;\n invalid: boolean;\n}>({ size: \"md\", invalid: false });\n\n// Mirrors Input's size math (see input.tsx): the group surface carries the\n// horizontal padding and text scale, the control carries the vertical\n// padding. Effective metrics — sm/md 12/8px, lg 14/10px — land the same\n// 36/40/44px field heights, so grouped and plain inputs align in a form.\nconst SIZE_ROOT: Record<InputGroupSize, string> = {\n // 16px on small viewports — iOS zooms into any focused field under 16px.\n sm: \"gap-2 px-3 text-md md:text-base\",\n md: \"gap-2 px-3 text-md\",\n lg: \"gap-2 px-3.5 text-md\",\n};\n// `my-0.5` insets the control 2px (the focused ring width) so the browser's\n// autofill fill nests inside the ring; `py` makes up the rest of the height.\nconst SIZE_CONTROL: Record<InputGroupSize, string> = {\n sm: \"my-0.5 py-1.5\",\n md: \"my-0.5 py-1.5\",\n lg: \"my-0.5 py-2\",\n};\n// In-field icon size per group size — same scale as Input's leading icon.\nconst SIZE_ADDON_ICON: Record<InputGroupSize, string> = {\n sm: \"[&_svg]:size-4\",\n md: \"[&_svg]:size-5\",\n lg: \"[&_svg]:size-5\",\n};\n// `lg` gets the squircle treatment like Input; sm/md stay plain round.\nconst SIZE_RADIUS: Record<InputGroupSize, string> = {\n sm: \"rounded-base\",\n md: \"rounded-base\",\n lg: \"squircle rounded-base\",\n};\n// Concentric inner-curve cover for the `lg` squircle — same engine workaround\n// as Input (see input.tsx `SIZE_RING_COVER` for the full story).\nconst SIZE_RING_COVER: Record<InputGroupSize, string> = {\n sm: \"\",\n md: \"\",\n lg: cn(\n \"isolate before:pointer-events-none before:absolute before:-z-10 before:content-['']\",\n \"before:bg-pho-primary before:inset-px before:rounded-[calc(var(--radius-base)-1px)]\",\n // Invalid sits between rest (1px) and focus (2px) — keep the cover concentric.\n \"data-[invalid]:before:inset-[1.5px] data-[invalid]:before:rounded-[calc(var(--radius-base)-1.5px)]\",\n \"has-[:focus-visible]:before:inset-0.5 has-[:focus-visible]:before:rounded-[calc(var(--radius-base)-2px)]\",\n \"before:transition-[inset,border-radius] before:duration-100 before:ease-linear\",\n ),\n};\n\nexport interface InputGroupRootProps extends HTMLAttributes<HTMLDivElement> {\n /** Size variant, matching Input's scale. @default \"md\" */\n size?: InputGroupSize;\n /** Render the invalid state (error ring; `aria-invalid` on the control). */\n invalid?: boolean;\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * The shared field surface: one hairline ring around the control and its\n * addons, with the same focus / invalid / disabled treatment as `Input`.\n * Clicking anywhere on the surface (addon text, icons, blank space) focuses\n * the control, so the whole group reads as a single field.\n */\nfunction Root({\n size = \"md\",\n invalid,\n className,\n onPointerDown,\n ref,\n ...props\n}: InputGroupRootProps) {\n const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {\n onPointerDown?.(event);\n if (event.defaultPrevented) return;\n // Interactive children keep their own pointer behavior (and the control\n // itself keeps native caret placement).\n const target = event.target as HTMLElement;\n if (target.closest(\"input, button, a, select, textarea, label\")) return;\n const input = event.currentTarget.querySelector(\"input\");\n if (!input || input.disabled) return;\n // Focus the control instead of the wrapper — and don't blur it again.\n event.preventDefault();\n input.focus();\n };\n\n return (\n <InputGroupContext.Provider value={{ size, invalid: Boolean(invalid) }}>\n <div\n ref={ref}\n data-invalid={invalid || undefined}\n onPointerDown={handlePointerDown}\n className={cn(\n // Flat field surface — hairline ring only, same as Input; elevation\n // shadows are reserved for floating layers.\n \"bg-pho-primary ring-pho-primary relative flex w-full cursor-text items-center ring-1 transition-shadow duration-100 ease-linear ring-inset\",\n SIZE_ROOT[size],\n SIZE_RADIUS[size],\n SIZE_RING_COVER[size],\n // Any focusable child (input, a Select trigger, an addon button)\n // lights the shared ring — including an open Select popup.\n \"has-[:focus-visible]:ring-pho-brand has-[:focus-visible]:ring-2\",\n \"has-[button[data-popup-open]]:ring-pho-brand has-[button[data-popup-open]]:ring-2\",\n // Invalid is mid-weight: thicker than the 1px rest hairline, thinner\n // than the 2px focus / open ring. Rest uses the subtle error ink;\n // focus / open steps up to the solid error.\n \"data-[invalid]:ring-pho-error-subtle data-[invalid]:has-[:focus-visible]:ring-pho-error data-[invalid]:has-[button[data-popup-open]]:ring-pho-error data-[invalid]:ring-[1.5px]\",\n \"has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50\",\n className,\n )}\n {...props}\n />\n </InputGroupContext.Provider>\n );\n}\n\nexport interface InputGroupInputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n ref?: Ref<HTMLInputElement>;\n}\n\n/**\n * The text control. Rendered as Base UI `Field.Control`, so inside a\n * `Field.Root` it picks up the label and description wiring automatically;\n * standalone it behaves as a plain `<input>` (pass `aria-label` then).\n */\nfunction GroupInput({ className, ref, ...props }: InputGroupInputProps) {\n const { size, invalid } = useContext(InputGroupContext);\n return (\n <Field.Control\n ref={ref}\n aria-invalid={invalid || undefined}\n {...props}\n className={cn(\n \"text-pho-primary placeholder:text-pho-placeholder m-0 w-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed\",\n // Rounding for the autofill fill nested 2px inside the ring.\n \"autofill:rounded-[calc(var(--radius-base)-2px)]\",\n SIZE_CONTROL[size],\n className,\n )}\n />\n );\n}\n\n/**\n * Inline content beside the control — prefix/suffix text, an icon, a `Kbd`\n * hint, or a small button. Text and icons render in the secondary tone so the\n * value stays the loudest thing on the surface.\n */\nfunction Addon({\n className,\n ref,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { ref?: Ref<HTMLDivElement> }) {\n const { size } = useContext(InputGroupContext);\n return (\n <div\n ref={ref}\n className={cn(\n \"text-pho-secondary flex shrink-0 items-center gap-1 select-none\",\n \"[&_svg]:shrink-0\",\n SIZE_ADDON_ICON[size],\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * A hairline between segments — turns an addon into a boxed section\n * (`https:// │ workspace │ .photon.dev`).\n */\nfunction GroupSeparator({\n className,\n orientation = \"vertical\",\n ...props\n}: StyledProps<typeof BaseSeparator>) {\n return (\n <BaseSeparator\n orientation={orientation}\n className={cn(\n // `my-0.5` keeps the line 2px clear of the ring (children paint over\n // the inset box-shadow, so a full-bleed line would notch it) — the\n // same inset the control itself uses, covering the focused 2px ring.\n \"my-0.5 w-px shrink-0 self-stretch bg-[var(--border-color-pho-secondary)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Input Group — one field surface shared by a text control and its addons:\n * prefix/suffix text, icons, keyboard hints, or a trailing button. Same\n * ring, sizes, and focus / invalid / disabled behavior as `Input`, so grouped\n * and plain fields align in the same form. For a leading icon alone, plain\n * `Input` with `icon` is enough.\n */\nexport const InputGroup = {\n Root,\n Input: GroupInput,\n Addon,\n Separator: GroupSeparator,\n};\n"],"mappings":";;;;;;AAyBA,IAAM,IAAoB,EAGvB;AAAA,EAAE,MAAM;AAAA,EAAM,SAAS;AAAM,CAAC,GAM3B,IAA4C;AAAA,EAEhD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAGM,IAA+C;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEM,IAAkD;AAAA,EACtD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEM,IAA8C;AAAA,EAClD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAGM,IAAkD;AAAA,EACtD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,EACF,uFACA,uFAEA,sGACA,4GACA,gFACF;AACF;AAgBA,SAAS,EAAK,EACZ,MAAA,IAAO,MACP,SAAA,GACA,WAAA,GACA,eAAA,GACA,KAAA,GACA,GAAG,EAAA,GACmB;AACtB,QAAM,IAAA,CAAqB,MAAwC;AAMjE,QALA,IAAgB,CAAK,GACjB,EAAM,oBAGK,EAAM,OACV,QAAQ,2CAA2C,EAAG;AACjE,UAAM,IAAQ,EAAM,cAAc,cAAc,OAAO;AACvD,IAAI,CAAC,KAAS,EAAM,aAEpB,EAAM,eAAe,GACrB,EAAM,MAAM;AAAA,EACd;AAEA,SACE,gBAAA,EAAC,EAAkB,UAAnB;AAAA,IAA4B,OAAO;AAAA,MAAE,MAAA;AAAA,MAAM,SAAS,EAAQ;AAAA,IAAS;AAAA,IACnE,UAAA,gBAAA,EAAC,OAAD;AAAA,MACO,KAAA;AAAA,MACL,gBAAc,KAAW;AAAA,MACzB,eAAe;AAAA,MACf,WAAW,EAGT,8IACA,EAAU,CAAA,GACV,EAAY,CAAA,GACZ,EAAgB,CAAA,GAGhB,mEACA,qFAIA,mLACA,2EACA,CACF;AAAA,MACA,GAAI;AAAA,IACL,CAAA;AAAA,EACyB,CAAA;AAEhC;AAcA,SAAS,EAAW,EAAE,WAAA,GAAW,KAAA,GAAK,GAAG,EAAA,GAA+B;AACtE,QAAM,EAAE,MAAA,GAAM,SAAA,EAAA,IAAY,EAAW,CAAiB;AACtD,SACE,gBAAA,EAAC,EAAM,SAAP;AAAA,IACO,KAAA;AAAA,IACL,gBAAc,KAAW;AAAA,IACzB,GAAI;AAAA,IACJ,WAAW,EACT,uIAEA,mDACA,EAAa,CAAA,GACb,CACF;AAAA,EACD,CAAA;AAEL;AAOA,SAAS,EAAM,EACb,WAAA,GACA,KAAA,GACA,GAAG,EAAA,GAC8D;AACjE,QAAM,EAAE,MAAA,EAAA,IAAS,EAAW,CAAiB;AAC7C,SACE,gBAAA,EAAC,OAAD;AAAA,IACO,KAAA;AAAA,IACL,WAAW,EACT,mEACA,oBACA,EAAgB,CAAA,GAChB,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AAMA,SAAS,EAAe,EACtB,WAAA,GACA,aAAA,IAAc,YACd,GAAG,EAAA,GACiC;AACpC,SACE,gBAAA,EAAC,GAAD;AAAA,IACe,aAAA;AAAA,IACb,WAAW,EAIT,4EACA,CACF;AAAA,IACA,GAAI;AAAA,EACL,CAAA;AAEL;AASA,IAAa,IAAa;AAAA,EACxB,MAAA;AAAA,EACA,OAAO;AAAA,EACP,OAAA;AAAA,EACA,WAAW;AACb"}