@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 +4 -0
- package/dist/agent.json +76 -0
- package/dist/command.d.ts +7 -7
- package/dist/hooks.d.ts +2 -2
- package/dist/llms.txt +77 -0
- package/dist/otp-input.js +1 -1
- package/dist/otp-input.js.map +1 -1
- package/package.json +3 -1
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`:
|
package/dist/agent.json
ADDED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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-
|
|
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
|
package/dist/otp-input.js.map
CHANGED
|
@@ -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.
|
|
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",
|