@ngrok/mantle 0.73.1 → 0.73.2

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 (96) hide show
  1. package/dist/accordion.d.ts +1 -1
  2. package/dist/agent.json +1 -1
  3. package/dist/alert-dialog.d.ts +8 -8
  4. package/dist/alert.d.ts +3 -3
  5. package/dist/anchor.d.ts +1 -1
  6. package/dist/{as-child-C2PttRwz.d.ts → as-child-CpZKMqTE.d.ts} +1 -1
  7. package/dist/badge.d.ts +2 -2
  8. package/dist/{button-CoGmk7_d.d.ts → button-DbHFERMB.d.ts} +6 -6
  9. package/dist/button.d.ts +3 -3
  10. package/dist/card.d.ts +1 -1
  11. package/dist/checkbox.d.ts +1 -1
  12. package/dist/code-block.d.ts +3 -3
  13. package/dist/code-block_highlight-utils.d.ts +1 -1
  14. package/dist/code.d.ts +1 -1
  15. package/dist/color.d.ts +1 -1
  16. package/dist/combobox.d.ts +2 -2
  17. package/dist/command.d.ts +4 -4
  18. package/dist/data-table.d.ts +3 -3
  19. package/dist/{deep-non-nullable-CT7hWCFG.d.ts → deep-non-nullable-Xu7ckQM6.d.ts} +1 -1
  20. package/dist/description-list.d.ts +1 -1
  21. package/dist/dialog.d.ts +2 -2
  22. package/dist/{direction-CVntIxOS.d.ts → direction-D9IZ1wW6.d.ts} +1 -1
  23. package/dist/{dropdown-menu-DVvNlA72.d.ts → dropdown-menu-CvOiQUSZ.d.ts} +2 -2
  24. package/dist/dropdown-menu.d.ts +1 -1
  25. package/dist/empty.d.ts +2 -2
  26. package/dist/field-context-B7Z1cmZW.js +2 -0
  27. package/dist/field-context-B7Z1cmZW.js.map +1 -0
  28. package/dist/field.d.ts +138 -67
  29. package/dist/field.js +1 -1
  30. package/dist/field.js.map +1 -1
  31. package/dist/hooks.d.ts +3 -3
  32. package/dist/hooks.js +1 -1
  33. package/dist/{icon-D_BMDi_q.d.ts → icon-BJ7q2RXZ.d.ts} +2 -2
  34. package/dist/{icon-button-Dty-yfE2.d.ts → icon-button-BDTb-lxs.d.ts} +3 -3
  35. package/dist/icon.d.ts +3 -3
  36. package/dist/icons.d.ts +3 -3
  37. package/dist/{in-view-DdIrfU4u.d.ts → in-view-BUgyu-Tk.d.ts} +1 -1
  38. package/dist/{in-view-BLZVEGFC.js → in-view-CeVqeGbv.js} +1 -1
  39. package/dist/{in-view-BLZVEGFC.js.map → in-view-CeVqeGbv.js.map} +1 -1
  40. package/dist/{index-TI92Xpg5.d.ts → index-BbZBDzPh.d.ts} +1 -1
  41. package/dist/{index-j46YISoN.d.ts → index-BhlxYL_y.d.ts} +1 -1
  42. package/dist/{index-DIBURJqf.d.ts → index-CWXKBva-.d.ts} +3 -3
  43. package/dist/{index-CVk4t5hk.d.ts → index-DS_4n2eb.d.ts} +1 -1
  44. package/dist/input.d.ts +4 -4
  45. package/dist/input.js +1 -1
  46. package/dist/{is-input-CEEoHxXN.js → is-input-CtUHJGgL.js} +1 -1
  47. package/dist/{is-input-CEEoHxXN.js.map → is-input-CtUHJGgL.js.map} +1 -1
  48. package/dist/llms.txt +1 -1
  49. package/dist/media-object.d.ts +1 -1
  50. package/dist/multi-select.d.ts +2 -2
  51. package/dist/multi-select.js +1 -1
  52. package/dist/multi-select.js.map +1 -1
  53. package/dist/otp-input.d.ts +2 -2
  54. package/dist/otp-input.js +1 -1
  55. package/dist/otp-input.js.map +1 -1
  56. package/dist/pagination.d.ts +3 -3
  57. package/dist/pagination.js +1 -1
  58. package/dist/{primitive-Ed9cel2r.d.ts → primitive-qkxTYBUY.d.ts} +1 -1
  59. package/dist/radio-group.d.ts +1 -1
  60. package/dist/radio-group.js +1 -1
  61. package/dist/radio-group.js.map +1 -1
  62. package/dist/{resolve-pre-rendered-props-DxvamgE6.d.ts → resolve-pre-rendered-props-BONSCwYA.d.ts} +1 -1
  63. package/dist/sandboxed-on-click.d.ts +1 -1
  64. package/dist/select-B7orOUPj.js +2 -0
  65. package/dist/select-B7orOUPj.js.map +1 -0
  66. package/dist/{select-8ymlL8kC.d.ts → select-SZFFzYs0.d.ts} +3 -3
  67. package/dist/select.d.ts +1 -1
  68. package/dist/select.js +1 -1
  69. package/dist/separator.d.ts +1 -1
  70. package/dist/sheet.d.ts +2 -2
  71. package/dist/slider.d.ts +17 -0
  72. package/dist/slider.js +1 -1
  73. package/dist/slider.js.map +1 -1
  74. package/dist/slot.d.ts +1 -1
  75. package/dist/split-button.d.ts +3 -3
  76. package/dist/{svg-only-CLbMy439.d.ts → svg-only-D4uqM1OC.d.ts} +2 -2
  77. package/dist/switch.d.ts +1 -1
  78. package/dist/{table-BWxS7pXj.d.ts → table-CjSQkfZe.d.ts} +1 -1
  79. package/dist/table.d.ts +1 -1
  80. package/dist/tabs.js +1 -1
  81. package/dist/text-area.d.ts +1 -1
  82. package/dist/theme.d.ts +2 -2
  83. package/dist/{themes-f2W5S6xS.d.ts → themes-FPux5kIu.d.ts} +1 -1
  84. package/dist/toast.d.ts +3 -3
  85. package/dist/{types-DnghL1WE.d.ts → types-QKZ5fvaQ.d.ts} +1 -1
  86. package/dist/types.d.ts +5 -5
  87. package/dist/{use-prefers-reduced-motion-YUurmkwx.js → use-prefers-reduced-motion-Bpx8G3UT.js} +1 -1
  88. package/dist/{use-prefers-reduced-motion-YUurmkwx.js.map → use-prefers-reduced-motion-Bpx8G3UT.js.map} +1 -1
  89. package/dist/utils.d.ts +2 -2
  90. package/dist/utils.js +1 -1
  91. package/dist/{validation-DF1z7YDr.d.ts → validation-CBSOmooP.d.ts} +1 -1
  92. package/dist/{variant-props-B4io4uA_.d.ts → variant-props-BZbM__kQ.d.ts} +2 -2
  93. package/dist/{with-style-props-CW8buMhK.d.ts → with-style-props-xzZLnIrF.d.ts} +1 -1
  94. package/package.json +1 -1
  95. package/dist/select-BBB_e15a.js +0 -2
  96. package/dist/select-BBB_e15a.js.map +0 -1
