@ngrok/mantle 0.71.0 → 0.71.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,6 +38,10 @@ Also install the required `devDependencies`:
38
38
 
39
39
  Next, check out the [Overview & Setup](https://mantle.ngrok.com/) docs and start using mantle components in your application!
40
40
 
41
+ ## Using with AI Agents
42
+
43
+ Mantle ships machine-readable entry points for coding agents — see [For AI Agents](https://mantle.ngrok.com/for-ai-agents) for the system-prompt snippet, conventions, and the full list of `/api/*.json` and `llms.txt` endpoints. An offline pointer file (`@ngrok/mantle/agent.json`) is included in the published package as a fallback when network access isn't available.
44
+
41
45
  ## Code Block Tooling
42
46
 
43
47
  Mantle ships runtime components from `@ngrok/mantle`, while build-time and server-side tooling lives in `@ngrok/mantle-vite-plugins`:
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@ngrok/mantle",
3
+ "version": "0.71.1",
4
+ "origin": "https://mantle.ngrok.com",
5
+ "endpoints": {
6
+ "docs": "https://mantle.ngrok.com/",
7
+ "forAiAgents": "https://mantle.ngrok.com/for-ai-agents",
8
+ "llmsTxt": "https://mantle.ngrok.com/llms.txt",
9
+ "llmsFullTxt": "https://mantle.ngrok.com/llms-full.txt",
10
+ "components": "https://mantle.ngrok.com/api/components.json",
11
+ "hooks": "https://mantle.ngrok.com/api/hooks.json",
12
+ "utilities": "https://mantle.ngrok.com/api/utils.json",
13
+ "package": "https://mantle.ngrok.com/api/package.json",
14
+ "changelog": "https://mantle.ngrok.com/api/changelog.json",
15
+ "searchIndex": "https://mantle.ngrok.com/api/search-index.json",
16
+ "schema": "https://mantle.ngrok.com/api/schema.json"
17
+ },
18
+ "subpaths": [
19
+ "@ngrok/mantle/accordion",
20
+ "@ngrok/mantle/alert",
21
+ "@ngrok/mantle/alert-dialog",
22
+ "@ngrok/mantle/anchor",
23
+ "@ngrok/mantle/badge",
24
+ "@ngrok/mantle/browser-only",
25
+ "@ngrok/mantle/button",
26
+ "@ngrok/mantle/calendar",
27
+ "@ngrok/mantle/card",
28
+ "@ngrok/mantle/checkbox",
29
+ "@ngrok/mantle/code",
30
+ "@ngrok/mantle/code-block",
31
+ "@ngrok/mantle/color",
32
+ "@ngrok/mantle/combobox",
33
+ "@ngrok/mantle/command",
34
+ "@ngrok/mantle/cx",
35
+ "@ngrok/mantle/data-table",
36
+ "@ngrok/mantle/description-list",
37
+ "@ngrok/mantle/dialog",
38
+ "@ngrok/mantle/dropdown-menu",
39
+ "@ngrok/mantle/empty",
40
+ "@ngrok/mantle/flag",
41
+ "@ngrok/mantle/highlight-utils",
42
+ "@ngrok/mantle/hooks",
43
+ "@ngrok/mantle/hover-card",
44
+ "@ngrok/mantle/icon",
45
+ "@ngrok/mantle/icons",
46
+ "@ngrok/mantle/input",
47
+ "@ngrok/mantle/kbd",
48
+ "@ngrok/mantle/label",
49
+ "@ngrok/mantle/main",
50
+ "@ngrok/mantle/media-object",
51
+ "@ngrok/mantle/multi-select",
52
+ "@ngrok/mantle/otp-input",
53
+ "@ngrok/mantle/pagination",
54
+ "@ngrok/mantle/popover",
55
+ "@ngrok/mantle/progress",
56
+ "@ngrok/mantle/radio-group",
57
+ "@ngrok/mantle/sandboxed-on-click",
58
+ "@ngrok/mantle/select",
59
+ "@ngrok/mantle/separator",
60
+ "@ngrok/mantle/sheet",
61
+ "@ngrok/mantle/skeleton",
62
+ "@ngrok/mantle/skip-to-main-link",
63
+ "@ngrok/mantle/slider",
64
+ "@ngrok/mantle/slot",
65
+ "@ngrok/mantle/split-button",
66
+ "@ngrok/mantle/switch",
67
+ "@ngrok/mantle/table",
68
+ "@ngrok/mantle/tabs",
69
+ "@ngrok/mantle/text-area",
70
+ "@ngrok/mantle/theme",
71
+ "@ngrok/mantle/toast",
72
+ "@ngrok/mantle/tooltip",
73
+ "@ngrok/mantle/types",
74
+ "@ngrok/mantle/utils"
75
+ ]
76
+ }
package/dist/command.d.ts CHANGED
@@ -138,7 +138,7 @@ declare const Command: {
138
138
  ref?: React.Ref<HTMLDivElement>;
139
139
  } & {
140
140
  asChild?: boolean;
141
- }, "key" | keyof _$react.HTMLAttributes<HTMLDivElement> | "asChild"> & {
141
+ }, "asChild" | "key" | keyof _$react.HTMLAttributes<HTMLDivElement>> & {
142
142
  label?: string;
143
143
  shouldFilter?: boolean;
144
144
  filter?: (value: string, search: string, keywords?: string[]) => number;
@@ -330,7 +330,7 @@ declare const Command: {
330
330
  ref?: React.Ref<HTMLInputElement>;
331
331
  } & {
332
332
  asChild?: boolean;
333
- }, "key" | keyof _$react.InputHTMLAttributes<HTMLInputElement> | "asChild">, "value" | "onChange" | "type"> & {
333
+ }, "asChild" | "key" | keyof _$react.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "type" | "value"> & {
334
334
  value?: string;
335
335
  onValueChange?: (search: string) => void;
336
336
  } & _$react.RefAttributes<HTMLInputElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
@@ -372,7 +372,7 @@ declare const Command: {
372
372
  ref?: React.Ref<HTMLDivElement>;
373
373
  } & {
374
374
  asChild?: boolean;
375
- }, "key" | keyof _$react.HTMLAttributes<HTMLDivElement> | "asChild"> & {
375
+ }, "asChild" | "key" | keyof _$react.HTMLAttributes<HTMLDivElement>> & {
376
376
  label?: string;
377
377
  } & _$react.RefAttributes<HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
378
378
  /**
@@ -413,7 +413,7 @@ declare const Command: {
413
413
  ref?: React.Ref<HTMLDivElement>;
414
414
  } & {
415
415
  asChild?: boolean;
416
- }, "key" | keyof _$react.HTMLAttributes<HTMLDivElement> | "asChild"> & _$react.RefAttributes<HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
416
+ }, "asChild" | "key" | keyof _$react.HTMLAttributes<HTMLDivElement>> & _$react.RefAttributes<HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
417
417
  /**
418
418
  * The group component for the Command component.
419
419
  *
@@ -452,7 +452,7 @@ declare const Command: {
452
452
  ref?: React.Ref<HTMLDivElement>;
453
453
  } & {
454
454
  asChild?: boolean;
455
- }, "key" | keyof _$react.HTMLAttributes<HTMLDivElement> | "asChild">, "value" | "heading"> & {
455
+ }, "asChild" | "key" | keyof _$react.HTMLAttributes<HTMLDivElement>>, "heading" | "value"> & {
456
456
  heading?: React.ReactNode;
457
457
  value?: string;
458
458
  forceMount?: boolean;
@@ -495,7 +495,7 @@ declare const Command: {
495
495
  ref?: React.Ref<HTMLDivElement>;
496
496
  } & {
497
497
  asChild?: boolean;
498
- }, "key" | keyof _$react.HTMLAttributes<HTMLDivElement> | "asChild">, "disabled" | "value" | "onSelect"> & {
498
+ }, "asChild" | "key" | keyof _$react.HTMLAttributes<HTMLDivElement>>, "disabled" | "onSelect" | "value"> & {
499
499
  disabled?: boolean;
500
500
  onSelect?: (value: string) => void;
501
501
  value?: string;
@@ -571,7 +571,7 @@ declare const Command: {
571
571
  ref?: React.Ref<HTMLDivElement>;
572
572
  } & {
573
573
  asChild?: boolean;
574
- }, "key" | keyof _$react.HTMLAttributes<HTMLDivElement> | "asChild"> & {
574
+ }, "asChild" | "key" | keyof _$react.HTMLAttributes<HTMLDivElement>> & {
575
575
  alwaysRender?: boolean;
576
576
  } & _$react.RefAttributes<HTMLDivElement>, "ref"> & _$react.RefAttributes<HTMLDivElement>>;
577
577
  };
package/dist/hooks.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { n as MarginType, o as useComposedRefs, s as copyToClipboard } from "./in-view-Da08Bx6l.js";
2
- import { RefObject, useLayoutEffect } from "react";
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/llms.txt ADDED
@@ -0,0 +1,77 @@
1
+ # @ngrok/mantle (0.71.1)
2
+
3
+ > Offline discovery hint shipped inside the @ngrok/mantle npm package. Authoritative metadata lives at https://mantle.ngrok.com/for-ai-agents.
4
+
5
+ Docs: https://mantle.ngrok.com/
6
+ Agent guide: https://mantle.ngrok.com/for-ai-agents
7
+ Index: https://mantle.ngrok.com/llms.txt
8
+ Full text: https://mantle.ngrok.com/llms-full.txt
9
+
10
+ ## Endpoints
11
+
12
+ - Components: https://mantle.ngrok.com/api/components.json
13
+ - Hooks: https://mantle.ngrok.com/api/hooks.json
14
+ - Utilities: https://mantle.ngrok.com/api/utils.json
15
+ - Package info: https://mantle.ngrok.com/api/package.json
16
+ - Changelog: https://mantle.ngrok.com/api/changelog.json
17
+ - Search index: https://mantle.ngrok.com/api/search-index.json
18
+ - Schemas: https://mantle.ngrok.com/api/schema.json
19
+
20
+ ## Importable subpaths
21
+
22
+ - `@ngrok/mantle/accordion`
23
+ - `@ngrok/mantle/alert`
24
+ - `@ngrok/mantle/alert-dialog`
25
+ - `@ngrok/mantle/anchor`
26
+ - `@ngrok/mantle/badge`
27
+ - `@ngrok/mantle/browser-only`
28
+ - `@ngrok/mantle/button`
29
+ - `@ngrok/mantle/calendar`
30
+ - `@ngrok/mantle/card`
31
+ - `@ngrok/mantle/checkbox`
32
+ - `@ngrok/mantle/code`
33
+ - `@ngrok/mantle/code-block`
34
+ - `@ngrok/mantle/color`
35
+ - `@ngrok/mantle/combobox`
36
+ - `@ngrok/mantle/command`
37
+ - `@ngrok/mantle/cx`
38
+ - `@ngrok/mantle/data-table`
39
+ - `@ngrok/mantle/description-list`
40
+ - `@ngrok/mantle/dialog`
41
+ - `@ngrok/mantle/dropdown-menu`
42
+ - `@ngrok/mantle/empty`
43
+ - `@ngrok/mantle/flag`
44
+ - `@ngrok/mantle/highlight-utils`
45
+ - `@ngrok/mantle/hooks`
46
+ - `@ngrok/mantle/hover-card`
47
+ - `@ngrok/mantle/icon`
48
+ - `@ngrok/mantle/icons`
49
+ - `@ngrok/mantle/input`
50
+ - `@ngrok/mantle/kbd`
51
+ - `@ngrok/mantle/label`
52
+ - `@ngrok/mantle/main`
53
+ - `@ngrok/mantle/media-object`
54
+ - `@ngrok/mantle/multi-select`
55
+ - `@ngrok/mantle/otp-input`
56
+ - `@ngrok/mantle/pagination`
57
+ - `@ngrok/mantle/popover`
58
+ - `@ngrok/mantle/progress`
59
+ - `@ngrok/mantle/radio-group`
60
+ - `@ngrok/mantle/sandboxed-on-click`
61
+ - `@ngrok/mantle/select`
62
+ - `@ngrok/mantle/separator`
63
+ - `@ngrok/mantle/sheet`
64
+ - `@ngrok/mantle/skeleton`
65
+ - `@ngrok/mantle/skip-to-main-link`
66
+ - `@ngrok/mantle/slider`
67
+ - `@ngrok/mantle/slot`
68
+ - `@ngrok/mantle/split-button`
69
+ - `@ngrok/mantle/switch`
70
+ - `@ngrok/mantle/table`
71
+ - `@ngrok/mantle/tabs`
72
+ - `@ngrok/mantle/text-area`
73
+ - `@ngrok/mantle/theme`
74
+ - `@ngrok/mantle/toast`
75
+ - `@ngrok/mantle/tooltip`
76
+ - `@ngrok/mantle/types`
77
+ - `@ngrok/mantle/utils`
package/dist/otp-input.js CHANGED
@@ -1,2 +1,2 @@
1
- import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./slot-D_ZUrdEW.js";import{forwardRef as n,useContext as r}from"react";import{jsx as i,jsxs as a}from"react/jsx-runtime";import{MinusIcon as o}from"@phosphor-icons/react/Minus";import{OTPInput as s,OTPInputContext as c,REGEXP_ONLY_CHARS as l,REGEXP_ONLY_DIGITS as u,REGEXP_ONLY_DIGITS_AND_CHARS as d}from"input-otp";const f=({totalActive:e,total:t})=>e===0?`idle`:e===1?`caret`:e===t?`all`:`range`,p=({children:e})=>{let t=r(c),n=t.slots.length;return i(`div`,{className:`group/otp contents`,"data-otp-state":f({totalActive:t.slots.reduce((e,t)=>e+ +!!t.isActive,0),total:n}),children:e})},m=n(({children:t,className:n,containerClassName:r,...a},o)=>i(s,{ref:o,"data-slot":`otp-input`,containerClassName:e(`flex items-center gap-2 has-disabled:opacity-50`,r),className:e(`disabled:cursor-not-allowed`,n),...a,children:i(p,{children:t})}));m.displayName=`OtpInput`;const h=n(({asChild:n,children:r,className:a,...o},s)=>i(n?t:`div`,{ref:s,"data-slot":`otp-input-group`,className:e(`relative flex items-center rounded-md`,`has-[[data-active]~[data-active]]:ring-focus-accent has-[[data-active]~[data-active]]:ring-4`,a),...o,children:r}));h.displayName=`OtpInputGroup`;const g=n(({className:t,index:n,...o},s)=>{let l=r(c).slots[n],u=l?.char??null,d=l?.hasFakeCaret??!1;return a(`div`,{ref:s,"data-slot":`otp-input-slot`,"data-active":l?.isActive??!1?``:void 0,className:e(`border-form bg-form text-strong relative flex h-10 w-10 items-center justify-center border-y border-r text-sm shadow-sm outline-hidden transition-all duration-300 ease-out`,`first:rounded-l-md first:border-l last:rounded-r-md`,`[&:has(+[data-active])]:group-data-[otp-state=caret]/otp:border-r-transparent`,`data-active:group-data-[otp-state=caret]/otp:border-accent-600`,`data-active:group-data-[otp-state=caret]/otp:border-l`,`data-active:group-data-[otp-state=caret]/otp:ring-focus-accent`,`data-active:group-data-[otp-state=caret]/otp:z-20`,`data-active:group-data-[otp-state=caret]/otp:ring-4`,`group-data-[otp-state=all]/otp:border-accent-600`,t),...o,children:[u,d&&i(`div`,{className:`pointer-events-none absolute inset-0 flex items-center justify-center`,children:i(`div`,{className:`bg-strong h-4 w-px animate-pulse`})})]})});g.displayName=`OtpInputSlot`;const _=n(({asChild:n,children:r,className:a,semantic:s=!1,...c},l)=>{let u=n?t:`div`,d=s?{role:`separator`}:{"aria-hidden":!0,role:`none`};return i(u,{ref:l,"data-slot":`otp-input-separator`,className:e(`text-muted flex items-center`,a),...d,...c,children:r??i(o,{weight:`bold`})})});_.displayName=`OtpInputSeparator`;const v={Root:m,Group:h,Slot:g,Separator:_};export{v as OtpInput,l as REGEXP_ONLY_CHARS,u as REGEXP_ONLY_DIGITS,d as REGEXP_ONLY_DIGITS_AND_CHARS};
1
+ import{t as e}from"./cx-D1HYnpvA.js";import{t}from"./slot-D_ZUrdEW.js";import{forwardRef as n,useContext as r}from"react";import{jsx as i,jsxs as a}from"react/jsx-runtime";import{MinusIcon as o}from"@phosphor-icons/react/Minus";import{OTPInput as s,OTPInputContext as c,REGEXP_ONLY_CHARS as l,REGEXP_ONLY_DIGITS as u,REGEXP_ONLY_DIGITS_AND_CHARS as d}from"input-otp";const f=({totalActive:e,total:t})=>e===0?`idle`:e===1?`caret`:e===t?`all`:`range`,p=({children:e})=>{let t=r(c),n=t.slots.length;return i(`div`,{className:`group/otp contents`,"data-otp-state":f({totalActive:t.slots.reduce((e,t)=>e+ +!!t.isActive,0),total:n}),children:e})},m=n(({children:t,className:n,containerClassName:r,...a},o)=>i(s,{ref:o,"data-slot":`otp-input`,containerClassName:e(`flex items-center gap-2 has-disabled:opacity-50`,r),className:e(`disabled:cursor-not-allowed`,n),...a,children:i(p,{children:t})}));m.displayName=`OtpInput`;const h=n(({asChild:n,children:r,className:a,...o},s)=>i(n?t:`div`,{ref:s,"data-slot":`otp-input-group`,className:e(`relative flex items-center rounded-md`,`has-[[data-active]~[data-active]]:ring-focus-accent has-[[data-active]~[data-active]]:ring-4`,a),...o,children:r}));h.displayName=`OtpInputGroup`;const g=n(({className:t,index:n,...o},s)=>{let l=r(c).slots[n],u=l?.char??null,d=l?.hasFakeCaret??!1;return a(`div`,{ref:s,"data-slot":`otp-input-slot`,"data-active":l?.isActive??!1?``:void 0,className:e(`border-form bg-form text-strong relative flex h-10 w-10 items-center justify-center border-y border-r text-sm shadow-sm outline-hidden transition-all duration-150 ease-out`,`first:rounded-l-md first:border-l last:rounded-r-md`,`[&:has(+[data-active])]:group-data-[otp-state=caret]/otp:border-r-transparent`,`data-active:group-data-[otp-state=caret]/otp:border-accent-600`,`data-active:group-data-[otp-state=caret]/otp:border-l`,`data-active:group-data-[otp-state=caret]/otp:ring-focus-accent`,`data-active:group-data-[otp-state=caret]/otp:z-20`,`data-active:group-data-[otp-state=caret]/otp:ring-4`,`group-data-[otp-state=all]/otp:border-accent-600`,t),...o,children:[u,d&&i(`div`,{className:`pointer-events-none absolute inset-0 flex items-center justify-center`,children:i(`div`,{className:`bg-strong h-4 w-px animate-pulse`})})]})});g.displayName=`OtpInputSlot`;const _=n(({asChild:n,children:r,className:a,semantic:s=!1,...c},l)=>{let u=n?t:`div`,d=s?{role:`separator`}:{"aria-hidden":!0,role:`none`};return i(u,{ref:l,"data-slot":`otp-input-separator`,className:e(`text-muted flex items-center`,a),...d,...c,children:r??i(o,{weight:`bold`})})});_.displayName=`OtpInputSeparator`;const v={Root:m,Group:h,Slot:g,Separator:_};export{v as OtpInput,l as REGEXP_ONLY_CHARS,u as REGEXP_ONLY_DIGITS,d as REGEXP_ONLY_DIGITS_AND_CHARS};
2
2
  //# sourceMappingURL=otp-input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"otp-input.js","names":["AsChildSlot"],"sources":["../src/components/otp-input/otp-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { MinusIcon } from \"@phosphor-icons/react/Minus\";\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport type { ComponentProps, ComponentRef, ReactNode } from \"react\";\nimport { forwardRef, useContext } from \"react\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Slot as AsChildSlot } from \"../slot/index.js\";\n\ntype OtpState = \"idle\" | \"caret\" | \"range\" | \"all\";\n\n/**\n * Map the count of active slots to a discrete `data-otp-state` value used by\n * descendant CSS selectors. Split out from the rendering component so the\n * decision tree reads as a flat `if`/`else` chain rather than a nested\n * ternary.\n */\nconst computeOtpState = ({\n\ttotalActive,\n\ttotal,\n}: {\n\ttotalActive: number;\n\ttotal: number;\n}): OtpState => {\n\tif (totalActive === 0) {\n\t\treturn \"idle\";\n\t}\n\tif (totalActive === 1) {\n\t\treturn \"caret\";\n\t}\n\tif (totalActive === total) {\n\t\treturn \"all\";\n\t}\n\treturn \"range\";\n};\n\n/**\n * Bridge component that lives inside `<OTPInput>` (so it can read\n * `OTPInputContext`) and exposes the current selection state as a DOM data\n * attribute. Descendant `OtpInput.Group` / `OtpInput.Slot` parts read this\n * via Tailwind's `group-data-*` selector, so all conditional styling lives\n * in CSS — no React context.\n *\n * `data-otp-state` is one of:\n * - `\"idle\"` — no slot active (input not focused)\n * - `\"caret\"` — exactly one slot active (typing caret)\n * - `\"range\"` — multiple but not all slots active (partial selection)\n * - `\"all\"` — every slot active (cmd+a / select-all)\n */\nconst MantleOtpBridge = ({ children }: { children: ReactNode }) => {\n\tconst inputOtpContext = useContext(OTPInputContext);\n\tconst total = inputOtpContext.slots.length;\n\tconst totalActive = inputOtpContext.slots.reduce(\n\t\t(count, slot) => count + (slot.isActive ? 1 : 0),\n\t\t0,\n\t);\n\tconst otpState = computeOtpState({ totalActive, total });\n\n\t// `display: contents` keeps this element in the DOM tree (so `group/`\n\t// ancestor selectors resolve) without producing a layout box.\n\treturn (\n\t\t<div className=\"group/otp contents\" data-otp-state={otpState}>\n\t\t\t{children}\n\t\t</div>\n\t);\n};\n\n// Drop the `render` / `children?: never` branch of input-otp's discriminated\n// union — `OtpInput.Root` always wraps its children in `MantleOtpBridge`,\n// so consumers compose with `OtpInput.Group` / `OtpInput.Slot` children\n// rather than a render prop.\ntype OtpInputRootProps = Omit<ComponentProps<typeof OTPInput>, \"render\" | \"children\"> & {\n\tchildren?: ReactNode;\n};\n\n/**\n * The root of the OTP input. Renders an accessible single hidden input that\n * captures keystrokes, paste events, and autofill, and exposes per-slot state\n * (active, char, fake caret) to descendant `OtpInput.Slot` parts via context.\n *\n * Wraps the `input-otp` library by Guilherme Rodz.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\n// `OtpInput.Root` does not support `asChild`: the underlying `OTPInput`\n// owns its hidden `<input>` and its render contract — swapping the element\n// would break input-otp's internal focus and selection management.\nconst Root = forwardRef<ComponentRef<typeof OTPInput>, OtpInputRootProps>(\n\t({ children, className, containerClassName, ...props }, ref) => {\n\t\treturn (\n\t\t\t<OTPInput\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input\"\n\t\t\t\tcontainerClassName={cx(\n\t\t\t\t\t\"flex items-center gap-2 has-disabled:opacity-50\",\n\t\t\t\t\tcontainerClassName,\n\t\t\t\t)}\n\t\t\t\tclassName={cx(\"disabled:cursor-not-allowed\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<MantleOtpBridge>{children}</MantleOtpBridge>\n\t\t\t</OTPInput>\n\t\t);\n\t},\n);\nRoot.displayName = \"OtpInput\";\n\ntype OtpInputGroupProps = ComponentProps<\"div\"> & WithAsChild;\n\n/**\n * Groups one or more `OtpInput.Slot` parts into a visually-connected segment.\n * Slots inside a group share rounded corners on the outer edges and join with\n * shared borders between adjacent slots.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\nconst Group = forwardRef<HTMLDivElement, OtpInputGroupProps>(\n\t({ asChild, children, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? AsChildSlot : \"div\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input-group\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"relative flex items-center rounded-md\",\n\t\t\t\t\t// A \"range\" selection within this group means two or more\n\t\t\t\t\t// slots are simultaneously active. CSS `:has()` with the\n\t\t\t\t\t// general sibling combinator catches that without us\n\t\t\t\t\t// having to count: if any active slot is preceded by\n\t\t\t\t\t// another active slot at the same nesting level, the\n\t\t\t\t\t// group has at least 2 actives → draw the ring.\n\t\t\t\t\t\"has-[[data-active]~[data-active]]:ring-focus-accent has-[[data-active]~[data-active]]:ring-4\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nGroup.displayName = \"OtpInputGroup\";\n\ntype OtpInputSlotProps = ComponentProps<\"div\"> & {\n\t/**\n\t * The zero-based index of the character slot to render. Must be a valid\n\t * index within the parent `OtpInput.Root`'s `maxLength`.\n\t */\n\tindex: number;\n};\n\n/**\n * Renders a single character slot for the OTP input. Reads its display state\n * (the typed character, active/focused state, and fake caret position) from\n * the nearest `OtpInput.Root` via context — so this part must always be\n * rendered inside an `OtpInput.Root`.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\n// `OtpInput.Slot` does not support `asChild`: the slot reads context-driven\n// state (char, fake caret, active) from `OTPInputContext` and renders that\n// state into a fixed visual structure. Letting consumers swap the element\n// would lose the caret overlay and the active-ring focus styling.\nconst OtpInputSlotImpl = forwardRef<HTMLDivElement, OtpInputSlotProps>(\n\t({ className, index, ...props }, ref) => {\n\t\tconst context = useContext(OTPInputContext);\n\t\tconst slot = context.slots[index];\n\t\tconst char = slot?.char ?? null;\n\t\tconst hasFakeCaret = slot?.hasFakeCaret ?? false;\n\t\tconst isActive = slot?.isActive ?? false;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input-slot\"\n\t\t\t\tdata-active={isActive ? \"\" : undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"border-form bg-form text-strong relative flex h-10 w-10 items-center justify-center border-y border-r text-sm shadow-sm outline-hidden transition-all duration-300 ease-out\",\n\t\t\t\t\t\"first:rounded-l-md first:border-l last:rounded-r-md\",\n\t\t\t\t\t// When this slot is immediately followed by the caret\n\t\t\t\t\t// slot, hide our `border-r` so the active slot's\n\t\t\t\t\t// `border-l` is the only line at the boundary — without\n\t\t\t\t\t// this, the two adjacent 1px borders read as a doubled\n\t\t\t\t\t// edge. We use an arbitrary `&:has(+ ...)` variant\n\t\t\t\t\t// because Tailwind's `has-[...]` shorthand doesn't\n\t\t\t\t\t// parse the nested bracketed attribute selector here.\n\t\t\t\t\t\"[&:has(+[data-active])]:group-data-[otp-state=caret]/otp:border-r-transparent\",\n\t\t\t\t\t// Per-slot ring renders only in `caret` state (single\n\t\t\t\t\t// active slot). When more than one slot is active, the\n\t\t\t\t\t// surrounding `OtpInput.Group` draws a single ring\n\t\t\t\t\t// around the whole group — see Group's `:has()` rule.\n\t\t\t\t\t// We also recolor the slot's own borders to accent and\n\t\t\t\t\t// fill in `border-l` (groups normally only render\n\t\t\t\t\t// `border-l` on `:first-child`), so the slot reads as\n\t\t\t\t\t// one cohesive highlighted box rather than a ring with\n\t\t\t\t\t// a gray box inside.\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:border-accent-600\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:border-l\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:ring-focus-accent\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:z-20\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:ring-4\",\n\t\t\t\t\t// Select-all: tint *every* border on the slot accent.\n\t\t\t\t\t// Tinting only the outside edges leaves the internal\n\t\t\t\t\t// vertical divider (gray `border-r`) meeting the\n\t\t\t\t\t// accent top/bottom borders at the corner, producing a\n\t\t\t\t\t// visible 1px miter spike. Coloring all borders the\n\t\t\t\t\t// same accent-600 hue makes the corner blend\n\t\t\t\t\t// seamlessly while still keeping the slot grid\n\t\t\t\t\t// readable at full opacity.\n\t\t\t\t\t\"group-data-[otp-state=all]/otp:border-accent-600\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{char}\n\t\t\t\t{hasFakeCaret && (\n\t\t\t\t\t<div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t<div className=\"bg-strong h-4 w-px animate-pulse\" />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nOtpInputSlotImpl.displayName = \"OtpInputSlot\";\n\ntype OtpInputSeparatorProps = ComponentProps<\"div\"> &\n\tWithAsChild & {\n\t\t/**\n\t\t * If `true`, the separator will be rendered with `role=\"separator\"` so\n\t\t * assistive tech announces it as a divider between OTP groups.\n\t\t * If `false`, the separator is purely decorative and is removed from\n\t\t * the accessibility tree — preferred inside an OTP control where the\n\t\t * minus icon is just visual chrome between slot groups.\n\t\t *\n\t\t * @default false\n\t\t */\n\t\tsemantic?: boolean;\n\t};\n\n/**\n * A visual separator between two `OtpInput.Group` segments. Renders a minus\n * icon by default; pass `children` to override the visual.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\nconst Separator = forwardRef<HTMLDivElement, OtpInputSeparatorProps>(\n\t({ asChild, children, className, semantic = false, ...props }, ref) => {\n\t\tconst Comp = asChild ? AsChildSlot : \"div\";\n\t\tconst semanticProps = semantic ? { role: \"separator\" } : { \"aria-hidden\": true, role: \"none\" };\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input-separator\"\n\t\t\t\tclassName={cx(\"text-muted flex items-center\", className)}\n\t\t\t\t{...semanticProps}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children ?? <MinusIcon weight=\"bold\" />}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nSeparator.displayName = \"OtpInputSeparator\";\n\n/**\n * Compound component for capturing one-time passcodes (OTP). Combines a\n * single hidden input (handling paste, autofill, and IME) with a row of\n * styled character slots.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * Composition:\n * ```\n * OtpInput.Root\n * ├── OtpInput.Group\n * │ └── OtpInput.Slot\n * ├── OtpInput.Separator\n * └── OtpInput.Group\n * └── OtpInput.Slot\n * ```\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\nconst OtpInput = {\n\t/**\n\t * The root of the OTP input. Wraps the hidden input that captures\n\t * keystrokes, paste, and autofill, and provides per-slot state to\n\t * descendant `OtpInput.Slot` parts.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * Groups one or more `OtpInput.Slot` parts into a visually-connected\n\t * segment with shared rounded corners and joined borders.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * A single character slot. Must be rendered inside an `OtpInput.Root`.\n\t * Reads its character, active state, and fake caret position from the\n\t * root via context.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tSlot: OtpInputSlotImpl,\n\t/**\n\t * A visual separator between two `OtpInput.Group` segments. Renders a\n\t * minus icon by default; pass `children` to override.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tSeparator,\n} as const;\n\nexport {\n\t//,\n\tOtpInput,\n};\n\nexport {\n\t//,\n\tREGEXP_ONLY_CHARS,\n\tREGEXP_ONLY_DIGITS,\n\tREGEXP_ONLY_DIGITS_AND_CHARS,\n} from \"input-otp\";\n"],"mappings":"+WAkBA,MAAM,GAAmB,CACxB,cACA,WAKI,IAAgB,EACZ,OAEJ,IAAgB,EACZ,QAEJ,IAAgB,EACZ,MAED,QAgBF,GAAmB,CAAE,cAAwC,CAClE,IAAM,EAAkB,EAAW,EAAgB,CAC7C,EAAQ,EAAgB,MAAM,OASpC,OACC,EAAC,MAAD,CAAK,UAAU,qBAAqB,iBALpB,EAAgB,CAAE,YAJf,EAAgB,MAAM,QACxC,EAAO,IAAS,GAAS,KAAK,SAC/B,EAE6C,CAAE,QAAO,CAKM,CAC1D,WACI,CAAA,EAyCF,EAAO,GACX,CAAE,WAAU,YAAW,qBAAoB,GAAG,GAAS,IAEtD,EAAC,EAAD,CACM,MACL,YAAU,YACV,mBAAoB,EACnB,kDACA,EACA,CACD,UAAW,EAAG,8BAA+B,EAAU,CACvD,GAAI,WAEJ,EAAC,EAAD,CAAkB,WAA2B,CAAA,CACnC,CAAA,CAGb,CACD,EAAK,YAAc,WA4BnB,MAAM,EAAQ,GACZ,CAAE,UAAS,WAAU,YAAW,GAAG,GAAS,IAI3C,EAHY,EAAUA,EAAc,MAGpC,CACM,MACL,YAAU,kBACV,UAAW,EACV,wCAOA,+FACA,EACA,CACD,GAAI,EAEH,WACK,CAAA,CAGT,CACD,EAAM,YAAc,gBAuCpB,MAAM,EAAmB,GACvB,CAAE,YAAW,QAAO,GAAG,GAAS,IAAQ,CAExC,IAAM,EADU,EAAW,EACP,CAAC,MAAM,GACrB,EAAO,GAAM,MAAQ,KACrB,EAAe,GAAM,cAAgB,GAG3C,OACC,EAAC,MAAD,CACM,MACL,YAAU,iBACV,cANe,GAAM,UAAY,GAMT,GAAK,IAAA,GAC7B,UAAW,EACV,8KACA,sDAQA,gFAUA,iEACA,wDACA,iEACA,oDACA,sDASA,mDACA,EACA,CACD,GAAI,WAxCL,CA0CE,EACA,GACA,EAAC,MAAD,CAAK,UAAU,iFACd,EAAC,MAAD,CAAK,UAAU,mCAAqC,CAAA,CAC/C,CAAA,CAEF,IAGR,CACD,EAAiB,YAAc,eAuC/B,MAAM,EAAY,GAChB,CAAE,UAAS,WAAU,YAAW,WAAW,GAAO,GAAG,GAAS,IAAQ,CACtE,IAAM,EAAO,EAAUA,EAAc,MAC/B,EAAgB,EAAW,CAAE,KAAM,YAAa,CAAG,CAAE,cAAe,GAAM,KAAM,OAAQ,CAE9F,OACC,EAAC,EAAD,CACM,MACL,YAAU,sBACV,UAAW,EAAG,+BAAgC,EAAU,CACxD,GAAI,EACJ,GAAI,WAEH,GAAY,EAAC,EAAD,CAAW,OAAO,OAAS,CAAA,CAClC,CAAA,EAGT,CACD,EAAU,YAAc,oBAqCxB,MAAM,EAAW,CAyBhB,OAwBA,QAyBA,KAAM,EAwBN,YACA"}
1
+ {"version":3,"file":"otp-input.js","names":["AsChildSlot"],"sources":["../src/components/otp-input/otp-input.tsx"],"sourcesContent":["\"use client\";\n\nimport { MinusIcon } from \"@phosphor-icons/react/Minus\";\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport type { ComponentProps, ComponentRef, ReactNode } from \"react\";\nimport { forwardRef, useContext } from \"react\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { Slot as AsChildSlot } from \"../slot/index.js\";\n\ntype OtpState = \"idle\" | \"caret\" | \"range\" | \"all\";\n\n/**\n * Map the count of active slots to a discrete `data-otp-state` value used by\n * descendant CSS selectors. Split out from the rendering component so the\n * decision tree reads as a flat `if`/`else` chain rather than a nested\n * ternary.\n */\nconst computeOtpState = ({\n\ttotalActive,\n\ttotal,\n}: {\n\ttotalActive: number;\n\ttotal: number;\n}): OtpState => {\n\tif (totalActive === 0) {\n\t\treturn \"idle\";\n\t}\n\tif (totalActive === 1) {\n\t\treturn \"caret\";\n\t}\n\tif (totalActive === total) {\n\t\treturn \"all\";\n\t}\n\treturn \"range\";\n};\n\n/**\n * Bridge component that lives inside `<OTPInput>` (so it can read\n * `OTPInputContext`) and exposes the current selection state as a DOM data\n * attribute. Descendant `OtpInput.Group` / `OtpInput.Slot` parts read this\n * via Tailwind's `group-data-*` selector, so all conditional styling lives\n * in CSS — no React context.\n *\n * `data-otp-state` is one of:\n * - `\"idle\"` — no slot active (input not focused)\n * - `\"caret\"` — exactly one slot active (typing caret)\n * - `\"range\"` — multiple but not all slots active (partial selection)\n * - `\"all\"` — every slot active (cmd+a / select-all)\n */\nconst MantleOtpBridge = ({ children }: { children: ReactNode }) => {\n\tconst inputOtpContext = useContext(OTPInputContext);\n\tconst total = inputOtpContext.slots.length;\n\tconst totalActive = inputOtpContext.slots.reduce(\n\t\t(count, slot) => count + (slot.isActive ? 1 : 0),\n\t\t0,\n\t);\n\tconst otpState = computeOtpState({ totalActive, total });\n\n\t// `display: contents` keeps this element in the DOM tree (so `group/`\n\t// ancestor selectors resolve) without producing a layout box.\n\treturn (\n\t\t<div className=\"group/otp contents\" data-otp-state={otpState}>\n\t\t\t{children}\n\t\t</div>\n\t);\n};\n\n// Drop the `render` / `children?: never` branch of input-otp's discriminated\n// union — `OtpInput.Root` always wraps its children in `MantleOtpBridge`,\n// so consumers compose with `OtpInput.Group` / `OtpInput.Slot` children\n// rather than a render prop.\ntype OtpInputRootProps = Omit<ComponentProps<typeof OTPInput>, \"render\" | \"children\"> & {\n\tchildren?: ReactNode;\n};\n\n/**\n * The root of the OTP input. Renders an accessible single hidden input that\n * captures keystrokes, paste events, and autofill, and exposes per-slot state\n * (active, char, fake caret) to descendant `OtpInput.Slot` parts via context.\n *\n * Wraps the `input-otp` library by Guilherme Rodz.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\n// `OtpInput.Root` does not support `asChild`: the underlying `OTPInput`\n// owns its hidden `<input>` and its render contract — swapping the element\n// would break input-otp's internal focus and selection management.\nconst Root = forwardRef<ComponentRef<typeof OTPInput>, OtpInputRootProps>(\n\t({ children, className, containerClassName, ...props }, ref) => {\n\t\treturn (\n\t\t\t<OTPInput\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input\"\n\t\t\t\tcontainerClassName={cx(\n\t\t\t\t\t\"flex items-center gap-2 has-disabled:opacity-50\",\n\t\t\t\t\tcontainerClassName,\n\t\t\t\t)}\n\t\t\t\tclassName={cx(\"disabled:cursor-not-allowed\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<MantleOtpBridge>{children}</MantleOtpBridge>\n\t\t\t</OTPInput>\n\t\t);\n\t},\n);\nRoot.displayName = \"OtpInput\";\n\ntype OtpInputGroupProps = ComponentProps<\"div\"> & WithAsChild;\n\n/**\n * Groups one or more `OtpInput.Slot` parts into a visually-connected segment.\n * Slots inside a group share rounded corners on the outer edges and join with\n * shared borders between adjacent slots.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\nconst Group = forwardRef<HTMLDivElement, OtpInputGroupProps>(\n\t({ asChild, children, className, ...props }, ref) => {\n\t\tconst Comp = asChild ? AsChildSlot : \"div\";\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input-group\"\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"relative flex items-center rounded-md\",\n\t\t\t\t\t// A \"range\" selection within this group means two or more\n\t\t\t\t\t// slots are simultaneously active. CSS `:has()` with the\n\t\t\t\t\t// general sibling combinator catches that without us\n\t\t\t\t\t// having to count: if any active slot is preceded by\n\t\t\t\t\t// another active slot at the same nesting level, the\n\t\t\t\t\t// group has at least 2 actives → draw the ring.\n\t\t\t\t\t\"has-[[data-active]~[data-active]]:ring-focus-accent has-[[data-active]~[data-active]]:ring-4\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nGroup.displayName = \"OtpInputGroup\";\n\ntype OtpInputSlotProps = ComponentProps<\"div\"> & {\n\t/**\n\t * The zero-based index of the character slot to render. Must be a valid\n\t * index within the parent `OtpInput.Root`'s `maxLength`.\n\t */\n\tindex: number;\n};\n\n/**\n * Renders a single character slot for the OTP input. Reads its display state\n * (the typed character, active/focused state, and fake caret position) from\n * the nearest `OtpInput.Root` via context — so this part must always be\n * rendered inside an `OtpInput.Root`.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\n// `OtpInput.Slot` does not support `asChild`: the slot reads context-driven\n// state (char, fake caret, active) from `OTPInputContext` and renders that\n// state into a fixed visual structure. Letting consumers swap the element\n// would lose the caret overlay and the active-ring focus styling.\nconst OtpInputSlotImpl = forwardRef<HTMLDivElement, OtpInputSlotProps>(\n\t({ className, index, ...props }, ref) => {\n\t\tconst context = useContext(OTPInputContext);\n\t\tconst slot = context.slots[index];\n\t\tconst char = slot?.char ?? null;\n\t\tconst hasFakeCaret = slot?.hasFakeCaret ?? false;\n\t\tconst isActive = slot?.isActive ?? false;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input-slot\"\n\t\t\t\tdata-active={isActive ? \"\" : undefined}\n\t\t\t\tclassName={cx(\n\t\t\t\t\t\"border-form bg-form text-strong relative flex h-10 w-10 items-center justify-center border-y border-r text-sm shadow-sm outline-hidden transition-all duration-150 ease-out\",\n\t\t\t\t\t\"first:rounded-l-md first:border-l last:rounded-r-md\",\n\t\t\t\t\t// When this slot is immediately followed by the caret\n\t\t\t\t\t// slot, hide our `border-r` so the active slot's\n\t\t\t\t\t// `border-l` is the only line at the boundary — without\n\t\t\t\t\t// this, the two adjacent 1px borders read as a doubled\n\t\t\t\t\t// edge. We use an arbitrary `&:has(+ ...)` variant\n\t\t\t\t\t// because Tailwind's `has-[...]` shorthand doesn't\n\t\t\t\t\t// parse the nested bracketed attribute selector here.\n\t\t\t\t\t\"[&:has(+[data-active])]:group-data-[otp-state=caret]/otp:border-r-transparent\",\n\t\t\t\t\t// Per-slot ring renders only in `caret` state (single\n\t\t\t\t\t// active slot). When more than one slot is active, the\n\t\t\t\t\t// surrounding `OtpInput.Group` draws a single ring\n\t\t\t\t\t// around the whole group — see Group's `:has()` rule.\n\t\t\t\t\t// We also recolor the slot's own borders to accent and\n\t\t\t\t\t// fill in `border-l` (groups normally only render\n\t\t\t\t\t// `border-l` on `:first-child`), so the slot reads as\n\t\t\t\t\t// one cohesive highlighted box rather than a ring with\n\t\t\t\t\t// a gray box inside.\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:border-accent-600\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:border-l\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:ring-focus-accent\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:z-20\",\n\t\t\t\t\t\"data-active:group-data-[otp-state=caret]/otp:ring-4\",\n\t\t\t\t\t// Select-all: tint *every* border on the slot accent.\n\t\t\t\t\t// Tinting only the outside edges leaves the internal\n\t\t\t\t\t// vertical divider (gray `border-r`) meeting the\n\t\t\t\t\t// accent top/bottom borders at the corner, producing a\n\t\t\t\t\t// visible 1px miter spike. Coloring all borders the\n\t\t\t\t\t// same accent-600 hue makes the corner blend\n\t\t\t\t\t// seamlessly while still keeping the slot grid\n\t\t\t\t\t// readable at full opacity.\n\t\t\t\t\t\"group-data-[otp-state=all]/otp:border-accent-600\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{char}\n\t\t\t\t{hasFakeCaret && (\n\t\t\t\t\t<div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t<div className=\"bg-strong h-4 w-px animate-pulse\" />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nOtpInputSlotImpl.displayName = \"OtpInputSlot\";\n\ntype OtpInputSeparatorProps = ComponentProps<\"div\"> &\n\tWithAsChild & {\n\t\t/**\n\t\t * If `true`, the separator will be rendered with `role=\"separator\"` so\n\t\t * assistive tech announces it as a divider between OTP groups.\n\t\t * If `false`, the separator is purely decorative and is removed from\n\t\t * the accessibility tree — preferred inside an OTP control where the\n\t\t * minus icon is just visual chrome between slot groups.\n\t\t *\n\t\t * @default false\n\t\t */\n\t\tsemantic?: boolean;\n\t};\n\n/**\n * A visual separator between two `OtpInput.Group` segments. Renders a minus\n * icon by default; pass `children` to override the visual.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\nconst Separator = forwardRef<HTMLDivElement, OtpInputSeparatorProps>(\n\t({ asChild, children, className, semantic = false, ...props }, ref) => {\n\t\tconst Comp = asChild ? AsChildSlot : \"div\";\n\t\tconst semanticProps = semantic ? { role: \"separator\" } : { \"aria-hidden\": true, role: \"none\" };\n\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"otp-input-separator\"\n\t\t\t\tclassName={cx(\"text-muted flex items-center\", className)}\n\t\t\t\t{...semanticProps}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children ?? <MinusIcon weight=\"bold\" />}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nSeparator.displayName = \"OtpInputSeparator\";\n\n/**\n * Compound component for capturing one-time passcodes (OTP). Combines a\n * single hidden input (handling paste, autofill, and IME) with a row of\n * styled character slots.\n *\n * @see https://mantle.ngrok.com/components/otp-input\n *\n * @example\n * Composition:\n * ```\n * OtpInput.Root\n * ├── OtpInput.Group\n * │ └── OtpInput.Slot\n * ├── OtpInput.Separator\n * └── OtpInput.Group\n * └── OtpInput.Slot\n * ```\n *\n * @example\n * ```tsx\n * <OtpInput.Root maxLength={6}>\n * <OtpInput.Group>\n * <OtpInput.Slot index={0} />\n * <OtpInput.Slot index={1} />\n * <OtpInput.Slot index={2} />\n * </OtpInput.Group>\n * <OtpInput.Separator />\n * <OtpInput.Group>\n * <OtpInput.Slot index={3} />\n * <OtpInput.Slot index={4} />\n * <OtpInput.Slot index={5} />\n * </OtpInput.Group>\n * </OtpInput.Root>\n * ```\n */\nconst OtpInput = {\n\t/**\n\t * The root of the OTP input. Wraps the hidden input that captures\n\t * keystrokes, paste, and autofill, and provides per-slot state to\n\t * descendant `OtpInput.Slot` parts.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * Groups one or more `OtpInput.Slot` parts into a visually-connected\n\t * segment with shared rounded corners and joined borders.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tGroup,\n\t/**\n\t * A single character slot. Must be rendered inside an `OtpInput.Root`.\n\t * Reads its character, active state, and fake caret position from the\n\t * root via context.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tSlot: OtpInputSlotImpl,\n\t/**\n\t * A visual separator between two `OtpInput.Group` segments. Renders a\n\t * minus icon by default; pass `children` to override.\n\t *\n\t * @see https://mantle.ngrok.com/components/otp-input\n\t *\n\t * @example\n\t * ```tsx\n\t * <OtpInput.Root maxLength={6}>\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={0} />\n\t * <OtpInput.Slot index={1} />\n\t * <OtpInput.Slot index={2} />\n\t * </OtpInput.Group>\n\t * <OtpInput.Separator />\n\t * <OtpInput.Group>\n\t * <OtpInput.Slot index={3} />\n\t * <OtpInput.Slot index={4} />\n\t * <OtpInput.Slot index={5} />\n\t * </OtpInput.Group>\n\t * </OtpInput.Root>\n\t * ```\n\t */\n\tSeparator,\n} as const;\n\nexport {\n\t//,\n\tOtpInput,\n};\n\nexport {\n\t//,\n\tREGEXP_ONLY_CHARS,\n\tREGEXP_ONLY_DIGITS,\n\tREGEXP_ONLY_DIGITS_AND_CHARS,\n} from \"input-otp\";\n"],"mappings":"+WAkBA,MAAM,GAAmB,CACxB,cACA,WAKI,IAAgB,EACZ,OAEJ,IAAgB,EACZ,QAEJ,IAAgB,EACZ,MAED,QAgBF,GAAmB,CAAE,cAAwC,CAClE,IAAM,EAAkB,EAAW,EAAgB,CAC7C,EAAQ,EAAgB,MAAM,OASpC,OACC,EAAC,MAAD,CAAK,UAAU,qBAAqB,iBALpB,EAAgB,CAAE,YAJf,EAAgB,MAAM,QACxC,EAAO,IAAS,GAAS,KAAK,SAC/B,EAE6C,CAAE,QAAO,CAKM,CAC1D,WACI,CAAA,EAyCF,EAAO,GACX,CAAE,WAAU,YAAW,qBAAoB,GAAG,GAAS,IAEtD,EAAC,EAAD,CACM,MACL,YAAU,YACV,mBAAoB,EACnB,kDACA,EACA,CACD,UAAW,EAAG,8BAA+B,EAAU,CACvD,GAAI,WAEJ,EAAC,EAAD,CAAkB,WAA2B,CAAA,CACnC,CAAA,CAGb,CACD,EAAK,YAAc,WA4BnB,MAAM,EAAQ,GACZ,CAAE,UAAS,WAAU,YAAW,GAAG,GAAS,IAI3C,EAHY,EAAUA,EAAc,MAGpC,CACM,MACL,YAAU,kBACV,UAAW,EACV,wCAOA,+FACA,EACA,CACD,GAAI,EAEH,WACK,CAAA,CAGT,CACD,EAAM,YAAc,gBAuCpB,MAAM,EAAmB,GACvB,CAAE,YAAW,QAAO,GAAG,GAAS,IAAQ,CAExC,IAAM,EADU,EAAW,EACP,CAAC,MAAM,GACrB,EAAO,GAAM,MAAQ,KACrB,EAAe,GAAM,cAAgB,GAG3C,OACC,EAAC,MAAD,CACM,MACL,YAAU,iBACV,cANe,GAAM,UAAY,GAMT,GAAK,IAAA,GAC7B,UAAW,EACV,8KACA,sDAQA,gFAUA,iEACA,wDACA,iEACA,oDACA,sDASA,mDACA,EACA,CACD,GAAI,WAxCL,CA0CE,EACA,GACA,EAAC,MAAD,CAAK,UAAU,iFACd,EAAC,MAAD,CAAK,UAAU,mCAAqC,CAAA,CAC/C,CAAA,CAEF,IAGR,CACD,EAAiB,YAAc,eAuC/B,MAAM,EAAY,GAChB,CAAE,UAAS,WAAU,YAAW,WAAW,GAAO,GAAG,GAAS,IAAQ,CACtE,IAAM,EAAO,EAAUA,EAAc,MAC/B,EAAgB,EAAW,CAAE,KAAM,YAAa,CAAG,CAAE,cAAe,GAAM,KAAM,OAAQ,CAE9F,OACC,EAAC,EAAD,CACM,MACL,YAAU,sBACV,UAAW,EAAG,+BAAgC,EAAU,CACxD,GAAI,EACJ,GAAI,WAEH,GAAY,EAAC,EAAD,CAAW,OAAO,OAAS,CAAA,CAClC,CAAA,EAGT,CACD,EAAU,YAAc,oBAqCxB,MAAM,EAAW,CAyBhB,OAwBA,QAyBA,KAAM,EAwBN,YACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngrok/mantle",
3
- "version": "0.71.0",
3
+ "version": "0.71.1",
4
4
  "description": "mantle is ngrok's UI library and design system.",
5
5
  "homepage": "https://mantle.ngrok.com",
6
6
  "license": "MIT",
@@ -48,6 +48,8 @@
48
48
  "default": "./dist/source-all.css"
49
49
  },
50
50
  "./package.json": "./package.json",
51
+ "./agent.json": "./dist/agent.json",
52
+ "./llms.txt": "./dist/llms.txt",
51
53
  "./accordion": {
52
54
  "@ngrok/src-live-types": "./src/components/accordion/index.ts",
53
55
  "types": "./dist/accordion.d.ts",