package/dist/field.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"field.js","names":[],"sources":["../src/components/field/field-context.ts","../src/components/field/error-helpers.ts","../src/components/field/field.tsx","../src/components/field/field-error-messages.ts"],"sourcesContent":["import { createContext, type ComponentProps } from \"react\";\nimport { parseValidation, type ValidationProp, type ValidationState } from \"./validation.js\";\n\n/**\n * ARIA props that `Field.Control` applies to the field's focusable control.\n */\ntype FieldControlAriaProps = {\n\t/**\n\t * IDREFs for helper or error text that describe the focusable control.\n\t */\n\t\"aria-describedby\"?: string;\n\t/**\n\t * IDREFs for error text that represent the control's current error state.\n\t */\n\t\"aria-errormessage\"?: string;\n\t/**\n\t * The resolved ARIA invalid state for the focusable control.\n\t */\n\t\"aria-invalid\"?: ComponentProps<\"input\">[\"aria-invalid\"];\n};\n\n/**\n * Context value owned by `Field.Item` and consumed by message/control parts.\n *\n * `Field.Item` owns the two stable slot IDs (one for the description, one for\n * the error list) so consumers don't manage ARIA wiring themselves. The IDs\n * are emitted unconditionally; ARIA treats unresolved IDREFs as no-ops, so\n * dangling IDs (when no description or error list is rendered) are harmless.\n */\ntype FieldItemContextValue = {\n\t/**\n\t * Stable ID for the rendered `Field.Description` slot, generated once per\n\t * `Field.Item`.\n\t */\n\tdescriptionId: string;\n\t/**\n\t * Stable ID for the rendered `Field.Errors` / `Field.ErrorList` slot,\n\t * generated once per `Field.Item`.\n\t */\n\terrorId: string;\n\t/**\n\t * `true` while a non-empty `Field.Errors` / `Field.ErrorList` is mounted\n\t * under this `Field.Item`. Used by `Field.Item` to infer an `\"error\"`\n\t * validation state when no explicit `validation` prop is supplied.\n\t */\n\thasErrors: boolean;\n\t/**\n\t * Marks a non-empty `Field.Errors` / `Field.ErrorList` as mounted. Returns\n\t * its cleanup callback.\n\t */\n\tregisterError: () => () => void;\n\t/**\n\t * Validation state inferred or supplied by the surrounding `Field.Item`.\n\t */\n\tvalidation?: ValidationState;\n};\n\n/**\n * Options for resolving the ARIA props that `Field.Control` applies.\n */\ntype ResolveFieldControlAriaPropsOptions = {\n\t/**\n\t * Explicit `aria-invalid` value lifted off the control's child element.\n\t * A non-false value forces the resolved validation state to `\"error\"`.\n\t */\n\t\"aria-invalid\"?: ComponentProps<\"input\">[\"aria-invalid\"];\n\t/**\n\t * The nearest `Field.Item` context, when the control is rendered inside one.\n\t */\n\tcontext: FieldItemContextValue | null;\n\t/**\n\t * Explicit validation override supplied to `Field.Control`.\n\t */\n\tvalidation?: ValidationProp;\n};\n\n/**\n * Context shared by the parts of a single `Field.Item`.\n */\nconst FieldItemContext = createContext<FieldItemContextValue | null>(null);\n\n/**\n * Resolves the ARIA and validation props that `Field.Control` applies to its\n * focusable child. Field owns the `aria-describedby` / `aria-errormessage`\n * contract — the resolver emits the surrounding `Field.Item`'s description and\n * error slot IDs directly, without merging anything from the control element.\n */\nconst resolveFieldControlAriaProps = ({\n\t\"aria-invalid\": ariaInvalid,\n\tcontext,\n\tvalidation,\n}: ResolveFieldControlAriaPropsOptions) => {\n\tconst parsedValidation = parseValidation({\n\t\t\"aria-invalid\": ariaInvalid,\n\t\tdefaultAriaInvalid: false,\n\t\tvalidation: validation ?? context?.validation,\n\t});\n\t// Always emit both slot IDs in aria-describedby when inside a Field.Item.\n\t// Per WAI-ARIA, unresolved IDREFs are ignored by assistive tech, so the\n\t// dangling ID is harmless when the corresponding slot isn't rendered and\n\t// lets us skip mount-time bookkeeping. aria-errormessage is additionally\n\t// spec-gated on aria-invalid=\"true\", so it stays inert until the field is\n\t// actually invalid.\n\tconst ariaDescribedBy = context ? `${context.descriptionId} ${context.errorId}` : undefined;\n\tconst ariaErrorMessage = parsedValidation.isInvalid && context ? context.errorId : undefined;\n\n\treturn {\n\t\tariaProps: {\n\t\t\t\"aria-describedby\": ariaDescribedBy,\n\t\t\t\"aria-errormessage\": ariaErrorMessage,\n\t\t\t\"aria-invalid\": parsedValidation.ariaInvalid,\n\t\t} satisfies FieldControlAriaProps,\n\t\tvalidation: parsedValidation.validation,\n\t};\n};\n\nexport {\n\t//,\n\tFieldItemContext,\n\tresolveFieldControlAriaProps,\n};\nexport type {\n\t//,\n\tFieldControlAriaProps,\n\tFieldItemContextValue,\n};\n","import { Children, Fragment, isValidElement, type ReactNode } from \"react\";\n\n/**\n * A validation message accepted by `Field.Errors`. Non-string absence values\n * are allowed so consumers can pass mapped validator output directly while\n * still rendering only real strings.\n */\ntype FieldErrorMessage = string | null | undefined | false;\n\ntype RenderableContentProps = { children?: ReactNode };\n\n/**\n * Options for checking a manual `Field.ErrorList` subtree.\n */\ntype HasRenderableErrorListChildrenOptions = {\n\t/**\n\t * The list children to inspect before rendering or wiring ARIA IDs.\n\t */\n\tchildren: ReactNode;\n\t/**\n\t * The local `Field.ErrorItem` component type from `field.tsx`. Passed in\n\t * (rather than imported) to avoid a circular dependency between\n\t * `field.tsx` and this helpers module.\n\t */\n\terrorItemType: unknown;\n};\n\n/**\n * Normalizes validator output into display-ready message strings without\n * coupling `Field.Errors` to a specific form library's error object shape.\n */\nconst normalizeErrorMessages = (messages: readonly FieldErrorMessage[] | undefined) =>\n\tmessages\n\t\t?.map((message) => (typeof message === \"string\" ? message.trim() : \"\"))\n\t\t.filter((message) => message.length > 0) ?? [];\n\n/**\n * Returns `true` when the supplied children would produce visible content in\n * a `Field.ErrorItem` — i.e. they are not `null`, `undefined`, `false`, or a\n * whitespace-only string. Used by both `Field.ErrorItem`'s render guard and\n * the `Field.ErrorList` walker so an empty item is identified consistently.\n */\nconst isErrorItemRenderable = (children: ReactNode): boolean => {\n\t// Booleans (including `true`) render nothing in React, so a `cond && expr`\n\t// pattern that resolves to `true` would otherwise count as renderable here.\n\tif (children == null || typeof children === \"boolean\") {\n\t\treturn false;\n\t}\n\tif (typeof children === \"string\" && children.trim().length === 0) {\n\t\treturn false;\n\t}\n\treturn true;\n};\n\n/**\n * Empty-detection walker for `Field.ErrorList`. Recurses through Fragments so\n * error items wrapped in conditional `<>…</>` still register, applies\n * `Field.ErrorItem`'s render guard so empty items do not count as content,\n * and treats any other child (custom component, host element, etc.) as\n * opaque-and-therefore-renderable.\n */\nconst hasRenderableErrorListChildren = ({\n\tchildren,\n\terrorItemType,\n}: HasRenderableErrorListChildrenOptions): boolean => {\n\tlet found = false;\n\n\tChildren.forEach(children, (child) => {\n\t\tif (found || child == null || typeof child === \"boolean\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof child === \"string\") {\n\t\t\tif (child.trim().length > 0) {\n\t\t\t\tfound = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!isValidElement<RenderableContentProps>(child)) {\n\t\t\tfound = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (child.type === errorItemType) {\n\t\t\tfound = isErrorItemRenderable(child.props.children);\n\t\t\treturn;\n\t\t}\n\n\t\tif (child.type === Fragment) {\n\t\t\tfound = hasRenderableErrorListChildren({\n\t\t\t\tchildren: child.props.children,\n\t\t\t\terrorItemType,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tfound = true;\n\t});\n\n\treturn found;\n};\n\nexport {\n\t//,\n\thasRenderableErrorListChildren,\n\tisErrorItemRenderable,\n\tnormalizeErrorMessages,\n};\nexport type {\n\t//,\n\tFieldErrorMessage,\n};\n","import { QuestionIcon } from \"@phosphor-icons/react/Question\";\nimport {\n\tcloneElement,\n\ttype ComponentRef,\n\ttype ComponentProps,\n\tforwardRef,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n\tuseCallback,\n\tuseContext,\n\tuseId,\n\tuseMemo,\n\tuseState,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { useIsomorphicLayoutEffect } from \"../../hooks/use-isomorphic-layout-effect.js\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { IconButton, type IconButtonProps } from \"../button/icon-button.js\";\nimport { Label } from \"../label/label.js\";\nimport { Popover } from \"../popover/index.js\";\nimport { Slot } from \"../slot/index.js\";\nimport {\n\tFieldItemContext,\n\tresolveFieldControlAriaProps,\n\ttype FieldControlAriaProps,\n} from \"./field-context.js\";\nimport {\n\thasRenderableErrorListChildren,\n\tisErrorItemRenderable,\n\tnormalizeErrorMessages,\n\ttype FieldErrorMessage,\n} from \"./error-helpers.js\";\nimport { FieldValidationProvider, resolveValidation, type WithValidation } from \"./validation.js\";\n\n/**\n * Props for the `Field.Errors` convenience renderer. It owns its generated\n * children, so use `Field.ErrorList` / `Field.ErrorItem` directly when custom\n * list contents or polymorphic list markup are needed.\n */\ntype FieldErrorsProps = Omit<ComponentProps<\"ul\">, \"children\" | \"id\"> & {\n\t/**\n\t * Validation messages to render. Strings are trimmed, and empty, nullish,\n\t * or false values are ignored before rendering the list.\n\t */\n\tmessages?: readonly FieldErrorMessage[];\n};\n\n/**\n * Renders a semantic `<fieldset>` for grouping related controls under a\n * single accessible name. Resets the default browser fieldset chrome\n * (border, padding, `min-width` quirk) so it composes cleanly with\n * `Field.Legend` and `Field.Group`. Always renders a real `<fieldset>` so\n * the grouping semantics cannot be accidentally removed.\n *\n * Reach for `Field.Set` when the grouping carries semantic weight — most\n * commonly a `RadioGroup` (where the legend names the question the radios\n * answer) or a set of related checkboxes. For laying out unrelated fields\n * with consistent spacing, prefer `Field.Group` on its own.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Set>\n * <Field.Legend>Notification frequency</Field.Legend>\n * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n * </RadioGroup.Root>\n * </Field.Set>\n * ```\n */\nconst FieldSet = forwardRef<ComponentRef<\"fieldset\">, ComponentProps<\"fieldset\">>(\n\t({ className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<fieldset\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-set\"\n\t\t\t\tclassName={cx(\"flex w-full min-w-0 flex-col gap-4 border-0 p-0\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nFieldSet.displayName = \"FieldSet\";\n\n/**\n * The caption for a `Field.Set`. Always renders a semantic `<legend>` styled\n * to match the `Label` component so a fieldset reads like a section header,\n * and gives screen readers an accessible name for the surrounding group\n * (e.g. \"Notification frequency, group, Daily\").\n *\n * **Spacing.** Has a default `mb-1.5` so the legend sits 6px above the next\n * sibling — matching the figma. We use a margin (not the parent `Field.Set`'s\n * flex `gap`) because `<legend>` has special browser rendering inside a\n * `<fieldset>` that ignores the parent's flex `gap`. Override the default\n * with any `mb-*` utility on `Field.Legend`.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Set>\n * <Field.Legend>Notification frequency</Field.Legend>\n * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n * </RadioGroup.Root>\n * </Field.Set>\n * ```\n */\nconst Legend = forwardRef<ComponentRef<\"legend\">, ComponentProps<\"legend\">>(\n\t({ className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<legend\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-legend\"\n\t\t\t\t// `mb-1.5` (not the parent's `gap-*`) drives the Legend ↔ next-sibling\n\t\t\t\t// spacing because `<legend>` has special browser rendering inside a\n\t\t\t\t// `<fieldset>` that ignores the parent's flex `gap`. Pairs with\n\t\t\t\t// RadioGroup.Item's own `py-1` for a 10px text-bottom-to-radio rhythm\n\t\t\t\t// matching the figma. Override with any `mb-*` utility on Field.Legend.\n\t\t\t\tclassName={cx(\"text-strong mb-1.5 text-sm font-medium font-sans\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nLegend.displayName = \"FieldLegend\";\n\n/**\n * Horizontal layout container for the label area of a field. Aligns a\n * `<Field.Label>` (which may contain `Field.Optional`) with adjacent affordances\n * like a help-icon `Popover.Trigger` on a shared center line with a tight\n * `gap-1`. Center-alignment is used (not baseline) so SVG icon buttons —\n * which have no text baseline — sit visually centered next to the label\n * text rather than dropping to the box bottom.\n *\n * Use this when the label needs sibling decorations that can't live inside\n * the `<Field.Label>` itself (e.g. an interactive help button — clicking inside a\n * `<label>` would forward focus to the associated control). For a label\n * with only an `(Optional)` suffix, place `Field.Optional` directly inside\n * the `<Field.Label>` instead — no `LabelRow` needed.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst LabelRow = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\"> & WithAsChild>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"div\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-label-row\"\n\t\t\t\tclassName={cx(\"flex items-center gap-1\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nLabelRow.displayName = \"FieldLabelRow\";\n\n/**\n * `Popover.Root` re-export for the help-affordance pattern. Pair with\n * `Field.HelpTrigger` (renders a default question-mark `IconButton`) and\n * `Field.HelpContent` (the popover body) to drop a help button into a\n * `Field.LabelRow` without manually wiring `Popover` + `IconButton` +\n * `QuestionIcon`. All `Popover.Root` props are forwarded — pass `modal`,\n * `defaultOpen`, etc. as needed.\n *\n * Popover (not Tooltip) so the affordance is reachable on touch devices.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Help = Popover.Root;\n\n/**\n * Props for the default help popover trigger. A contextual label is required\n * so repeated help affordances do not all share the same accessible name.\n */\ntype FieldHelpTriggerProps = Partial<Omit<IconButtonProps, \"icon\" | \"label\">> &\n\tPick<IconButtonProps, \"label\"> & {\n\t\t/**\n\t\t * The icon to render inside the trigger button. Defaults to a Phosphor\n\t\t * `QuestionIcon` so the most common case only needs a contextual label.\n\t\t */\n\t\ticon?: ReactNode;\n\t};\n\n/**\n * The trigger for a `Field.Help` popover — a `Popover.Trigger` wired to a\n * ghost-appearance `IconButton` with a default Phosphor `QuestionIcon`.\n * Requires a contextual screen-reader label, and accepts `icon` or other\n * `IconButton` props for visual customization.\n *\n * Pre-styled with `text-body` (matching the figma) so the icon reads as\n * subtle metadata at rest; `IconButton`'s ghost `hover:text-strong` still\n * brightens it on interaction. Carries a default `-my-0.5` so the 24px\n * `xs` button keeps a full click target while contributing only 20px to\n * the `Field.LabelRow` flex line — matching the label's text line-height\n * so the label text is not pushed off-center.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst HelpTrigger = forwardRef<ComponentRef<\"button\">, FieldHelpTriggerProps>(\n\t(\n\t\t{\n\t\t\tappearance = \"ghost\",\n\t\t\tclassName,\n\t\t\ticon = <QuestionIcon />,\n\t\t\tlabel,\n\t\t\tsize = \"xs\",\n\t\t\ttype = \"button\",\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => (\n\t\t<Popover.Trigger asChild>\n\t\t\t<IconButton\n\t\t\t\tref={ref}\n\t\t\t\tappearance={appearance}\n\t\t\t\t// `-my-0.5` keeps the 24px (`size-6`) `xs` IconButton click target while\n\t\t\t\t// trimming 4px (2px each side) off its flex-line contribution so the row\n\t\t\t\t// height matches the label's 20px line-height. Without this the trigger\n\t\t\t\t// drives the LabelRow to 24px and pushes the label text down 2px.\n\t\t\t\tclassName={cx(\"text-body -my-0.5\", className)}\n\t\t\t\ticon={icon}\n\t\t\t\tlabel={label}\n\t\t\t\tsize={size}\n\t\t\t\ttype={type}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</Popover.Trigger>\n\t),\n);\nHelpTrigger.displayName = \"FieldHelpTrigger\";\n\n/**\n * The popover body for a `Field.Help`. Wraps `Popover.Content` so all\n * positioning / sizing options (`side`, `align`, `preferredWidth`, etc.)\n * work as expected, and overrides the inherited `data-slot` to\n * `field-help-content` so consumers can target it as part of a `Field`\n * subtree without colliding with other popovers.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst HelpContent = forwardRef<ComponentRef<\"div\">, ComponentProps<typeof Popover.Content>>(\n\t(props, ref) => <Popover.Content ref={ref} data-slot=\"field-help-content\" {...props} />,\n);\nHelpContent.displayName = \"FieldHelpContent\";\n\n/**\n * Inline \"(Optional)\" suffix to mark a field as optional. Defaults to the\n * literal string `(Optional)` so the common case is `<Field.Optional />` with\n * no children — pass children to translate or replace the text. Renders a\n * `<span>` in `text-muted` at `text-sm` / `font-normal` so it reads as\n * secondary metadata next to the bolder Label text.\n *\n * Place inside the `<Field.Label>` so screen readers announce it as part of the\n * accessible name (e.g. \"Email, Optional, edit text\"). Pair with a small\n * `gap` on the label's flex layout, or rely on the natural inline spacing.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Optional = forwardRef<ComponentRef<\"span\">, ComponentProps<\"span\"> & WithAsChild>(\n\t({ asChild, children, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"span\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-optional\"\n\t\t\t\tclassName={cx(\"text-muted text-sm font-normal font-sans\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children ?? \"(Optional)\"}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nOptional.displayName = \"FieldOptional\";\n\n/**\n * Layout container that stacks multiple `Field.Item`s vertically with\n * `gap-4` between them. This is the default way to compose multiple fields\n * — most forms only need a `Field.Group` of `Field.Item`s. Reach for\n * `Field.Set` + `Field.Legend` only when the grouping carries semantic\n * weight (e.g. a `RadioGroup` or related checkboxes).\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Group = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\"> & WithAsChild>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"div\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-group\"\n\t\t\t\tclassName={cx(\"flex w-full flex-col gap-4\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nGroup.displayName = \"FieldGroup\";\n\n/**\n * A single form field — `Label`, a control (`Input`, `Select`, `Checkbox`,\n * etc.), and any `Field.Description`, `Field.Errors`, or `Field.ErrorList` siblings stacked\n * vertically with a consistent `gap-1.5` so help and error messaging sit\n * tightly under the input.\n *\n * Renders a plain `<div>` — the `<label htmlFor>` ↔ control association\n * already provides the right semantics for a single field, so no implicit\n * `role` is added. `Field.Item` owns the contextual description/error IDs\n * that `Field.Control` applies to the focusable control. Rendered errors\n * infer an `\"error\"` validation state unless `validation` is supplied as an\n * explicit override.\n *\n * **Single-slot constraint.** A `Field.Item` owns one description ID and one\n * errors ID, so render at most one `Field.Description` and one\n * `Field.Errors` *or* `Field.ErrorList` (not both) per item. A second instance\n * would duplicate the slot `id` in the DOM. Pass multiple messages to\n * `Field.Errors`, or multiple `Field.ErrorItem` children to `Field.ErrorList`,\n * instead.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Item = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\"> & WithAsChild & WithValidation>(\n\t({ asChild, children, className, validation: validationProp, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"div\";\n\t\tconst descriptionId = useId();\n\t\tconst errorId = useId();\n\t\tconst [hasErrors, setHasErrors] = useState(false);\n\t\tconst validation = resolveValidation(validationProp ?? (hasErrors ? \"error\" : undefined));\n\n\t\tconst registerError = useCallback(() => {\n\t\t\tsetHasErrors(true);\n\n\t\t\treturn () => {\n\t\t\t\tsetHasErrors(false);\n\t\t\t};\n\t\t}, []);\n\n\t\tconst context = useMemo(\n\t\t\t() => ({\n\t\t\t\tdescriptionId,\n\t\t\t\terrorId,\n\t\t\t\thasErrors,\n\t\t\t\tregisterError,\n\t\t\t\tvalidation,\n\t\t\t}),\n\t\t\t[descriptionId, errorId, hasErrors, registerError, validation],\n\t\t);\n\n\t\treturn (\n\t\t\t<FieldItemContext.Provider value={context}>\n\t\t\t\t<FieldValidationProvider validation={validation}>\n\t\t\t\t\t<Comp\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tdata-slot=\"field-item\"\n\t\t\t\t\t\tdata-validation={validation}\n\t\t\t\t\t\tclassName={cx(\"flex w-full flex-col gap-1.5\", className)}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</Comp>\n\t\t\t\t</FieldValidationProvider>\n\t\t\t</FieldItemContext.Provider>\n\t\t);\n\t},\n);\nItem.displayName = \"FieldItem\";\n\ntype FieldControlSlotProps = Omit<\n\tComponentProps<typeof Slot>,\n\t\"aria-describedby\" | \"aria-errormessage\" | \"aria-invalid\" | \"children\"\n>;\n\n/**\n * Element-child form of `Field.Control`. Renders via `Slot`, so it accepts\n * any HTML/Slot props and a forwarded ref — those land on the single child\n * element along with the generated ARIA props.\n */\ntype FieldControlElementProps = FieldControlSlotProps &\n\tWithValidation & {\n\t\t/**\n\t\t * A single control element to receive the field ARIA props.\n\t\t */\n\t\tchildren: ReactElement;\n\t};\n\n/**\n * Render-prop form of `Field.Control`. The caller owns the rendered element,\n * so `Field.Control` itself renders nothing — extra DOM props and `ref` have\n * no element to attach to and are intentionally not part of this variant.\n * Slot props are marked `never` so passing e.g. `className` alongside a\n * render-prop child is a type error rather than a silently ignored prop.\n */\ntype FieldControlRenderProps = WithValidation & {\n\t/**\n\t * A render function that places the field ARIA props onto a control of\n\t * the caller's choosing. Used for compound controls or wrappers where\n\t * `Slot` cannot reach the focusable element.\n\t */\n\tchildren: (props: FieldControlAriaProps) => ReactNode;\n} & { [K in keyof FieldControlSlotProps]?: never };\n\n/**\n * Props for `Field.Control`. A discriminated union over how the caller\n * supplies the focusable element:\n *\n * - `FieldControlElementProps` — pass a single React element child and\n * `Field.Control` clones the generated ARIA props onto it via `Slot`.\n * Accepts the full Slot prop surface plus a forwarded ref.\n * - `FieldControlRenderProps` — pass a render function that receives the\n * ARIA props and places them on a control of the caller's choosing. The\n * caller owns the rendered element, so DOM/Slot props and `ref` are\n * excluded from this variant at the type level.\n *\n * @example\n * ```tsx\n * // Element form — Slot clones ARIA props onto <Input/>\n * <Field.Control>\n * <Input id=\"email\" name=\"email\" />\n * </Field.Control>\n *\n * // Render-prop form — caller spreads ARIA props onto its own element\n * <Field.Control>\n * {(ariaProps) => (\n * <label>\n * Accept terms\n * <input type=\"checkbox\" {...ariaProps} />\n * </label>\n * )}\n * </Field.Control>\n * ```\n */\ntype FieldControlProps = FieldControlElementProps | FieldControlRenderProps;\n\n/**\n * Applies `Field.Item` description, error, and validation state to a single\n * focusable control. It always behaves like an `asChild` slot: pass one child\n * element to receive the generated ARIA props, or use a function child to\n * place those props manually. For compound controls, wrap the focusable part\n * that receives ARIA props (for example `Select.Trigger`, not `Select.Root`).\n * Pass `validation` here only when the control needs to override the\n * surrounding `Field.Item` state.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Control = forwardRef<HTMLElement, FieldControlProps>(\n\t({ children, validation, ...props }, ref) => {\n\t\tconst context = useContext(FieldItemContext);\n\n\t\tif (typeof children === \"function\") {\n\t\t\tconst baseControlState = resolveFieldControlAriaProps({ context, validation });\n\t\t\treturn (\n\t\t\t\t<FieldValidationProvider validation={baseControlState.validation}>\n\t\t\t\t\t{children(baseControlState.ariaProps)}\n\t\t\t\t</FieldValidationProvider>\n\t\t\t);\n\t\t}\n\n\t\tinvariant(\n\t\t\tisValidElement<FieldControlAriaProps>(children),\n\t\t\t\"Field.Control expects a single React element child (or a render-prop function). Got a non-element value (string, array, fragment, null, or undefined). Wrap the control in a single element, or use the function child form: <Field.Control>{(props) => <YourControl {...props} />}</Field.Control>.\",\n\t\t);\n\n\t\t// `aria-describedby` and `aria-errormessage` are owned by Field; values\n\t\t// supplied on the child element are overwritten by `cloneElement`\n\t\t// below. `aria-invalid` is the one ARIA prop a child may meaningfully\n\t\t// override (e.g., explicit `aria-invalid=\"false\"` to suppress an\n\t\t// inferred error).\n\t\tconst childControlState = resolveFieldControlAriaProps({\n\t\t\t\"aria-invalid\": children.props[\"aria-invalid\"],\n\t\t\tcontext,\n\t\t\tvalidation,\n\t\t});\n\n\t\treturn (\n\t\t\t<FieldValidationProvider validation={childControlState.validation}>\n\t\t\t\t<Slot ref={ref} {...props}>\n\t\t\t\t\t{cloneElement(children, childControlState.ariaProps)}\n\t\t\t\t</Slot>\n\t\t\t</FieldValidationProvider>\n\t\t);\n\t},\n);\nControl.displayName = \"FieldControl\";\n\n/**\n * Helper / hint text. Renders a `<p>` in the muted body color so it reads\n * as secondary to the bolder content above it. Use inside `Field.Item`, below\n * the control, to clarify expected format or constraints for that single field.\n *\n * **At most one per `Field.Item`.** `Field.Item` owns a single description\n * slot ID and applies it via context, so a second `Field.Description` would\n * duplicate that `id` in the DOM.\n *\n * **Auto-tighten.** When this description sits directly after rendered\n * `Field.Errors` or `Field.ErrorList` output, the parent's `gap-1.5`\n * collapses via a matching negative top margin so error list + helper read as\n * one tight block. Pass any margin utility (`mt-1`, `mt-0`, etc.) to override\n * — the rule's specificity is flattened to `(0,1,0)` so a single user class wins.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Description = forwardRef<ComponentRef<\"p\">, Omit<ComponentProps<\"p\">, \"id\"> & WithAsChild>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"p\";\n\t\tconst context = useContext(FieldItemContext);\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-description\"\n\t\t\t\tid={context?.descriptionId}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"text-body text-sm leading-4\",\n\t\t\t\t\t// When this description sits directly after a Field.ErrorList\n\t\t\t\t\t// sibling, collapse the parent's gap-1.5 with a matching negative\n\t\t\t\t\t// top margin so the list + helper read as one tight block.\n\t\t\t\t\t// Wrapping the matched selector in :where() flattens its specificity\n\t\t\t\t\t// to (0,1,0) so a user-supplied margin utility (mt-2, mt-0, etc.)\n\t\t\t\t\t// passed on Field.Description still overrides cleanly.\n\t\t\t\t\t\"[:where([data-slot=field-error-list]+&)]:-mt-1.5\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nDescription.displayName = \"FieldDescription\";\n\n/**\n * A single error message list item for a field. Renders an `<li>` in\n * `text-danger-600` so it stands out from a sibling `Field.Description`.\n * Must be rendered inside a `Field.ErrorList`. Empty or blank children render\n * nothing so message-less validator results do not produce empty list items.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.Label htmlFor=\"username\">Username</Field.Label>\n * <Field.Control>\n * <Input id=\"username\" name=\"username\" />\n * </Field.Control>\n * <Field.ErrorList>\n * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n * </Field.ErrorList>\n * <Field.Description>Pick something memorable.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst FieldErrorItem = forwardRef<ComponentRef<\"li\">, ComponentProps<\"li\">>(\n\t({ children, className, ...props }, ref) => {\n\t\tif (!isErrorItemRenderable(children)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<li\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-error\"\n\t\t\t\tclassName={cx(\"text-danger-600 text-sm leading-4\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</li>\n\t\t);\n\t},\n);\nFieldErrorItem.displayName = \"FieldErrorItem\";\n\n/**\n * Convenience renderer for string validation messages. Trims each message,\n * filters empty values, and renders a semantic `Field.ErrorList` containing\n * one `Field.ErrorItem` per remaining message.\n *\n * Accepts strings directly so product code can map any validation library's\n * error shape into messages without coupling Mantle to that library.\n * Deliberately does not support `asChild` because it owns the generated list\n * items; use `Field.ErrorList` with `asChild` for custom list markup.\n *\n * **At most one per `Field.Item`.** `Field.Errors` renders a `Field.ErrorList`\n * under the hood, and `Field.Item` owns a single errors slot ID. Use either\n * `Field.Errors` *or* `Field.ErrorList` per item, not both, and pass multiple\n * messages to one `Field.Errors` instead of rendering it twice.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst FieldErrors = forwardRef<ComponentRef<\"ul\">, FieldErrorsProps>(\n\t({ messages, ...props }, ref) => (\n\t\t<FieldErrorList ref={ref} {...props}>\n\t\t\t{normalizeErrorMessages(messages).map((message, index) => (\n\t\t\t\t<FieldErrorItem key={index}>{message}</FieldErrorItem>\n\t\t\t))}\n\t\t</FieldErrorList>\n\t),\n);\nFieldErrors.displayName = \"FieldErrors\";\n\n/**\n * Wraps one or more `Field.ErrorItem` children in a semantic `<ul>` with\n * `role=\"list\"` so a list of validation errors is announced as a list by\n * screen readers, including Safari/VoiceOver combinations that drop list\n * semantics when list styling is removed. Renders nothing when no children are\n * passed, or when all `Field.ErrorItem` children are empty.\n *\n * The list strips its default browser styling (`list-none`, `p-0`, `m-0`) and\n * stacks items as a flex column with no gap so consecutive errors read as a\n * single tight block.\n *\n * **At most one per `Field.Item`.** `Field.Item` owns a single errors slot ID\n * and applies it via context. Use either `Field.ErrorList` *or* `Field.Errors`\n * per item, not both, and put multiple `Field.ErrorItem` children inside the\n * single list instead of rendering two `Field.ErrorList`s.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.Label htmlFor=\"username\">Username</Field.Label>\n * <Field.Control>\n * <Input id=\"username\" name=\"username\" />\n * </Field.Control>\n * <Field.ErrorList>\n * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n * </Field.ErrorList>\n * <Field.Description>Pick something memorable.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst FieldErrorList = forwardRef<\n\tComponentRef<\"ul\">,\n\tOmit<ComponentProps<\"ul\">, \"id\"> & WithAsChild\n>(({ asChild, children, className, ...props }, ref) => {\n\tconst hasRenderableChildren = hasRenderableErrorListChildren({\n\t\tchildren,\n\t\terrorItemType: FieldErrorItem,\n\t});\n\tconst context = useContext(FieldItemContext);\n\tconst registerError = context?.registerError;\n\n\tuseIsomorphicLayoutEffect(() => {\n\t\tif (!hasRenderableChildren || registerError == null) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn registerError();\n\t}, [hasRenderableChildren, registerError]);\n\n\tif (!hasRenderableChildren) {\n\t\treturn null;\n\t}\n\n\tconst Comp = asChild ? Slot : \"ul\";\n\n\treturn (\n\t\t<Comp\n\t\t\tref={ref}\n\t\t\tdata-slot=\"field-error-list\"\n\t\t\tid={context?.errorId}\n\t\t\trole=\"list\"\n\t\t\tclassName={cx(\"m-0 flex w-full flex-col list-none p-0\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n});\nFieldErrorList.displayName = \"FieldErrorList\";\n\n/**\n * Compound component for semantic, accessible form fields. Composes a\n * `Field.Label`, control (`Input`, `Select`, etc.), `Field.Description`, and\n * validation errors (`Field.Errors` / `Field.ErrorList` + `Field.ErrorItem`)\n * with consistent spacing and ARIA wiring. Stack multiple fields with\n * `Field.Group`; use `Field.Set` + `Field.Legend` for radios / related\n * checkboxes that share one accessible name.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * Composition:\n * ```\n * Field.Group\n * └── Field.Item\n * ├── Field.LabelRow\n * │ ├── Field.Label\n * │ │ └── Field.Optional\n * │ └── Field.Help\n * │ ├── Field.HelpTrigger\n * │ └── Field.HelpContent\n * ├── Field.Control\n * │ └── (control)\n * ├── Field.Errors (or)\n * ├── Field.ErrorList\n * │ └── Field.ErrorItem\n * └── Field.Description\n * ```\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item>\n * <Field.LabelRow>\n * <Field.Label htmlFor=\"api-key\">\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input id=\"api-key\" name=\"apiKey\" />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Field = {\n\t/**\n\t * A single form field. Provides message IDs and validation state to\n\t * `Field.Control`; rendered errors infer `\"error\"` validation.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tItem,\n\t/**\n\t * Applies generated field ARIA props and validation state to a single\n\t * focusable control. Accepts either a single React element child (cloned\n\t * via `Slot`) or a render-prop child that receives the ARIA props for\n\t * cases where `Slot` cannot reach the focusable element — for example a\n\t * `<label>`-wrapped native checkbox, or a third-party component that\n\t * needs the props placed manually on an inner input.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * // Element child — Slot clones the generated ARIA props onto <Input/>.\n\t * <Field.Item>\n\t * <Field.Label htmlFor=\"api-key\">API key</Field.Label>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * </Field.Item>\n\t * ```\n\t *\n\t * @example\n\t * ```tsx\n\t * // Render-prop child — caller spreads the ARIA props onto an inner\n\t * // element when the focusable target is nested (e.g. inside a <label>).\n\t * <Field.Item>\n\t * <Field.Control>\n\t * {(ariaProps) => (\n\t * <label>\n\t * Accept terms\n\t * <input type=\"checkbox\" {...ariaProps} />\n\t * </label>\n\t * )}\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"You must accept the terms.\"]} />\n\t * </Field.Item>\n\t * ```\n\t */\n\tControl,\n\t/**\n\t * Layout container that stacks multiple `Field.Item`s vertically.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * Semantic `<fieldset>` for related controls that share one accessible\n\t * name from `Field.Legend`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Set>\n\t * <Field.Legend>Notification frequency</Field.Legend>\n\t * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n\t * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n\t * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n\t * </RadioGroup.Root>\n\t * </Field.Set>\n\t * ```\n\t */\n\tSet: FieldSet,\n\t/**\n\t * Caption for `Field.Set`. Renders a semantic `<legend>`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Set>\n\t * <Field.Legend>Notification frequency</Field.Legend>\n\t * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n\t * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n\t * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n\t * </RadioGroup.Root>\n\t * </Field.Set>\n\t * ```\n\t */\n\tLegend,\n\t/**\n\t * The Mantle `Label`, exposed on `Field` for field composition.\n\t *\n\t * @see https://mantle.ngrok.com/components/label\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tLabel,\n\t/**\n\t * Horizontal layout container for the label area of a field. Aligns a\n\t * `<Field.Label>` (which may contain `Field.Optional`) with adjacent affordances\n\t * like a help-icon `Popover.Trigger` on a shared center line with `gap-1`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tLabelRow,\n\t/**\n\t * `Popover.Root` re-export for the help-affordance pattern. Pair with\n\t * `Field.HelpTrigger` and `Field.HelpContent` to drop a `?` button next to\n\t * a label without manually composing Popover + IconButton + QuestionIcon.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tHelp,\n\t/**\n\t * Trigger for a `Field.Help` popover — a ghost `IconButton` with a default\n\t * `QuestionIcon`. Requires a contextual `label`; pass `icon` to swap the\n\t * glyph, or other `IconButton` props (`size`, `appearance`, etc.) to customize.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tHelpTrigger,\n\t/**\n\t * Body of a `Field.Help` popover. Re-exports `Popover.Content` so all\n\t * positioning / sizing options (`side`, `align`, `preferredWidth`, etc.)\n\t * work as expected.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tHelpContent,\n\t/**\n\t * Inline \"(Optional)\" suffix to mark a field as optional. Default content\n\t * is `(Optional)`; pass children to translate or replace it. Place inside\n\t * the `<Field.Label>` so screen readers announce it as part of the accessible\n\t * name.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tOptional,\n\t/**\n\t * Helper / hint text rendered below the control in the muted body color.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tDescription,\n\t/**\n\t * Convenience renderer for validation messages. Trims string messages,\n\t * filters empty values, and renders a `Field.ErrorList` with one\n\t * `Field.ErrorItem` for each remaining message.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.LabelRow>\n\t * <Field.Label htmlFor=\"api-key\">\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input id=\"api-key\" name=\"apiKey\" />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tErrors: FieldErrors,\n\t/**\n\t * Wraps one or more `Field.ErrorItem` children in a semantic `<ul>`.\n\t * Renders nothing when given no renderable children.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.Label htmlFor=\"username\">Username</Field.Label>\n\t * <Field.Control>\n\t * <Input id=\"username\" name=\"username\" />\n\t * </Field.Control>\n\t * <Field.ErrorList>\n\t * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n\t * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n\t * </Field.ErrorList>\n\t * <Field.Description>Pick something memorable.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tErrorList: FieldErrorList,\n\t/**\n\t * A single error message list item for a field. Renders an `<li>` in\n\t * `text-danger-600` and must be nested inside a `Field.ErrorList`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item>\n\t * <Field.Label htmlFor=\"username\">Username</Field.Label>\n\t * <Field.Control>\n\t * <Input id=\"username\" name=\"username\" />\n\t * </Field.Control>\n\t * <Field.ErrorList>\n\t * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n\t * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n\t * </Field.ErrorList>\n\t * <Field.Description>Pick something memorable.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tErrorItem: FieldErrorItem,\n} as const;\n\nexport {\n\t//,\n\tField,\n};\n","import { normalizeErrorMessages } from \"./error-helpers.js\";\n\n/**\n * Shapes commonly found in `field.state.meta.errors` from TanStack React Form\n * across its built-in validators (Standard Schema / Zod issues, raw strings,\n * thrown `Error` instances) plus the falsy slots Standard Schema can produce.\n */\ntype FieldError = { readonly message?: string | undefined } | string | null | undefined | false;\n\n/**\n * Reduce a TanStack React Form field's `meta.errors` array (or any array of\n * mixed string / `{ message }` / nullish error entries) to a clean `string[]`\n * for passing directly to `Field.Errors`' `messages` prop.\n *\n * Handles the shapes TanStack form yields for Zod, Standard Schema, and\n * thrown `Error` validators: items may be strings, objects with `.message`,\n * `undefined`, `null`, or `false`. Empty / whitespace-only messages are\n * dropped so callers don't have to filter again.\n *\n * @example\n * ```tsx\n * <Field.Item>\n * <Field.Label htmlFor={field.name}>Email</Field.Label>\n * <Field.Control>\n * <Input id={field.name} value={field.state.value} />\n * </Field.Control>\n * <Field.Errors messages={toErrorMessages(field.state.meta.errors)} />\n * </Field.Item>\n * ```\n */\nconst toErrorMessages = (errors: readonly FieldError[] | null | undefined): string[] =>\n\tnormalizeErrorMessages(\n\t\terrors?.map((error) => (typeof error === \"string\" || !error ? error : error.message)),\n\t);\n\nexport {\n\t//,\n\ttoErrorMessages,\n};\n\nexport type {\n\t//,\n\tFieldError,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"field.js","names":[],"sources":["../src/components/field/error-helpers.ts","../src/components/field/field.tsx","../src/components/field/field-error-messages.ts"],"sourcesContent":["import { Children, Fragment, isValidElement, type ReactNode } from \"react\";\n\n/**\n * A validation message accepted by `Field.Errors`. Non-string absence values\n * are allowed so consumers can pass mapped validator output directly while\n * still rendering only real strings.\n */\ntype FieldErrorMessage = string | null | undefined | false;\n\ntype RenderableContentProps = { children?: ReactNode };\n\n/**\n * Options for checking a manual `Field.ErrorList` subtree.\n */\ntype HasRenderableErrorListChildrenOptions = {\n\t/**\n\t * The list children to inspect before rendering or wiring ARIA IDs.\n\t */\n\tchildren: ReactNode;\n\t/**\n\t * The local `Field.ErrorItem` component type from `field.tsx`. Passed in\n\t * (rather than imported) to avoid a circular dependency between\n\t * `field.tsx` and this helpers module.\n\t */\n\terrorItemType: unknown;\n};\n\n/**\n * Normalizes validator output into display-ready message strings without\n * coupling `Field.Errors` to a specific form library's error object shape.\n */\nconst normalizeErrorMessages = (messages: readonly FieldErrorMessage[] | undefined) => {\n\tconst normalizedMessages: string[] = [];\n\tconst seenMessages = new Set<string>();\n\n\tfor (const message of messages ?? []) {\n\t\tif (typeof message !== \"string\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst normalizedMessage = message.trim();\n\t\tif (normalizedMessage.length === 0 || seenMessages.has(normalizedMessage)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tseenMessages.add(normalizedMessage);\n\t\tnormalizedMessages.push(normalizedMessage);\n\t}\n\n\treturn normalizedMessages;\n};\n\n/**\n * Returns `true` when the supplied children would produce visible content in\n * a `Field.ErrorItem` — i.e. they are not `null`, `undefined`, `false`, or a\n * whitespace-only string. Used by both `Field.ErrorItem`'s render guard and\n * the `Field.ErrorList` walker so an empty item is identified consistently.\n */\nconst isErrorItemRenderable = (children: ReactNode): boolean => {\n\t// Booleans (including `true`) render nothing in React, so a `cond && expr`\n\t// pattern that resolves to `true` would otherwise count as renderable here.\n\tif (children == null || typeof children === \"boolean\") {\n\t\treturn false;\n\t}\n\tif (typeof children === \"string\" && children.trim().length === 0) {\n\t\treturn false;\n\t}\n\treturn true;\n};\n\n/**\n * Empty-detection walker for `Field.ErrorList`. Recurses through Fragments so\n * error items wrapped in conditional `<>…</>` still register, applies\n * `Field.ErrorItem`'s render guard so empty items do not count as content,\n * and treats any other child (custom component, host element, etc.) as\n * opaque-and-therefore-renderable.\n */\nconst hasRenderableErrorListChildren = ({\n\tchildren,\n\terrorItemType,\n}: HasRenderableErrorListChildrenOptions): boolean => {\n\tlet found = false;\n\n\tChildren.forEach(children, (child) => {\n\t\tif (found || child == null || typeof child === \"boolean\") {\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof child === \"string\") {\n\t\t\tif (child.trim().length > 0) {\n\t\t\t\tfound = true;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!isValidElement<RenderableContentProps>(child)) {\n\t\t\tfound = true;\n\t\t\treturn;\n\t\t}\n\n\t\tif (child.type === errorItemType) {\n\t\t\tfound = isErrorItemRenderable(child.props.children);\n\t\t\treturn;\n\t\t}\n\n\t\tif (child.type === Fragment) {\n\t\t\tfound = hasRenderableErrorListChildren({\n\t\t\t\tchildren: child.props.children,\n\t\t\t\terrorItemType,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tfound = true;\n\t});\n\n\treturn found;\n};\n\nexport {\n\t//,\n\thasRenderableErrorListChildren,\n\tisErrorItemRenderable,\n\tnormalizeErrorMessages,\n};\nexport type {\n\t//,\n\tFieldErrorMessage,\n};\n","import { QuestionIcon } from \"@phosphor-icons/react/Question\";\nimport {\n\tcloneElement,\n\ttype ComponentRef,\n\ttype ComponentProps,\n\tforwardRef,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n\tuseCallback,\n\tuseContext,\n\tuseId,\n\tuseMemo,\n\tuseState,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport { useIsomorphicLayoutEffect } from \"../../hooks/use-isomorphic-layout-effect.js\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { IconButton, type IconButtonProps } from \"../button/icon-button.js\";\nimport { Label } from \"../label/label.js\";\nimport { Popover } from \"../popover/index.js\";\nimport { Slot } from \"../slot/index.js\";\nimport {\n\tFieldControlContext,\n\tFieldItemContext,\n\tresolveFieldControlAriaProps,\n\ttype FieldControlAriaProps,\n} from \"./field-context.js\";\nimport {\n\thasRenderableErrorListChildren,\n\tisErrorItemRenderable,\n\tnormalizeErrorMessages,\n\ttype FieldErrorMessage,\n} from \"./error-helpers.js\";\nimport { FieldValidationProvider, resolveValidation, type WithValidation } from \"./validation.js\";\n\n/**\n * Renders a semantic `<fieldset>` for grouping related controls under a\n * single accessible name. Resets the default browser fieldset chrome\n * (border, padding, `min-width` quirk) so it composes cleanly with\n * `Field.Legend` and `Field.Group`. Always renders a real `<fieldset>` so\n * the grouping semantics cannot be accidentally removed.\n *\n * Reach for `Field.Set` when the grouping carries semantic weight — most\n * commonly a `RadioGroup` (where the legend names the question the radios\n * answer) or a set of related checkboxes. For laying out unrelated fields\n * with consistent spacing, prefer `Field.Group` on its own.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Set>\n * <Field.Legend>Notification frequency</Field.Legend>\n * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n * </RadioGroup.Root>\n * </Field.Set>\n * ```\n */\nconst FieldSet = forwardRef<ComponentRef<\"fieldset\">, ComponentProps<\"fieldset\">>(\n\t({ className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<fieldset\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-set\"\n\t\t\t\tclassName={cx(\"flex w-full min-w-0 flex-col gap-4 border-0 p-0\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nFieldSet.displayName = \"FieldSet\";\n\n/**\n * The caption for a `Field.Set`. Always renders a semantic `<legend>` styled\n * to match the `Label` component so a fieldset reads like a section header,\n * and gives screen readers an accessible name for the surrounding group\n * (e.g. \"Notification frequency, group, Daily\").\n *\n * **Spacing.** Has a default `mb-1.5` so the legend sits 6px above the next\n * sibling — matching the figma. We use a margin (not the parent `Field.Set`'s\n * flex `gap`) because `<legend>` has special browser rendering inside a\n * `<fieldset>` that ignores the parent's flex `gap`. Override the default\n * with any `mb-*` utility on `Field.Legend`.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Set>\n * <Field.Legend>Notification frequency</Field.Legend>\n * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n * </RadioGroup.Root>\n * </Field.Set>\n * ```\n */\nconst Legend = forwardRef<ComponentRef<\"legend\">, ComponentProps<\"legend\">>(\n\t({ className, ...props }, ref) => {\n\t\treturn (\n\t\t\t<legend\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-legend\"\n\t\t\t\t// `mb-1.5` (not the parent's `gap-*`) drives the Legend ↔ next-sibling\n\t\t\t\t// spacing because `<legend>` has special browser rendering inside a\n\t\t\t\t// `<fieldset>` that ignores the parent's flex `gap`. Pairs with\n\t\t\t\t// RadioGroup.Item's own `py-1` for a 10px text-bottom-to-radio rhythm\n\t\t\t\t// matching the figma. Override with any `mb-*` utility on Field.Legend.\n\t\t\t\tclassName={cx(\"text-strong mb-1.5 text-sm font-medium font-sans\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nLegend.displayName = \"FieldLegend\";\n\n/**\n * Caption for a `Field.Item`. Renders the Mantle `Label` with the same\n * `htmlFor`, click-to-focus, disabled, and typography behavior — but inside a\n * `Field.Item`, the label-to-control association is automatic: `Field.Item`\n * generates a stable control id, `Field.Control` splats that id onto its\n * focusable child, and `Field.Label` consumes the same id as the default\n * `htmlFor`. The required `name` on `Field.Item` is the single source of truth\n * for the control's form name — no matching `htmlFor` / `id` pair, no separate\n * `useId()` call.\n *\n * Pass an explicit `htmlFor` to opt out — for example when the focusable\n * element is rendered outside of `Field.Control` and the auto-generated id\n * never lands on it.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * // htmlFor is wired automatically from Field.Item's name.\n * <Field.Item name=\"apiKey\">\n * <Field.Label>API key</Field.Label>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * </Field.Item>\n *\n * // Opt out with an explicit htmlFor when needed.\n * <Field.Item name=\"legacy\">\n * <Field.Label htmlFor=\"legacy-control\">Legacy field</Field.Label>\n * <input id=\"legacy-control\" />\n * </Field.Item>\n * ```\n */\nconst FieldLabel = forwardRef<ComponentRef<\"label\">, ComponentProps<typeof Label>>(\n\t({ htmlFor, ...props }, ref) => {\n\t\tconst context = useContext(FieldItemContext);\n\n\t\treturn <Label ref={ref} htmlFor={htmlFor ?? context?.controlId} {...props} />;\n\t},\n);\nFieldLabel.displayName = \"FieldLabel\";\n\n/**\n * Horizontal layout container for the label area of a field. Aligns a\n * `<Field.Label>` (which may contain `Field.Optional`) with adjacent affordances\n * like a help-icon `Popover.Trigger` on a shared center line with a tight\n * `gap-1`. Center-alignment is used (not baseline) so SVG icon buttons —\n * which have no text baseline — sit visually centered next to the label\n * text rather than dropping to the box bottom.\n *\n * Use this when the label needs sibling decorations that can't live inside\n * the `<Field.Label>` itself (e.g. an interactive help button — clicking inside a\n * `<label>` would forward focus to the associated control). For a label\n * with only an `(Optional)` suffix, place `Field.Optional` directly inside\n * the `<Field.Label>` instead — no `LabelRow` needed.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst LabelRow = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\"> & WithAsChild>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"div\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-label-row\"\n\t\t\t\tclassName={cx(\"flex items-center gap-1\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nLabelRow.displayName = \"FieldLabelRow\";\n\n/**\n * `Popover.Root` re-export for the help-affordance pattern. Pair with\n * `Field.HelpTrigger` (renders a default question-mark `IconButton`) and\n * `Field.HelpContent` (the popover body) to drop a help button into a\n * `Field.LabelRow` without manually wiring `Popover` + `IconButton` +\n * `QuestionIcon`. All `Popover.Root` props are forwarded — pass `modal`,\n * `defaultOpen`, etc. as needed.\n *\n * Popover (not Tooltip) so the affordance is reachable on touch devices.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Help = Popover.Root;\n\n/**\n * Props for the default help popover trigger. A contextual label is required\n * so repeated help affordances do not all share the same accessible name.\n */\ntype FieldHelpTriggerProps = Partial<Omit<IconButtonProps, \"icon\" | \"label\">> &\n\tPick<IconButtonProps, \"label\"> & {\n\t\t/**\n\t\t * The icon to render inside the trigger button. Defaults to a Phosphor\n\t\t * `QuestionIcon` so the most common case only needs a contextual label.\n\t\t */\n\t\ticon?: ReactNode;\n\t};\n\n/**\n * The trigger for a `Field.Help` popover — a `Popover.Trigger` wired to a\n * ghost-appearance `IconButton` with a default Phosphor `QuestionIcon`.\n * Requires a contextual screen-reader label, and accepts `icon` or other\n * `IconButton` props for visual customization.\n *\n * Pre-styled with `text-body` (matching the figma) so the icon reads as\n * subtle metadata at rest; `IconButton`'s ghost `hover:text-strong` still\n * brightens it on interaction. Carries a default `-my-0.5` so the 24px\n * `xs` button keeps a full click target while contributing only 20px to\n * the `Field.LabelRow` flex line — matching the label's text line-height\n * so the label text is not pushed off-center.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst HelpTrigger = forwardRef<ComponentRef<\"button\">, FieldHelpTriggerProps>(\n\t(\n\t\t{\n\t\t\tappearance = \"ghost\",\n\t\t\tclassName,\n\t\t\ticon = <QuestionIcon />,\n\t\t\tlabel,\n\t\t\tsize = \"xs\",\n\t\t\ttype = \"button\",\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => (\n\t\t<Popover.Trigger asChild>\n\t\t\t<IconButton\n\t\t\t\tref={ref}\n\t\t\t\tappearance={appearance}\n\t\t\t\t// `-my-0.5` keeps the 24px (`size-6`) `xs` IconButton click target while\n\t\t\t\t// trimming 4px (2px each side) off its flex-line contribution so the row\n\t\t\t\t// height matches the label's 20px line-height. Without this the trigger\n\t\t\t\t// drives the LabelRow to 24px and pushes the label text down 2px.\n\t\t\t\tclassName={cx(\"text-body -my-0.5\", className)}\n\t\t\t\ticon={icon}\n\t\t\t\tlabel={label}\n\t\t\t\tsize={size}\n\t\t\t\ttype={type}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</Popover.Trigger>\n\t),\n);\nHelpTrigger.displayName = \"FieldHelpTrigger\";\n\n/**\n * The popover body for a `Field.Help`. Wraps `Popover.Content` so all\n * positioning / sizing options (`side`, `align`, `preferredWidth`, etc.)\n * work as expected, and overrides the inherited `data-slot` to\n * `field-help-content` so consumers can target it as part of a `Field`\n * subtree without colliding with other popovers.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst HelpContent = forwardRef<ComponentRef<\"div\">, ComponentProps<typeof Popover.Content>>(\n\t(props, ref) => <Popover.Content ref={ref} data-slot=\"field-help-content\" {...props} />,\n);\nHelpContent.displayName = \"FieldHelpContent\";\n\n/**\n * Inline \"(Optional)\" suffix to mark a field as optional. Defaults to the\n * literal string `(Optional)` so the common case is `<Field.Optional />` with\n * no children — pass children to translate or replace the text. Renders a\n * `<span>` in `text-muted` at `text-sm` / `font-normal` so it reads as\n * secondary metadata next to the bolder Label text.\n *\n * Place inside the `<Field.Label>` so screen readers announce it as part of the\n * accessible name (e.g. \"Email, Optional, edit text\"). Pair with a small\n * `gap` on the label's flex layout, or rely on the natural inline spacing.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Optional = forwardRef<ComponentRef<\"span\">, ComponentProps<\"span\"> & WithAsChild>(\n\t({ asChild, children, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"span\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-optional\"\n\t\t\t\tclassName={cx(\"text-muted text-sm font-normal font-sans\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children ?? \"(Optional)\"}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nOptional.displayName = \"FieldOptional\";\n\n/**\n * Layout container that stacks multiple `Field.Item`s vertically with\n * `gap-4` between them. This is the default way to compose multiple fields\n * — most forms only need a `Field.Group` of `Field.Item`s. Reach for\n * `Field.Set` + `Field.Legend` only when the grouping carries semantic\n * weight (e.g. a `RadioGroup` or related checkboxes).\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Group = forwardRef<ComponentRef<\"div\">, ComponentProps<\"div\"> & WithAsChild>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"div\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-group\"\n\t\t\t\tclassName={cx(\"flex w-full flex-col gap-4\", className)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nGroup.displayName = \"FieldGroup\";\n\n/**\n * A single form field — `Label`, a control (`Input`, `Select`, `Checkbox`,\n * etc.), and any `Field.Description`, `Field.Errors`, or `Field.ErrorList` siblings stacked\n * vertically with a consistent `gap-1.5` so help and error messaging sit\n * tightly under the input.\n *\n * Renders a plain `<div>` — the `<label htmlFor>` ↔ control association\n * already provides the right semantics for a single field, so no implicit\n * `role` is added. `Field.Item` owns the contextual description/error IDs\n * that `Field.Control` applies to the focusable control. Rendered errors\n * infer an `\"error\"` validation state unless `validation` is supplied as an\n * explicit override.\n *\n * **Single-slot constraint.** A `Field.Item` owns one description ID and one\n * errors ID, so render at most one `Field.Description` and one\n * `Field.Errors` *or* `Field.ErrorList` (not both) per item. A second instance\n * would duplicate the slot `id` in the DOM. Pass multiple messages to\n * `Field.Errors`, or multiple `Field.ErrorItem` children to `Field.ErrorList`,\n * instead.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\ntype FieldItemProps = ComponentProps<\"div\"> &\n\tWithAsChild &\n\tWithValidation & {\n\t\t/**\n\t\t * Form-value name for the field. Required so `Field.Control` can splat\n\t\t * it onto the focusable child while `Field.Item` owns the stable\n\t\t * generated control id used by `Field.Label`'s `htmlFor`.\n\t\t */\n\t\tname: string;\n\t};\n\nconst Item = forwardRef<ComponentRef<\"div\">, FieldItemProps>(\n\t({ asChild, children, className, name, validation: validationProp, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"div\";\n\t\tconst controlId = useId();\n\t\tconst descriptionId = useId();\n\t\tconst errorId = useId();\n\t\tconst [hasErrors, setHasErrors] = useState(false);\n\t\tconst validation = resolveValidation(validationProp ?? (hasErrors ? \"error\" : undefined));\n\n\t\tconst registerError = useCallback(() => {\n\t\t\tsetHasErrors(true);\n\n\t\t\treturn () => {\n\t\t\t\tsetHasErrors(false);\n\t\t\t};\n\t\t}, []);\n\n\t\tconst context = useMemo(\n\t\t\t() => ({\n\t\t\t\tcontrolId,\n\t\t\t\tdescriptionId,\n\t\t\t\terrorId,\n\t\t\t\thasErrors,\n\t\t\t\tname,\n\t\t\t\tregisterError,\n\t\t\t\tvalidation,\n\t\t\t}),\n\t\t\t[controlId, descriptionId, errorId, hasErrors, name, registerError, validation],\n\t\t);\n\n\t\treturn (\n\t\t\t<FieldItemContext.Provider value={context}>\n\t\t\t\t<FieldValidationProvider validation={validation}>\n\t\t\t\t\t<Comp\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\tdata-slot=\"field-item\"\n\t\t\t\t\t\tdata-validation={validation}\n\t\t\t\t\t\tclassName={cx(\"flex w-full flex-col gap-1.5\", className)}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</Comp>\n\t\t\t\t</FieldValidationProvider>\n\t\t\t</FieldItemContext.Provider>\n\t\t);\n\t},\n);\nItem.displayName = \"FieldItem\";\n\ntype FieldControlSlotProps = Omit<\n\tComponentProps<typeof Slot>,\n\t\"aria-describedby\" | \"aria-errormessage\" | \"aria-invalid\" | \"children\"\n>;\n\n/**\n * Element-child form of `Field.Control`. Renders via `Slot`, so it accepts\n * any HTML/Slot props and a forwarded ref — those land on the single child\n * element along with the generated ARIA props.\n */\ntype FieldControlElementProps = FieldControlSlotProps & {\n\t/**\n\t * A single control element to receive the field ARIA props.\n\t */\n\tchildren: ReactElement;\n};\n\n/**\n * Render-prop form of `Field.Control`. The caller owns the rendered element,\n * so `Field.Control` itself renders nothing — extra DOM props and `ref` have\n * no element to attach to and are intentionally not part of this variant.\n * Slot props are marked `never` so passing e.g. `className` alongside a\n * render-prop child is a type error rather than a silently ignored prop.\n */\ntype FieldControlRenderProps = {\n\t/**\n\t * A render function that places the field ARIA props onto a control of\n\t * the caller's choosing. Used for compound controls or wrappers where\n\t * `Slot` cannot reach the focusable element.\n\t */\n\tchildren: (props: FieldControlAriaProps) => ReactNode;\n} & { [K in keyof FieldControlSlotProps]?: never };\n\n/**\n * Props for `Field.Control`. A discriminated union over how the caller\n * supplies the focusable element:\n *\n * - `FieldControlElementProps` — pass a single React element child and\n * `Field.Control` clones the generated ARIA props onto it via `Slot`.\n * Accepts the full Slot prop surface plus a forwarded ref.\n * - `FieldControlRenderProps` — pass a render function that receives the\n * ARIA props and places them on a control of the caller's choosing. The\n * caller owns the rendered element, so DOM/Slot props and `ref` are\n * excluded from this variant at the type level.\n *\n * @example\n * ```tsx\n * // Element form — Slot splats id, name, and ARIA props onto <Input/>\n * <Field.Item name=\"email\">\n * <Field.Control>\n * <Input type=\"email\" />\n * </Field.Control>\n * </Field.Item>\n *\n * // Render-prop form — caller spreads the props onto its own element\n * <Field.Item name=\"acceptTerms\">\n * <Field.Control>\n * {(controlProps) => (\n * <label>\n * Accept terms\n * <input type=\"checkbox\" {...controlProps} />\n * </label>\n * )}\n * </Field.Control>\n * </Field.Item>\n * ```\n */\ntype FieldControlProps = FieldControlElementProps | FieldControlRenderProps;\n\n/**\n * Applies `Field.Item` description, error, and validation state to a single\n * focusable control. It always behaves like an `asChild` slot: pass one child\n * element to receive the generated ARIA props, or use a function child to\n * place those props manually. Mantle compound controls that consume\n * `FieldControlContext` can be wrapped at the root when their docs show that\n * composition; otherwise use the render-prop form to place the generated props\n * on the actual focusable element.\n *\n * `Field.Item` owns the full control contract — `id`, `name`, `aria-*`, and\n * `validation` all flow down from the surrounding `Field.Item` and overwrite\n * anything passed on the child. To override these values, set them on\n * `Field.Item` itself (e.g. `<Field.Item validation=\"error\">`); to opt out of\n * the contract entirely, render your control without `Field.Control`.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Control = forwardRef<HTMLElement, FieldControlProps>(({ children, ...props }, ref) => {\n\tconst context = useContext(FieldItemContext);\n\t// Field.Item owns id, name, aria-*, and validation — `cloneElement` below\n\t// overwrites whatever the child supplied, and the resolver no longer reads\n\t// child-side overrides. To override any of these, set them on Field.Item.\n\tconst controlState = resolveFieldControlAriaProps({ context });\n\n\tif (typeof children === \"function\") {\n\t\treturn (\n\t\t\t<FieldValidationProvider validation={controlState.validation}>\n\t\t\t\t<FieldControlContext.Provider value={context ? controlState.ariaProps : null}>\n\t\t\t\t\t{children(controlState.ariaProps)}\n\t\t\t\t</FieldControlContext.Provider>\n\t\t\t</FieldValidationProvider>\n\t\t);\n\t}\n\n\tinvariant(\n\t\tisValidElement<FieldControlAriaProps>(children),\n\t\t\"Field.Control expects a single React element child (or a render-prop function). Got a non-element value (string, array, fragment, null, or undefined). Wrap the control in a single element, or use the function child form: <Field.Control>{(props) => <YourControl {...props} />}</Field.Control>.\",\n\t);\n\n\t// Both `cloneElement` and `FieldControlContext` flow the same resolved\n\t// props. `cloneElement` covers the simple case (Input, native input) where\n\t// the direct child is the focusable element. `FieldControlContext` covers\n\t// compound widgets like Select / MultiSelect, where the direct child is a\n\t// context provider (e.g. `Select.Root`) that does not forward ARIA props\n\t// to its inner focusable trigger — that trigger reads the context itself.\n\treturn (\n\t\t<FieldValidationProvider validation={controlState.validation}>\n\t\t\t<FieldControlContext.Provider value={context ? controlState.ariaProps : null}>\n\t\t\t\t<Slot ref={ref} {...props}>\n\t\t\t\t\t{cloneElement(children, controlState.ariaProps)}\n\t\t\t\t</Slot>\n\t\t\t</FieldControlContext.Provider>\n\t\t</FieldValidationProvider>\n\t);\n});\nControl.displayName = \"FieldControl\";\n\n/**\n * Helper / hint text. Renders a `<p>` in the muted body color so it reads\n * as secondary to the bolder content above it. Use inside `Field.Item`, below\n * the control, to clarify expected format or constraints for that single field.\n *\n * **At most one per `Field.Item`.** `Field.Item` owns a single description\n * slot ID and applies it via context, so a second `Field.Description` would\n * duplicate that `id` in the DOM.\n *\n * **Auto-tighten.** When this description sits directly after rendered\n * `Field.Errors` or `Field.ErrorList` output, the parent's `gap-1.5`\n * collapses via a matching negative top margin so error list + helper read as\n * one tight block. Pass any margin utility (`mt-1`, `mt-0`, etc.) to override\n * — the rule's specificity is flattened to `(0,1,0)` so a single user class wins.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Description = forwardRef<ComponentRef<\"p\">, Omit<ComponentProps<\"p\">, \"id\"> & WithAsChild>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? Slot : \"p\";\n\t\tconst context = useContext(FieldItemContext);\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-description\"\n\t\t\t\tid={context?.descriptionId}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"text-body text-sm leading-4\",\n\t\t\t\t\t// When this description sits directly after a Field.ErrorList\n\t\t\t\t\t// sibling, collapse the parent's gap-1.5 with a matching negative\n\t\t\t\t\t// top margin so the list + helper read as one tight block.\n\t\t\t\t\t// Wrapping the matched selector in :where() flattens its specificity\n\t\t\t\t\t// to (0,1,0) so a user-supplied margin utility (mt-2, mt-0, etc.)\n\t\t\t\t\t// passed on Field.Description still overrides cleanly.\n\t\t\t\t\t\"[:where([data-slot=field-error-list]+&)]:-mt-1.5\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nDescription.displayName = \"FieldDescription\";\n\n/**\n * A single error message list item for a field. Renders an `<li>` in\n * `text-danger-600` so it stands out from a sibling `Field.Description`.\n * Must be rendered inside a `Field.ErrorList`. Empty or blank children render\n * nothing so message-less validator results do not produce empty list items.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"username\">\n * <Field.Label>Username</Field.Label>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.ErrorList>\n * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n * </Field.ErrorList>\n * <Field.Description>Pick something memorable.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst FieldErrorItem = forwardRef<ComponentRef<\"li\">, ComponentProps<\"li\">>(\n\t({ children, className, ...props }, ref) => {\n\t\tif (!isErrorItemRenderable(children)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<li\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"field-error\"\n\t\t\t\tclassName={cx(\"text-danger-600 text-sm leading-4\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</li>\n\t\t);\n\t},\n);\nFieldErrorItem.displayName = \"FieldErrorItem\";\n\n/**\n * Props for the `Field.Errors` convenience renderer. It owns its generated\n * children, so use `Field.ErrorList` / `Field.ErrorItem` directly when custom\n * list contents or polymorphic list markup are needed.\n */\ntype FieldErrorsProps = Omit<ComponentProps<\"ul\">, \"children\" | \"id\"> & {\n\t/**\n\t * Validation messages to render. Strings are trimmed, and empty, nullish,\n\t * or false values are ignored before rendering the list.\n\t */\n\tmessages?: readonly FieldErrorMessage[];\n};\n\n/**\n * Convenience renderer for string validation messages. Trims each message,\n * filters empty values, and renders a semantic `Field.ErrorList` containing\n * one `Field.ErrorItem` per remaining message.\n *\n * Accepts strings directly so product code can map any validation library's\n * error shape into messages without coupling Mantle to that library.\n * Deliberately does not support `asChild` because it owns the generated list\n * items; use `Field.ErrorList` with `asChild` for custom list markup.\n *\n * **At most one per `Field.Item`.** `Field.Errors` renders a `Field.ErrorList`\n * under the hood, and `Field.Item` owns a single errors slot ID. Use either\n * `Field.Errors` *or* `Field.ErrorList` per item, not both, and pass multiple\n * messages to one `Field.Errors` instead of rendering it twice.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst FieldErrors = forwardRef<ComponentRef<\"ul\">, FieldErrorsProps>(\n\t({ messages, ...props }, ref) => (\n\t\t<FieldErrorList ref={ref} {...props}>\n\t\t\t{normalizeErrorMessages(messages).map((message, index) => (\n\t\t\t\t<FieldErrorItem key={index}>{message}</FieldErrorItem>\n\t\t\t))}\n\t\t</FieldErrorList>\n\t),\n);\nFieldErrors.displayName = \"FieldErrors\";\n\n/**\n * Wraps one or more `Field.ErrorItem` children in a semantic `<ul>` with\n * `role=\"list\"` so a list of validation errors is announced as a list by\n * screen readers, including Safari/VoiceOver combinations that drop list\n * semantics when list styling is removed. Renders nothing when no children are\n * passed, or when all `Field.ErrorItem` children are empty.\n *\n * The list strips its default browser styling (`list-none`, `p-0`, `m-0`) and\n * stacks items as a flex column with no gap so consecutive errors read as a\n * single tight block.\n *\n * **At most one per `Field.Item`.** `Field.Item` owns a single errors slot ID\n * and applies it via context. Use either `Field.ErrorList` *or* `Field.Errors`\n * per item, not both, and put multiple `Field.ErrorItem` children inside the\n * single list instead of rendering two `Field.ErrorList`s.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"username\">\n * <Field.Label>Username</Field.Label>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.ErrorList>\n * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n * </Field.ErrorList>\n * <Field.Description>Pick something memorable.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst FieldErrorList = forwardRef<\n\tComponentRef<\"ul\">,\n\tOmit<ComponentProps<\"ul\">, \"id\"> & WithAsChild\n>(({ asChild, children, className, ...props }, ref) => {\n\tconst hasRenderableChildren = hasRenderableErrorListChildren({\n\t\tchildren,\n\t\terrorItemType: FieldErrorItem,\n\t});\n\tconst context = useContext(FieldItemContext);\n\tconst registerError = context?.registerError;\n\n\tuseIsomorphicLayoutEffect(() => {\n\t\tif (!hasRenderableChildren || registerError == null) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn registerError();\n\t}, [hasRenderableChildren, registerError]);\n\n\tif (!hasRenderableChildren) {\n\t\treturn null;\n\t}\n\n\tconst Comp = asChild ? Slot : \"ul\";\n\n\treturn (\n\t\t<Comp\n\t\t\tref={ref}\n\t\t\tdata-slot=\"field-error-list\"\n\t\t\tid={context?.errorId}\n\t\t\trole=\"list\"\n\t\t\tclassName={cx(\"m-0 flex w-full flex-col list-none p-0\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n});\nFieldErrorList.displayName = \"FieldErrorList\";\n\n/**\n * Compound component for semantic, accessible form fields. Composes a\n * `Field.Label`, control (`Input`, `Select`, etc.), `Field.Description`, and\n * validation errors (`Field.Errors` / `Field.ErrorList` + `Field.ErrorItem`)\n * with consistent spacing and ARIA wiring. Stack multiple fields with\n * `Field.Group`; use `Field.Set` + `Field.Legend` for radios / related\n * checkboxes that share one accessible name.\n *\n * @see https://mantle.ngrok.com/components/field\n *\n * @example\n * Composition:\n * ```\n * Field.Group\n * └── Field.Item\n * ├── Field.LabelRow\n * │ ├── Field.Label\n * │ │ └── Field.Optional\n * │ └── Field.Help\n * │ ├── Field.HelpTrigger\n * │ └── Field.HelpContent\n * ├── Field.Control\n * │ └── (control)\n * ├── Field.Errors (or)\n * ├── Field.ErrorList\n * │ └── Field.ErrorItem\n * └── Field.Description\n * ```\n *\n * @example\n * ```tsx\n * <Field.Group>\n * <Field.Item name=\"apiKey\">\n * <Field.LabelRow>\n * <Field.Label>\n * API key <Field.Optional />\n * </Field.Label>\n * <Field.Help>\n * <Field.HelpTrigger label=\"What is an API key?\" />\n * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n * </Field.Help>\n * </Field.LabelRow>\n * <Field.Control>\n * <Input />\n * </Field.Control>\n * <Field.Errors messages={[\"API key is required.\"]} />\n * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n * </Field.Item>\n * </Field.Group>\n * ```\n */\nconst Field = {\n\t/**\n\t * A single form field. Provides message IDs and validation state to\n\t * `Field.Control`; rendered errors infer `\"error\"` validation.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tItem,\n\t/**\n\t * Applies generated field ARIA props and validation state to a single\n\t * focusable control. Accepts either a single React element child (cloned\n\t * via `Slot`) or a render-prop child that receives the ARIA props for\n\t * cases where `Slot` cannot reach the focusable element — for example a\n\t * `<label>`-wrapped native checkbox, or a third-party component that\n\t * needs the props placed manually on an inner input.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * // Element child — Slot splats id, name, and ARIA props onto <Input/>.\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.Label>API key</Field.Label>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * </Field.Item>\n\t * ```\n\t *\n\t * @example\n\t * ```tsx\n\t * // Render-prop child — caller spreads the props onto an inner element\n\t * // when the focusable target is nested (e.g. inside a <label>).\n\t * <Field.Item name=\"acceptTerms\">\n\t * <Field.Control>\n\t * {(controlProps) => (\n\t * <label>\n\t * Accept terms\n\t * <input type=\"checkbox\" {...controlProps} />\n\t * </label>\n\t * )}\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"You must accept the terms.\"]} />\n\t * </Field.Item>\n\t * ```\n\t */\n\tControl,\n\t/**\n\t * Layout container that stacks multiple `Field.Item`s vertically.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * Semantic `<fieldset>` for related controls that share one accessible\n\t * name from `Field.Legend`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Set>\n\t * <Field.Legend>Notification frequency</Field.Legend>\n\t * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n\t * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n\t * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n\t * </RadioGroup.Root>\n\t * </Field.Set>\n\t * ```\n\t */\n\tSet: FieldSet,\n\t/**\n\t * Caption for `Field.Set`. Renders a semantic `<legend>`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Set>\n\t * <Field.Legend>Notification frequency</Field.Legend>\n\t * <RadioGroup.Root name=\"frequency\" defaultValue=\"daily\">\n\t * <RadioGroup.Item value=\"daily\" id=\"freq-daily\">…</RadioGroup.Item>\n\t * <RadioGroup.Item value=\"weekly\" id=\"freq-weekly\">…</RadioGroup.Item>\n\t * </RadioGroup.Root>\n\t * </Field.Set>\n\t * ```\n\t */\n\tLegend,\n\t/**\n\t * The Mantle `Label`, exposed on `Field` for field composition. Inside a\n\t * `Field.Item`, `htmlFor` defaults to the same stable id that `Field.Control`\n\t * splats onto its focusable child — so the label-to-control association is\n\t * automatic from `Field.Item`'s required `name` and you don't need to thread\n\t * a matching `htmlFor` / `id` pair by hand. Pass an explicit `htmlFor` to\n\t * opt out (e.g. when the focusable element is rendered outside of\n\t * `Field.Control`).\n\t *\n\t * @see https://mantle.ngrok.com/components/label\n\t *\n\t * @example\n\t * ```tsx\n\t * // htmlFor is wired automatically from Field.Item's name.\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tLabel: FieldLabel,\n\t/**\n\t * Horizontal layout container for the label area of a field. Aligns a\n\t * `<Field.Label>` (which may contain `Field.Optional`) with adjacent affordances\n\t * like a help-icon `Popover.Trigger` on a shared center line with `gap-1`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tLabelRow,\n\t/**\n\t * `Popover.Root` re-export for the help-affordance pattern. Pair with\n\t * `Field.HelpTrigger` and `Field.HelpContent` to drop a `?` button next to\n\t * a label without manually composing Popover + IconButton + QuestionIcon.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tHelp,\n\t/**\n\t * Trigger for a `Field.Help` popover — a ghost `IconButton` with a default\n\t * `QuestionIcon`. Requires a contextual `label`; pass `icon` to swap the\n\t * glyph, or other `IconButton` props (`size`, `appearance`, etc.) to customize.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tHelpTrigger,\n\t/**\n\t * Body of a `Field.Help` popover. Re-exports `Popover.Content` so all\n\t * positioning / sizing options (`side`, `align`, `preferredWidth`, etc.)\n\t * work as expected.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tHelpContent,\n\t/**\n\t * Inline \"(Optional)\" suffix to mark a field as optional. Default content\n\t * is `(Optional)`; pass children to translate or replace it. Place inside\n\t * the `<Field.Label>` so screen readers announce it as part of the accessible\n\t * name.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tOptional,\n\t/**\n\t * Helper / hint text rendered below the control in the muted body color.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tDescription,\n\t/**\n\t * Convenience renderer for validation messages. Trims string messages,\n\t * filters empty values, and renders a `Field.ErrorList` with one\n\t * `Field.ErrorItem` for each remaining message.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"apiKey\">\n\t * <Field.LabelRow>\n\t * <Field.Label>\n\t * API key <Field.Optional />\n\t * </Field.Label>\n\t * <Field.Help>\n\t * <Field.HelpTrigger label=\"What is an API key?\" />\n\t * <Field.HelpContent>Copy this from the dashboard.</Field.HelpContent>\n\t * </Field.Help>\n\t * </Field.LabelRow>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.Errors messages={[\"API key is required.\"]} />\n\t * <Field.Description>You can find this in the ngrok dashboard.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tErrors: FieldErrors,\n\t/**\n\t * Wraps one or more `Field.ErrorItem` children in a semantic `<ul>`.\n\t * Renders nothing when given no renderable children.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"username\">\n\t * <Field.Label>Username</Field.Label>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.ErrorList>\n\t * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n\t * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n\t * </Field.ErrorList>\n\t * <Field.Description>Pick something memorable.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tErrorList: FieldErrorList,\n\t/**\n\t * A single error message list item for a field. Renders an `<li>` in\n\t * `text-danger-600` and must be nested inside a `Field.ErrorList`.\n\t *\n\t * @see https://mantle.ngrok.com/components/field\n\t *\n\t * @example\n\t * ```tsx\n\t * <Field.Group>\n\t * <Field.Item name=\"username\">\n\t * <Field.Label>Username</Field.Label>\n\t * <Field.Control>\n\t * <Input />\n\t * </Field.Control>\n\t * <Field.ErrorList>\n\t * <Field.ErrorItem>Must be at least 3 characters.</Field.ErrorItem>\n\t * <Field.ErrorItem>Use letters, numbers, hyphens, or underscores.</Field.ErrorItem>\n\t * </Field.ErrorList>\n\t * <Field.Description>Pick something memorable.</Field.Description>\n\t * </Field.Item>\n\t * </Field.Group>\n\t * ```\n\t */\n\tErrorItem: FieldErrorItem,\n} as const;\n\nexport {\n\t//,\n\tField,\n};\n","import { normalizeErrorMessages } from \"./error-helpers.js\";\n\n/**\n * Shapes commonly found in `field.state.meta.errors` from TanStack React Form\n * across its built-in validators (Standard Schema / Zod issues, raw strings,\n * thrown `Error` instances) plus the falsy slots Standard Schema can produce.\n */\ntype FieldError = { readonly message?: string | undefined } | string | null | undefined | false;\n\n/**\n * Reduce a TanStack React Form field's `meta.errors` array (or any array of\n * mixed string / `{ message }` / nullish error entries) to a clean `string[]`\n * for passing directly to `Field.Errors`' `messages` prop.\n *\n * Handles the shapes TanStack form yields for Zod, Standard Schema, and\n * thrown `Error` validators: items may be strings, objects with `.message`,\n * `undefined`, `null`, or `false`. Empty / whitespace-only messages are\n * dropped and duplicate messages are collapsed so callers don't have to filter\n * again.\n *\n * @example\n * ```tsx\n * <Field.Item>\n * <Field.Label htmlFor={field.name}>Email</Field.Label>\n * <Field.Control>\n * <Input id={field.name} value={field.state.value} />\n * </Field.Control>\n * <Field.Errors messages={toErrorMessages(field.state.meta.errors)} />\n * </Field.Item>\n * ```\n */\nconst toErrorMessages = (errors: readonly FieldError[] | null | undefined): string[] =>\n\tnormalizeErrorMessages(\n\t\terrors?.map((error) => (typeof error === \"string\" || !error ? error : error.message)),\n\t);\n\nexport {\n\t//,\n\ttoErrorMessages,\n};\n\nexport type {\n\t//,\n\tFieldError,\n};\n"],"mappings":"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"}
package/dist/hooks.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { n as MarginType, o as useComposedRefs, s as copyToClipboard } from "./in-view-DdIrfU4u.js";
2
- import { RefObject, useLayoutEffect } from "react";
1
+ import { n as MarginType, o as useComposedRefs, s as copyToClipboard } from "./in-view-BUgyu-Tk.js";
2
+ import { RefObject, useEffect } from "react";
3
3
 
4
4
  //#region src/hooks/use-breakpoint.d.ts
5
5
  /**
@@ -282,7 +282,7 @@ declare function useIsHydrated(): boolean;
282
282
  *
283
283
  * return <div ref={ref}>Width: {width}</div>;
284
284
  */
285
- declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
285
+ declare const useIsomorphicLayoutEffect: typeof useEffect;
286
286
  //#endregion
287
287
  //#region src/hooks/use-matches-media-query.d.ts
288
288
  /**
package/dist/hooks.js CHANGED
@@ -1,2 +1,2 @@
1
- import{t as e}from"./use-matches-media-query-CojcYxlA.js";import{r as t}from"./browser-only-QPyyfLaB.js";import{n}from"./compose-refs-DZ3cPi47.js";import{t as r}from"./use-copy-to-clipboard-CTgtLjUg.js";import{t as i}from"./use-isomorphic-layout-effect-CNSD0lhi.js";import{n as a,t as o}from"./use-prefers-reduced-motion-YUurmkwx.js";import{t as s}from"./in-view-BLZVEGFC.js";import{useCallback as c,useEffect as l,useMemo as u,useReducer as d,useRef as f,useState as p,useSyncExternalStore as m}from"react";const h=[`2xl`,`xl`,`lg`,`md`,`sm`,`xs`,`2xs`],g=[`default`,...h];function _(){return m(j,M,()=>`default`)}function v(e){return m(P(e),I(e),()=>!1)}const y={"2xl":`(min-width: 96rem)`,xl:`(min-width: 80rem)`,lg:`(min-width: 64rem)`,md:`(min-width: 48rem)`,sm:`(min-width: 40rem)`,xs:`(min-width: 30rem)`,"2xs":`(min-width: 22.5rem)`},b={"2xl":`(max-width: 95.99rem)`,xl:`(max-width: 79.99rem)`,lg:`(max-width: 63.99rem)`,md:`(max-width: 47.99rem)`,sm:`(max-width: 39.99rem)`,xs:`(max-width: 29.99rem)`,"2xs":`(max-width: 22.49rem)`};let x=null,S=null;function C(){return x||={"2xl":window.matchMedia(y[`2xl`]),xl:window.matchMedia(y.xl),lg:window.matchMedia(y.lg),md:window.matchMedia(y.md),sm:window.matchMedia(y.sm),xs:window.matchMedia(y.xs),"2xs":window.matchMedia(y[`2xs`])},x}function w(e){return S||={"2xl":window.matchMedia(b[`2xl`]),xl:window.matchMedia(b.xl),lg:window.matchMedia(b.lg),md:window.matchMedia(b.md),sm:window.matchMedia(b.sm),xs:window.matchMedia(b.xs),"2xs":window.matchMedia(b[`2xs`])},S[e]}let T=`default`;const E=new Set;let D=!1;function O(){let e=C();for(let t of h)if(e[t].matches)return t;return`default`}let k=!1;function A(){k||(k=!0,requestAnimationFrame(()=>{k=!1;let e=O();if(e!==T){T=e;for(let e of E)e()}}))}function j(e){if(E.add(e),!D){D=!0;let e=C();T=O();for(let t of Object.values(e))t.addEventListener(`change`,A)}return e(),()=>{if(E.delete(e),E.size===0&&D){D=!1;let e=C();for(let t of Object.values(e))t.removeEventListener(`change`,A)}}}function M(){return T}const N=new Map;function P(e){let t=N.get(e);return t||(t=t=>{let n=w(e),r=!1,i=()=>{r||(r=!0,requestAnimationFrame(()=>{r=!1,t()}))};return n.addEventListener(`change`,i),()=>{n.removeEventListener(`change`,i)}},N.set(e,t),t)}const F=new Map;function I(e){let t=F.get(e);return t||(t=()=>w(e).matches,F.set(e,t),t)}function L(e){let t=f(e);return l(()=>{t.current=e}),u(()=>((...e)=>t.current?.(...e)),[])}function R(e,t){let n=L(e),r=f(0);return l(()=>()=>window.clearTimeout(r.current),[]),c((...e)=>{window.clearTimeout(r.current),r.current=window.setTimeout(()=>n(...e),t.waitMs)},[n,t.waitMs])}const z=(e=`mantle`)=>u(()=>B(e),[e]);function B(e=`mantle`){return[e.trim()||`mantle`,V()].join(`-`)}function V(){return Math.random().toString(36).substring(2,9)}function H(){let e=a();return u(()=>e?`auto`:`smooth`,[e])}function U(e,{root:t,margin:n,amount:r,once:i=!1,initial:a=!1}={}){let[o,c]=p(a);return l(()=>{if(!e.current||i&&o)return;function a(){return c(!0),i?void 0:()=>c(!1)}let l={root:t&&t.current||void 0,margin:n,amount:r};return s(e.current,a,l)},[t,e,n,i,r]),o}function W(e,t){switch(t.type){case`push`:return{undoStack:[...e.undoStack,t.snapshot],redoStack:[]};case`undo`:{if(e.undoStack.length===0)return e;let n=e.undoStack.slice(0,-1);return e.undoStack[e.undoStack.length-1]===void 0?e:{undoStack:n,redoStack:[...e.redoStack,t.current]}}case`redo`:{if(e.redoStack.length===0)return e;let n=e.redoStack.slice(0,-1);return e.redoStack[e.redoStack.length-1]===void 0?e:{undoStack:[...e.undoStack,t.current],redoStack:n}}}}function G(){let[e,t]=d(W,{undoStack:[],redoStack:[]}),n=c(e=>{t({type:`push`,snapshot:e})},[]),r=c(n=>{let r=e.undoStack[e.undoStack.length-1];if(r!==void 0)return t({type:`undo`,current:n}),r},[e.undoStack]),i=c(n=>{let r=e.redoStack[e.redoStack.length-1];if(r!==void 0)return t({type:`redo`,current:n}),r},[e.redoStack]);return u(()=>({canUndo:e.undoStack.length>0,canRedo:e.redoStack.length>0,push:n,undo:r,redo:i}),[e.undoStack.length,e.redoStack.length,n,r,i])}export{g as breakpoints,o as getPrefersReducedMotion,_ as useBreakpoint,L as useCallbackRef,n as useComposedRefs,r as useCopyToClipboard,R as useDebouncedCallback,U as useInView,v as useIsBelowBreakpoint,t as useIsHydrated,i as useIsomorphicLayoutEffect,e as useMatchesMediaQuery,a as usePrefersReducedMotion,z as useRandomStableId,H as useScrollBehavior,G as useUndoRedo};
1
+ import{t as e}from"./use-matches-media-query-CojcYxlA.js";import{r as t}from"./browser-only-QPyyfLaB.js";import{n}from"./compose-refs-DZ3cPi47.js";import{t as r}from"./use-copy-to-clipboard-CTgtLjUg.js";import{t as i}from"./use-isomorphic-layout-effect-CNSD0lhi.js";import{n as a,t as o}from"./use-prefers-reduced-motion-Bpx8G3UT.js";import{t as s}from"./in-view-CeVqeGbv.js";import{useCallback as c,useEffect as l,useMemo as u,useReducer as d,useRef as f,useState as p,useSyncExternalStore as m}from"react";const h=[`2xl`,`xl`,`lg`,`md`,`sm`,`xs`,`2xs`],g=[`default`,...h];function _(){return m(j,M,()=>`default`)}function v(e){return m(P(e),I(e),()=>!1)}const y={"2xl":`(min-width: 96rem)`,xl:`(min-width: 80rem)`,lg:`(min-width: 64rem)`,md:`(min-width: 48rem)`,sm:`(min-width: 40rem)`,xs:`(min-width: 30rem)`,"2xs":`(min-width: 22.5rem)`},b={"2xl":`(max-width: 95.99rem)`,xl:`(max-width: 79.99rem)`,lg:`(max-width: 63.99rem)`,md:`(max-width: 47.99rem)`,sm:`(max-width: 39.99rem)`,xs:`(max-width: 29.99rem)`,"2xs":`(max-width: 22.49rem)`};let x=null,S=null;function C(){return x||={"2xl":window.matchMedia(y[`2xl`]),xl:window.matchMedia(y.xl),lg:window.matchMedia(y.lg),md:window.matchMedia(y.md),sm:window.matchMedia(y.sm),xs:window.matchMedia(y.xs),"2xs":window.matchMedia(y[`2xs`])},x}function w(e){return S||={"2xl":window.matchMedia(b[`2xl`]),xl:window.matchMedia(b.xl),lg:window.matchMedia(b.lg),md:window.matchMedia(b.md),sm:window.matchMedia(b.sm),xs:window.matchMedia(b.xs),"2xs":window.matchMedia(b[`2xs`])},S[e]}let T=`default`;const E=new Set;let D=!1;function O(){let e=C();for(let t of h)if(e[t].matches)return t;return`default`}let k=!1;function A(){k||(k=!0,requestAnimationFrame(()=>{k=!1;let e=O();if(e!==T){T=e;for(let e of E)e()}}))}function j(e){if(E.add(e),!D){D=!0;let e=C();T=O();for(let t of Object.values(e))t.addEventListener(`change`,A)}return e(),()=>{if(E.delete(e),E.size===0&&D){D=!1;let e=C();for(let t of Object.values(e))t.removeEventListener(`change`,A)}}}function M(){return T}const N=new Map;function P(e){let t=N.get(e);return t||(t=t=>{let n=w(e),r=!1,i=()=>{r||(r=!0,requestAnimationFrame(()=>{r=!1,t()}))};return n.addEventListener(`change`,i),()=>{n.removeEventListener(`change`,i)}},N.set(e,t),t)}const F=new Map;function I(e){let t=F.get(e);return t||(t=()=>w(e).matches,F.set(e,t),t)}function L(e){let t=f(e);return l(()=>{t.current=e}),u(()=>((...e)=>t.current?.(...e)),[])}function R(e,t){let n=L(e),r=f(0);return l(()=>()=>window.clearTimeout(r.current),[]),c((...e)=>{window.clearTimeout(r.current),r.current=window.setTimeout(()=>n(...e),t.waitMs)},[n,t.waitMs])}const z=(e=`mantle`)=>u(()=>B(e),[e]);function B(e=`mantle`){return[e.trim()||`mantle`,V()].join(`-`)}function V(){return Math.random().toString(36).substring(2,9)}function H(){let e=a();return u(()=>e?`auto`:`smooth`,[e])}function U(e,{root:t,margin:n,amount:r,once:i=!1,initial:a=!1}={}){let[o,c]=p(a);return l(()=>{if(!e.current||i&&o)return;function a(){return c(!0),i?void 0:()=>c(!1)}let l={root:t&&t.current||void 0,margin:n,amount:r};return s(e.current,a,l)},[t,e,n,i,r]),o}function W(e,t){switch(t.type){case`push`:return{undoStack:[...e.undoStack,t.snapshot],redoStack:[]};case`undo`:{if(e.undoStack.length===0)return e;let n=e.undoStack.slice(0,-1);return e.undoStack[e.undoStack.length-1]===void 0?e:{undoStack:n,redoStack:[...e.redoStack,t.current]}}case`redo`:{if(e.redoStack.length===0)return e;let n=e.redoStack.slice(0,-1);return e.redoStack[e.redoStack.length-1]===void 0?e:{undoStack:[...e.undoStack,t.current],redoStack:n}}}}function G(){let[e,t]=d(W,{undoStack:[],redoStack:[]}),n=c(e=>{t({type:`push`,snapshot:e})},[]),r=c(n=>{let r=e.undoStack[e.undoStack.length-1];if(r!==void 0)return t({type:`undo`,current:n}),r},[e.undoStack]),i=c(n=>{let r=e.redoStack[e.redoStack.length-1];if(r!==void 0)return t({type:`redo`,current:n}),r},[e.redoStack]);return u(()=>({canUndo:e.undoStack.length>0,canRedo:e.redoStack.length>0,push:n,undo:r,redo:i}),[e.undoStack.length,e.redoStack.length,n,r,i])}export{g as breakpoints,o as getPrefersReducedMotion,_ as useBreakpoint,L as useCallbackRef,n as useComposedRefs,r as useCopyToClipboard,R as useDebouncedCallback,U as useInView,v as useIsBelowBreakpoint,t as useIsHydrated,i as useIsomorphicLayoutEffect,e as useMatchesMediaQuery,a as usePrefersReducedMotion,z as useRandomStableId,H as useScrollBehavior,G as useUndoRedo};
2
2
  //# sourceMappingURL=hooks.js.map
@@ -1,4 +1,4 @@
1
- import { t as SvgAttributes } from "./types-DnghL1WE.js";
1
+ import { t as SvgAttributes } from "./types-QKZ5fvaQ.js";
2
2
  import * as _$react from "react";
3
3
  import { ReactNode } from "react";
4
4
 
@@ -24,4 +24,4 @@ type IconProps = Omit<SvgAttributes, "children"> & {
24
24
  declare const Icon: _$react.ForwardRefExoticComponent<Omit<IconProps, "ref"> & _$react.RefAttributes<SVGSVGElement>>;
25
25
  //#endregion
26
26
  export { IconProps as n, Icon as t };
27
- //# sourceMappingURL=icon-D_BMDi_q.d.ts.map
27
+ //# sourceMappingURL=icon-BJ7q2RXZ.d.ts.map
@@ -1,5 +1,5 @@
1
- import { t as WithAsChild } from "./as-child-C2PttRwz.js";
2
- import { t as VariantProps } from "./variant-props-B4io4uA_.js";
1
+ import { t as WithAsChild } from "./as-child-CpZKMqTE.js";
2
+ import { t as VariantProps } from "./variant-props-BZbM__kQ.js";
3
3
  import * as _$react from "react";
4
4
  import { ButtonHTMLAttributes, ReactNode } from "react";
5
5
  import * as _$class_variance_authority_types0 from "class-variance-authority/types";
@@ -95,4 +95,4 @@ type IconButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & WithAsChild & I
95
95
  declare const IconButton: _$react.ForwardRefExoticComponent<IconButtonProps & _$react.RefAttributes<HTMLButtonElement>>;
96
96
  //#endregion
97
97
  export { IconButtonProps as n, IconButton as t };
98
- //# sourceMappingURL=icon-button-Dty-yfE2.d.ts.map
98
+ //# sourceMappingURL=icon-button-BDTb-lxs.d.ts.map
package/dist/icon.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as SvgAttributes } from "./types-DnghL1WE.js";
2
- import { n as IconProps, t as Icon } from "./icon-D_BMDi_q.js";
3
- import { n as SvgOnlyProps, t as SvgOnly } from "./svg-only-CLbMy439.js";
1
+ import { t as SvgAttributes } from "./types-QKZ5fvaQ.js";
2
+ import { n as IconProps, t as Icon } from "./icon-BJ7q2RXZ.js";
3
+ import { n as SvgOnlyProps, t as SvgOnly } from "./svg-only-D4uqM1OC.js";
4
4
  export { Icon, type IconProps, type SvgAttributes, SvgOnly, type SvgOnlyProps };
package/dist/icons.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { t as SvgAttributes } from "./types-DnghL1WE.js";
2
- import { a as AlphanumericSortingDirection, c as TimeSortingDirection, o as SortingDirection, s as SortingMode } from "./direction-CVntIxOS.js";
3
- import { i as Theme } from "./themes-f2W5S6xS.js";
1
+ import { t as SvgAttributes } from "./types-QKZ5fvaQ.js";
2
+ import { a as AlphanumericSortingDirection, c as TimeSortingDirection, o as SortingDirection, s as SortingMode } from "./direction-D9IZ1wW6.js";
3
+ import { i as Theme } from "./themes-FPux5kIu.js";
4
4
  import { ComponentProps } from "react";
5
5
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
6
6
 
@@ -93,4 +93,4 @@ declare function inView(element: Element, onStart: (element: Element, entry: Int
93
93
  }?: InViewOptions): VoidFunction;
94
94
  //#endregion
95
95
  export { composeRefs as a, inView as i, MarginType as n, useComposedRefs as o, ViewChangeHandler as r, copyToClipboard as s, InViewOptions as t };
96
- //# sourceMappingURL=in-view-DdIrfU4u.d.ts.map
96
+ //# sourceMappingURL=in-view-BUgyu-Tk.d.ts.map
@@ -1,2 +1,2 @@
1
1
  const e={some:0,all:1};function t(t,n,{root:r,margin:i,amount:a=`some`}={}){let o=new WeakMap,s=new IntersectionObserver(e=>{e.forEach(e=>{let t=o.get(e.target);if(e.isIntersecting!==!!t)if(e.isIntersecting){let t=n(e.target,e);typeof t==`function`?o.set(e.target,t):s.unobserve(e.target)}else typeof t==`function`&&(t(e),o.delete(e.target))})},{root:r,rootMargin:i,threshold:typeof a==`number`?a:e[a]});return s.observe(t),()=>{s.unobserve(t),s.disconnect()}}export{t};
2
- //# sourceMappingURL=in-view-BLZVEGFC.js.map
2
+ //# sourceMappingURL=in-view-CeVqeGbv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"in-view-BLZVEGFC.js","names":[],"sources":["../src/utils/in-view.ts"],"sourcesContent":["type MarginValue = `${number}${\"px\" | \"%\"}`;\n\n/**\n * Margin string used to expand or contract the intersection root's bounding box.\n * Follows the same syntax as the CSS `margin` shorthand (1–4 values).\n *\n * @example \"10px\"\n * @example \"10% 20px\"\n * @example \"10px 20px 10px 20px\"\n */\ntype MarginType =\n\t| MarginValue\n\t| `${MarginValue} ${MarginValue}`\n\t| `${MarginValue} ${MarginValue} ${MarginValue}`\n\t| `${MarginValue} ${MarginValue} ${MarginValue} ${MarginValue}`;\n\n/**\n * Options for the `inView` helper.\n */\ntype InViewOptions = {\n\t/**\n\t * The scrollable container element (or `Document`) to use as the intersection root.\n\t * Defaults to the browser viewport.\n\t */\n\troot?: Element | Document;\n\n\t/**\n\t * Expand or contract the detected area from each side of the root's bounding box.\n\t * Uses the same syntax as the CSS `margin` shorthand (e.g. `\"10px\"`, `\"10% 20px\"`).\n\t */\n\tmargin?: MarginType;\n\n\t/**\n\t * How much of the element must be visible before it is considered in view.\n\t * - `\"some\"` (default): Any part of the element is visible.\n\t * - `\"all\"`: The entire element is visible.\n\t * - `number`: An intersection ratio between `0` and `1` (e.g. `0.5` for 50%).\n\t */\n\tamount?: \"some\" | \"all\" | number;\n};\n\n/**\n * Callback invoked when an observed element leaves the viewport.\n * Receives the `IntersectionObserverEntry` for the departing element.\n */\ntype ViewChangeHandler = (entry: IntersectionObserverEntry) => void;\n\nconst thresholds = {\n\tsome: 0,\n\tall: 1,\n};\n\n/**\n * Observe when a DOM element enters or leaves the viewport (or a scrollable\n * container) using the `IntersectionObserver` API.\n *\n * When the element enters the viewport, `onStart` is called. If `onStart`\n * returns a function, that function is called when the element leaves the\n * viewport. If `onStart` returns nothing, the element is unobserved after\n * the first entry.\n *\n * @param element - The DOM element to observe.\n * @param onStart - Called when the element enters the viewport. Optionally\n * returns a cleanup function called when the element leaves.\n * @param options - Options for the intersection root, margin, and threshold.\n * @returns A cleanup function that disconnects the observer.\n *\n * @example\n * const stop = inView(element, (el) => {\n * el.classList.add(\"visible\");\n * return () => el.classList.remove(\"visible\");\n * });\n *\n * // Later, stop observing:\n * stop();\n */\nfunction inView(\n\telement: Element,\n\tonStart: (element: Element, entry: IntersectionObserverEntry) => void | ViewChangeHandler,\n\t{ root, margin: rootMargin, amount = \"some\" }: InViewOptions = {},\n): VoidFunction {\n\tconst activeIntersections = new WeakMap<Element, ViewChangeHandler>();\n\n\tconst onIntersectionChange: IntersectionObserverCallback = (entries) => {\n\t\tentries.forEach((entry) => {\n\t\t\tconst onEnd = activeIntersections.get(entry.target);\n\n\t\t\t/**\n\t\t\t * If there's no change to the intersection, we don't need to\n\t\t\t * do anything here.\n\t\t\t */\n\t\t\tif (entry.isIntersecting === Boolean(onEnd)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (entry.isIntersecting) {\n\t\t\t\tconst newOnEnd = onStart(entry.target, entry);\n\t\t\t\tif (typeof newOnEnd === \"function\") {\n\t\t\t\t\tactiveIntersections.set(entry.target, newOnEnd);\n\t\t\t\t} else {\n\t\t\t\t\tobserver.unobserve(entry.target);\n\t\t\t\t}\n\t\t\t} else if (typeof onEnd === \"function\") {\n\t\t\t\tonEnd(entry);\n\t\t\t\tactiveIntersections.delete(entry.target);\n\t\t\t}\n\t\t});\n\t};\n\n\tconst observer = new IntersectionObserver(onIntersectionChange, {\n\t\troot,\n\t\trootMargin,\n\t\tthreshold: typeof amount === \"number\" ? amount : thresholds[amount],\n\t});\n\n\tobserver.observe(element);\n\n\treturn () => {\n\t\tobserver.unobserve(element);\n\t\tobserver.disconnect();\n\t};\n}\n\nexport { inView };\nexport type { InViewOptions, MarginType, ViewChangeHandler };\n"],"mappings":"AA+CA,MAAM,EAAa,CAClB,KAAM,EACN,IAAK,EACL,CA0BD,SAAS,EACR,EACA,EACA,CAAE,OAAM,OAAQ,EAAY,SAAS,QAA0B,EAAE,CAClD,CACf,IAAM,EAAsB,IAAI,QA4B1B,EAAW,IAAI,qBA1BuC,GAAY,CACvE,EAAQ,QAAS,GAAU,CAC1B,IAAM,EAAQ,EAAoB,IAAI,EAAM,OAAO,CAM/C,KAAM,iBAAmB,EAAQ,EAIrC,GAAI,EAAM,eAAgB,CACzB,IAAM,EAAW,EAAQ,EAAM,OAAQ,EAAM,CACzC,OAAO,GAAa,WACvB,EAAoB,IAAI,EAAM,OAAQ,EAAS,CAE/C,EAAS,UAAU,EAAM,OAAO,MAEvB,OAAO,GAAU,aAC3B,EAAM,EAAM,CACZ,EAAoB,OAAO,EAAM,OAAO,GAExC,EAG6D,CAC/D,OACA,aACA,UAAW,OAAO,GAAW,SAAW,EAAS,EAAW,GAC5D,CAAC,CAIF,OAFA,EAAS,QAAQ,EAAQ,KAEZ,CACZ,EAAS,UAAU,EAAQ,CAC3B,EAAS,YAAY"}
1
+ {"version":3,"file":"in-view-CeVqeGbv.js","names":[],"sources":["../src/utils/in-view.ts"],"sourcesContent":["type MarginValue = `${number}${\"px\" | \"%\"}`;\n\n/**\n * Margin string used to expand or contract the intersection root's bounding box.\n * Follows the same syntax as the CSS `margin` shorthand (1–4 values).\n *\n * @example \"10px\"\n * @example \"10% 20px\"\n * @example \"10px 20px 10px 20px\"\n */\ntype MarginType =\n\t| MarginValue\n\t| `${MarginValue} ${MarginValue}`\n\t| `${MarginValue} ${MarginValue} ${MarginValue}`\n\t| `${MarginValue} ${MarginValue} ${MarginValue} ${MarginValue}`;\n\n/**\n * Options for the `inView` helper.\n */\ntype InViewOptions = {\n\t/**\n\t * The scrollable container element (or `Document`) to use as the intersection root.\n\t * Defaults to the browser viewport.\n\t */\n\troot?: Element | Document;\n\n\t/**\n\t * Expand or contract the detected area from each side of the root's bounding box.\n\t * Uses the same syntax as the CSS `margin` shorthand (e.g. `\"10px\"`, `\"10% 20px\"`).\n\t */\n\tmargin?: MarginType;\n\n\t/**\n\t * How much of the element must be visible before it is considered in view.\n\t * - `\"some\"` (default): Any part of the element is visible.\n\t * - `\"all\"`: The entire element is visible.\n\t * - `number`: An intersection ratio between `0` and `1` (e.g. `0.5` for 50%).\n\t */\n\tamount?: \"some\" | \"all\" | number;\n};\n\n/**\n * Callback invoked when an observed element leaves the viewport.\n * Receives the `IntersectionObserverEntry` for the departing element.\n */\ntype ViewChangeHandler = (entry: IntersectionObserverEntry) => void;\n\nconst thresholds = {\n\tsome: 0,\n\tall: 1,\n};\n\n/**\n * Observe when a DOM element enters or leaves the viewport (or a scrollable\n * container) using the `IntersectionObserver` API.\n *\n * When the element enters the viewport, `onStart` is called. If `onStart`\n * returns a function, that function is called when the element leaves the\n * viewport. If `onStart` returns nothing, the element is unobserved after\n * the first entry.\n *\n * @param element - The DOM element to observe.\n * @param onStart - Called when the element enters the viewport. Optionally\n * returns a cleanup function called when the element leaves.\n * @param options - Options for the intersection root, margin, and threshold.\n * @returns A cleanup function that disconnects the observer.\n *\n * @example\n * const stop = inView(element, (el) => {\n * el.classList.add(\"visible\");\n * return () => el.classList.remove(\"visible\");\n * });\n *\n * // Later, stop observing:\n * stop();\n */\nfunction inView(\n\telement: Element,\n\tonStart: (element: Element, entry: IntersectionObserverEntry) => void | ViewChangeHandler,\n\t{ root, margin: rootMargin, amount = \"some\" }: InViewOptions = {},\n): VoidFunction {\n\tconst activeIntersections = new WeakMap<Element, ViewChangeHandler>();\n\n\tconst onIntersectionChange: IntersectionObserverCallback = (entries) => {\n\t\tentries.forEach((entry) => {\n\t\t\tconst onEnd = activeIntersections.get(entry.target);\n\n\t\t\t/**\n\t\t\t * If there's no change to the intersection, we don't need to\n\t\t\t * do anything here.\n\t\t\t */\n\t\t\tif (entry.isIntersecting === Boolean(onEnd)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (entry.isIntersecting) {\n\t\t\t\tconst newOnEnd = onStart(entry.target, entry);\n\t\t\t\tif (typeof newOnEnd === \"function\") {\n\t\t\t\t\tactiveIntersections.set(entry.target, newOnEnd);\n\t\t\t\t} else {\n\t\t\t\t\tobserver.unobserve(entry.target);\n\t\t\t\t}\n\t\t\t} else if (typeof onEnd === \"function\") {\n\t\t\t\tonEnd(entry);\n\t\t\t\tactiveIntersections.delete(entry.target);\n\t\t\t}\n\t\t});\n\t};\n\n\tconst observer = new IntersectionObserver(onIntersectionChange, {\n\t\troot,\n\t\trootMargin,\n\t\tthreshold: typeof amount === \"number\" ? amount : thresholds[amount],\n\t});\n\n\tobserver.observe(element);\n\n\treturn () => {\n\t\tobserver.unobserve(element);\n\t\tobserver.disconnect();\n\t};\n}\n\nexport { inView };\nexport type { InViewOptions, MarginType, ViewChangeHandler };\n"],"mappings":"AA+CA,MAAM,EAAa,CAClB,KAAM,EACN,IAAK,EACL,CA0BD,SAAS,EACR,EACA,EACA,CAAE,OAAM,OAAQ,EAAY,SAAS,QAA0B,EAAE,CAClD,CACf,IAAM,EAAsB,IAAI,QA4B1B,EAAW,IAAI,qBA1BuC,GAAY,CACvE,EAAQ,QAAS,GAAU,CAC1B,IAAM,EAAQ,EAAoB,IAAI,EAAM,OAAO,CAM/C,KAAM,iBAAmB,EAAQ,EAIrC,GAAI,EAAM,eAAgB,CACzB,IAAM,EAAW,EAAQ,EAAM,OAAQ,EAAM,CACzC,OAAO,GAAa,WACvB,EAAoB,IAAI,EAAM,OAAQ,EAAS,CAE/C,EAAS,UAAU,EAAM,OAAO,MAEvB,OAAO,GAAU,aAC3B,EAAM,EAAM,CACZ,EAAoB,OAAO,EAAM,OAAO,GAExC,EAG6D,CAC/D,OACA,aACA,UAAW,OAAO,GAAW,SAAW,EAAS,EAAW,GAC5D,CAAC,CAIF,OAFA,EAAS,QAAQ,EAAQ,KAEZ,CACZ,EAAS,UAAU,EAAQ,CAC3B,EAAS,YAAY"}
@@ -44,4 +44,4 @@ type CssProperties = CSSProperties & Record<CssVariableName, string | number>;
44
44
  declare const $cssProperties: <T extends CssProperties = CssProperties>(input: T) => CSSProperties;
45
45
  //#endregion
46
46
  export { parseBooleanish as i, CssProperties as n, Booleanish as r, $cssProperties as t };
47
- //# sourceMappingURL=index-TI92Xpg5.d.ts.map
47
+ //# sourceMappingURL=index-BbZBDzPh.d.ts.map
@@ -19,4 +19,4 @@ import * as _$_radix_ui_react_slot0 from "@radix-ui/react-slot";
19
19
  declare const Slot$1: _$react.ForwardRefExoticComponent<Omit<_$_radix_ui_react_slot0.SlotProps & _$react.RefAttributes<HTMLElement>, "ref"> & _$react.RefAttributes<HTMLElement>>;
20
20
  //#endregion
21
21
  export { Slot$1 as t };
22
- //# sourceMappingURL=index-j46YISoN.d.ts.map
22
+ //# sourceMappingURL=index-BhlxYL_y.d.ts.map
@@ -1,5 +1,5 @@
1
- import { t as WithAsChild } from "./as-child-C2PttRwz.js";
2
- import { t as VariantProps } from "./variant-props-B4io4uA_.js";
1
+ import { t as WithAsChild } from "./as-child-CpZKMqTE.js";
2
+ import { t as VariantProps } from "./variant-props-BZbM__kQ.js";
3
3
  import * as _$react from "react";
4
4
  import { ComponentProps } from "react";
5
5
  import * as _$class_variance_authority_types0 from "class-variance-authority/types";
@@ -27,4 +27,4 @@ type ButtonGroupProps = ComponentProps<"div"> & ButtonGroupVariants & WithAsChil
27
27
  declare const ButtonGroup: _$react.ForwardRefExoticComponent<Omit<ButtonGroupProps, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
28
28
  //#endregion
29
29
  export { ButtonGroupProps as n, ButtonGroup as t };
30
- //# sourceMappingURL=index-DIBURJqf.d.ts.map
30
+ //# sourceMappingURL=index-CWXKBva-.d.ts.map
@@ -37,4 +37,4 @@ type Color = (typeof colors)[number];
37
37
  declare const isColor: (value: unknown) => value is Color;
38
38
  //#endregion
39
39
  export { functionalColors as a, isNamedColor as c, colors as i, namedColors as l, FunctionalColor as n, isColor as o, NamedColor as r, isFunctionalColor as s, Color as t };
40
- //# sourceMappingURL=index-CVk4t5hk.d.ts.map
40
+ //# sourceMappingURL=index-DS_4n2eb.d.ts.map
package/dist/input.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { o as WithValidation, r as Validation } from "./validation-DF1z7YDr.js";
1
+ import { o as WithValidation, r as Validation } from "./validation-CBSOmooP.js";
2
2
  import * as _$react from "react";
3
3
  import { InputHTMLAttributes, PropsWithChildren } from "react";
4
4
 
@@ -69,7 +69,7 @@ type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "
69
69
  * />
70
70
  * ```
71
71
  */
72
- declare const Input: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithAutoComplete & WithInputType & WithValidation & {
72
+ declare const Input: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "autoComplete"> & WithAutoComplete & WithInputType & WithValidation & {
73
73
  children?: _$react.ReactNode | undefined;
74
74
  } & _$react.RefAttributes<HTMLInputElement>>;
75
75
  type InputCaptureProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & BaseProps;
@@ -87,7 +87,7 @@ type InputCaptureProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComple
87
87
  * </Input>
88
88
  * ```
89
89
  */
90
- declare const InputCapture: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithAutoComplete & WithInputType & WithValidation & _$react.RefAttributes<HTMLInputElement>>;
90
+ declare const InputCapture: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "autoComplete"> & WithAutoComplete & WithInputType & WithValidation & _$react.RefAttributes<HTMLInputElement>>;
91
91
  //#endregion
92
92
  //#region src/components/input/password-input.d.ts
93
93
  type PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithValidation & WithAutoComplete & {
@@ -159,7 +159,7 @@ type PasswordInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "autoCompl
159
159
  * }
160
160
  * ```
161
161
  */
162
- declare const PasswordInput: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "autoComplete" | "type"> & WithValidation & WithAutoComplete & {
162
+ declare const PasswordInput: _$react.ForwardRefExoticComponent<Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "autoComplete"> & WithValidation & WithAutoComplete & {
163
163
  /**
164
164
  * Callback for when the visibility of the password value changes.
165
165
  */
package/dist/input.js CHANGED
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./icon-bWc5yC3-.js";import{t as n}from"./compose-refs-DZ3cPi47.js";import{a as r,r as i}from"./validation-BYME8rWN.js";import{t as a}from"./use-prefers-reduced-motion-YUurmkwx.js";import{t as o}from"./is-input-CEEoHxXN.js";import{createContext as s,forwardRef as c,useContext as l,useEffect as u,useRef as d,useState as f}from"react";import p from"clsx";import{jsx as m,jsxs as h}from"react/jsx-runtime";import{CheckCircleIcon as g}from"@phosphor-icons/react/CheckCircle";import{WarningIcon as _}from"@phosphor-icons/react/Warning";import{WarningDiamondIcon as v}from"@phosphor-icons/react/WarningDiamond";import{EyeIcon as y}from"@phosphor-icons/react/Eye";import{EyeClosedIcon as b}from"@phosphor-icons/react/EyeClosed";import{flushSync as x}from"react-dom";const S=c(({children:e,className:t,...n},r)=>{let i=!!e,a=d(null);return i?m(T,{className:t,forwardedRef:r,innerRef:a,...n,children:e}):m(T,{...n,className:t,forwardedRef:r,innerRef:a,children:m(C,{...n})})});S.displayName=`Input`;const C=c(({"aria-invalid":t,className:a,validation:o,...s},c)=>{let{"aria-invalid":u,forwardedRef:d,innerRef:f,validation:p,...h}=l(w),g=r(),{ariaInvalid:_,validation:v}=i({"aria-invalid":u??t,validation:p??o??g}),y={...h,...s,type:s.type??h.type??`text`};return m(`input`,{"aria-invalid":_,"data-slot":`input-capture`,"data-validation":v,className:e(`placeholder:text-placeholder min-w-0 flex-1 bg-transparent text-left autofill:shadow-[inset_0_0_0px_1000px_var(--color-blue-50)] focus:outline-hidden`,a),ref:n(c,d,f),...y})});C.displayName=`InputCapture`;const w=s({validation:void 0,innerRef:{current:null}}),T=({"aria-invalid":t,"aria-disabled":n,"data-slot":a=`input`,children:o,className:s,disabled:c,forwardedRef:l,innerRef:u,style:d,type:f,validation:p,...g})=>{let _=r(),{validation:v}=i({"aria-invalid":t,validation:p??_});return m(w.Provider,{value:{"aria-invalid":t,"aria-disabled":n,disabled:c,type:f,validation:p,...g,forwardedRef:l,innerRef:u},children:h(`div`,{role:`none`,"data-slot":a,"data-disabled":(c??n)||void 0,"data-validation":v||void 0,className:e(`pointer-coarse:text-base h-9 text-sm`,`bg-form relative flex w-full items-center gap-1.5 rounded-md border px-3 py-2 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-within:outline-hidden focus-within:ring-4`,`data-disabled:opacity-50`,`has-[input:not(:first-child)]:ps-2.5 has-[input:not(:last-child)]:pe-2.5 [&>:not(input)]:shrink-0 [&_svg]:size-5`,`border-form text-strong focus-within:border-accent-600 focus-within:ring-focus-accent`,`data-validation-success:border-success-600 focus-within:data-validation-success:border-success-600 focus-within:data-validation-success:ring-focus-success`,`data-validation-warning:border-warning-600 focus-within:data-validation-warning:border-warning-600 focus-within:data-validation-warning:ring-focus-warning`,`data-validation-error:border-danger-600 focus-within:data-validation-error:border-danger-600 focus-within:data-validation-error:ring-focus-danger`,`autofill:shadow-[inset_0_0_0px_1000px_var(--color-blue-50)] has-autofill:bg-blue-50 has-autofill:[-webkit-text-fill-color:var(--text-color-strong)]`,s),onMouseDown:e=>{e.target!==u?.current&&e.preventDefault()},onClick:()=>{u?.current?.focus()},onKeyDown:()=>{u?.current!==document.activeElement&&u?.current?.focus()},style:d,children:[o,m(E,{name:g.name,validation:v})]})})};T.displayName=`InputContainer`;const E=({name:e,validation:n})=>{switch(n){case`error`:return h(`div`,{className:`text-danger-600 order-last select-none`,children:[m(`span`,{className:`sr-only`,children:p(`The value entered for the`,e,`input has failed validation.`)}),m(t,{svg:m(_,{"aria-hidden":!0,weight:`fill`})})]});case`success`:return m(`div`,{className:`text-success-600 order-last select-none`,children:m(t,{svg:m(g,{weight:`fill`})})});case`warning`:return m(`div`,{className:`text-warning-600 order-last select-none`,children:m(t,{svg:m(v,{weight:`fill`})})});default:return null}};E.displayName=`ValidationFeedback`;const D=c(({onValueVisibilityChange:e,showValue:n=!1,...r},i)=>{let[o,s]=f(n),c=o?`text`:`password`,l=o?y:b,p=d(null),g=d(null);return u(()=>{s(n)},[n]),h(S,{"data-slot":`password-input`,type:c,ref:i,...r,children:[m(C,{}),h(`button`,{type:`button`,tabIndex:-1,className:`text-body hover:text-strong ml-1 cursor-pointer bg-inherit p-0`,onClick:()=>{g.current&&=(g.current.cancel(),null);let t=!o;x(()=>{s(t)}),e?.(t);let n=p.current;n&&!a()&&(g.current=n.animate([{transform:`scaleY(0)`},{transform:`scaleY(1)`}],{duration:200,easing:`ease-out`}),g.current.onfinish=()=>{g.current=null})},children:[h(`span`,{className:`sr-only`,children:[`Turn password visibility `,o?`off`:`on`]}),m(t,{ref:p,svg:m(l,{"aria-hidden":!0})})]})]})});D.displayName=`PasswordInput`;export{S as Input,C as InputCapture,D as PasswordInput,o as isInput};
1
+ import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./icon-bWc5yC3-.js";import{t as n}from"./compose-refs-DZ3cPi47.js";import{a as r,r as i}from"./validation-BYME8rWN.js";import{t as a}from"./use-prefers-reduced-motion-Bpx8G3UT.js";import{t as o}from"./is-input-CtUHJGgL.js";import{createContext as s,forwardRef as c,useContext as l,useEffect as u,useRef as d,useState as f}from"react";import p from"clsx";import{jsx as m,jsxs as h}from"react/jsx-runtime";import{CheckCircleIcon as g}from"@phosphor-icons/react/CheckCircle";import{WarningIcon as _}from"@phosphor-icons/react/Warning";import{WarningDiamondIcon as v}from"@phosphor-icons/react/WarningDiamond";import{EyeIcon as y}from"@phosphor-icons/react/Eye";import{EyeClosedIcon as b}from"@phosphor-icons/react/EyeClosed";import{flushSync as x}from"react-dom";const S=c(({children:e,className:t,...n},r)=>{let i=!!e,a=d(null);return i?m(T,{className:t,forwardedRef:r,innerRef:a,...n,children:e}):m(T,{...n,className:t,forwardedRef:r,innerRef:a,children:m(C,{...n})})});S.displayName=`Input`;const C=c(({"aria-invalid":t,className:a,validation:o,...s},c)=>{let{"aria-invalid":u,forwardedRef:d,innerRef:f,validation:p,...h}=l(w),g=r(),{ariaInvalid:_,validation:v}=i({"aria-invalid":u??t,validation:p??o??g}),y={...h,...s,type:s.type??h.type??`text`};return m(`input`,{"aria-invalid":_,"data-slot":`input-capture`,"data-validation":v,className:e(`placeholder:text-placeholder min-w-0 flex-1 bg-transparent text-left autofill:shadow-[inset_0_0_0px_1000px_var(--color-blue-50)] focus:outline-hidden`,a),ref:n(c,d,f),...y})});C.displayName=`InputCapture`;const w=s({validation:void 0,innerRef:{current:null}}),T=({"aria-invalid":t,"aria-disabled":n,"data-slot":a=`input`,children:o,className:s,disabled:c,forwardedRef:l,innerRef:u,style:d,type:f,validation:p,...g})=>{let _=r(),{validation:v}=i({"aria-invalid":t,validation:p??_});return m(w.Provider,{value:{"aria-invalid":t,"aria-disabled":n,disabled:c,type:f,validation:p,...g,forwardedRef:l,innerRef:u},children:h(`div`,{role:`none`,"data-slot":a,"data-disabled":(c??n)||void 0,"data-validation":v||void 0,className:e(`pointer-coarse:text-base h-9 text-sm`,`bg-form relative flex w-full items-center gap-1.5 rounded-md border px-3 py-2 file:border-0 file:bg-transparent file:text-sm file:font-medium focus-within:outline-hidden focus-within:ring-4`,`data-disabled:opacity-50`,`has-[input:not(:first-child)]:ps-2.5 has-[input:not(:last-child)]:pe-2.5 [&>:not(input)]:shrink-0 [&_svg]:size-5`,`border-form text-strong focus-within:border-accent-600 focus-within:ring-focus-accent`,`data-validation-success:border-success-600 focus-within:data-validation-success:border-success-600 focus-within:data-validation-success:ring-focus-success`,`data-validation-warning:border-warning-600 focus-within:data-validation-warning:border-warning-600 focus-within:data-validation-warning:ring-focus-warning`,`data-validation-error:border-danger-600 focus-within:data-validation-error:border-danger-600 focus-within:data-validation-error:ring-focus-danger`,`autofill:shadow-[inset_0_0_0px_1000px_var(--color-blue-50)] has-autofill:bg-blue-50 has-autofill:[-webkit-text-fill-color:var(--text-color-strong)]`,s),onMouseDown:e=>{e.target!==u?.current&&e.preventDefault()},onClick:()=>{u?.current?.focus()},onKeyDown:()=>{u?.current!==document.activeElement&&u?.current?.focus()},style:d,children:[o,m(E,{name:g.name,validation:v})]})})};T.displayName=`InputContainer`;const E=({name:e,validation:n})=>{switch(n){case`error`:return h(`div`,{className:`text-danger-600 order-last select-none`,children:[m(`span`,{className:`sr-only`,children:p(`The value entered for the`,e,`input has failed validation.`)}),m(t,{svg:m(_,{"aria-hidden":!0,weight:`fill`})})]});case`success`:return m(`div`,{className:`text-success-600 order-last select-none`,children:m(t,{svg:m(g,{weight:`fill`})})});case`warning`:return m(`div`,{className:`text-warning-600 order-last select-none`,children:m(t,{svg:m(v,{weight:`fill`})})});default:return null}};E.displayName=`ValidationFeedback`;const D=c(({onValueVisibilityChange:e,showValue:n=!1,...r},i)=>{let[o,s]=f(n),c=o?`text`:`password`,l=o?y:b,p=d(null),g=d(null);return u(()=>{s(n)},[n]),h(S,{"data-slot":`password-input`,type:c,ref:i,...r,children:[m(C,{}),h(`button`,{type:`button`,tabIndex:-1,className:`text-body hover:text-strong ml-1 cursor-pointer bg-inherit p-0`,onClick:()=>{g.current&&=(g.current.cancel(),null);let t=!o;x(()=>{s(t)}),e?.(t);let n=p.current;n&&!a()&&(g.current=n.animate([{transform:`scaleY(0)`},{transform:`scaleY(1)`}],{duration:200,easing:`ease-out`}),g.current.onfinish=()=>{g.current=null})},children:[h(`span`,{className:`sr-only`,children:[`Turn password visibility `,o?`off`:`on`]}),m(t,{ref:p,svg:m(l,{"aria-hidden":!0})})]})]})});D.displayName=`PasswordInput`;export{S as Input,C as InputCapture,D as PasswordInput,o as isInput};
2
2
  //# sourceMappingURL=input.js.map
@@ -1,2 +1,2 @@
1
1
  function e(e){return e!=null&&e instanceof HTMLInputElement}export{e as t};
2
- //# sourceMappingURL=is-input-CEEoHxXN.js.map
2
+ //# sourceMappingURL=is-input-CtUHJGgL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-input-CEEoHxXN.js","names":[],"sources":["../src/components/input/is-input.ts"],"sourcesContent":["/**\n * Type guard for an HTMLInputElement.\n *\n * @example\n * ```tsx\n * function handleElement(element: HTMLElement) {\n * if (isInput(element)) {\n * // TypeScript now knows element is HTMLInputElement\n * element.value = \"new value\";\n * element.focus();\n * }\n * }\n * ```\n */\nexport function isInput(value: unknown): value is HTMLInputElement {\n\treturn value != null && value instanceof HTMLInputElement;\n}\n"],"mappings":"AAcA,SAAgB,EAAQ,EAA2C,CAClE,OAAO,GAAS,MAAQ,aAAiB"}
1
+ {"version":3,"file":"is-input-CtUHJGgL.js","names":[],"sources":["../src/components/input/is-input.ts"],"sourcesContent":["/**\n * Type guard for an HTMLInputElement.\n *\n * @example\n * ```tsx\n * function handleElement(element: HTMLElement) {\n * if (isInput(element)) {\n * // TypeScript now knows element is HTMLInputElement\n * element.value = \"new value\";\n * element.focus();\n * }\n * }\n * ```\n */\nexport function isInput(value: unknown): value is HTMLInputElement {\n\treturn value != null && value instanceof HTMLInputElement;\n}\n"],"mappings":"AAcA,SAAgB,EAAQ,EAA2C,CAClE,OAAO,GAAS,MAAQ,aAAiB"}
package/dist/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # @ngrok/mantle (0.73.1)
1
+ # @ngrok/mantle (0.73.2)
2
2
 
3
3
  > Offline discovery hint shipped inside the @ngrok/mantle npm package. Authoritative metadata lives at https://mantle.ngrok.com/for-ai-agents.
4
4