@waveso/ui 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -22
- package/dist/accordion.d.ts +4 -20
- package/dist/accordion.js +2 -2
- package/dist/action-bar.d.ts +1 -10
- package/dist/action-bar.js +6 -5
- package/dist/alert-dialog.d.ts +12 -52
- package/dist/alert-dialog.js +5 -5
- package/dist/alert.d.ts +13 -22
- package/dist/alert.js +13 -4
- package/dist/animate.d.ts +6 -49
- package/dist/animate.js +8 -13
- package/dist/aspect-ratio.d.ts +3 -8
- package/dist/autocomplete.d.ts +21 -88
- package/dist/autocomplete.js +3 -3
- package/dist/avatar.d.ts +7 -28
- package/dist/avatar.js +4 -4
- package/dist/badge.d.ts +3 -11
- package/dist/badge.js +6 -6
- package/dist/breadcrumb.d.ts +7 -31
- package/dist/button-group.d.ts +7 -20
- package/dist/button-group.js +5 -4
- package/dist/button.d.ts +4 -12
- package/dist/button.js +6 -6
- package/dist/card.d.ts +16 -33
- package/dist/card.js +27 -14
- package/dist/checkbox.d.ts +1 -6
- package/dist/checkbox.js +2 -2
- package/dist/collapsible.d.ts +3 -12
- package/dist/combobox.d.ts +18 -81
- package/dist/combobox.js +4 -4
- package/dist/context-menu.d.ts +17 -68
- package/dist/context-menu.js +14 -14
- package/dist/count.d.ts +1 -15
- package/dist/count.js +3 -2
- package/dist/dialog.d.ts +10 -41
- package/dist/dialog.js +5 -5
- package/dist/direction.d.ts +0 -1
- package/dist/drawer.d.ts +11 -44
- package/dist/drawer.js +1 -1
- package/dist/encrypted-text.d.ts +15 -14
- package/dist/encrypted-text.js +205 -66
- package/dist/field.d.ts +27 -30
- package/dist/field.js +36 -8
- package/dist/fieldset.d.ts +14 -0
- package/dist/fieldset.js +26 -0
- package/dist/film-grain-shader.d.ts +3 -4
- package/dist/film-grain-webgl.d.ts +2 -9
- package/dist/film-grain-webgl.js +4 -1
- package/dist/film-grain.d.ts +1 -11
- package/dist/form.d.ts +23 -42
- package/dist/form.js +7 -4
- package/dist/glyph-matrix.d.ts +25 -0
- package/dist/glyph-matrix.js +266 -0
- package/dist/gradient-reveal-text.d.ts +4 -17
- package/dist/gradient-reveal-text.js +8 -8
- package/dist/hooks/use-mobile.d.ts +2 -3
- package/dist/infinite-scroll.d.ts +1 -16
- package/dist/input-group.d.ts +11 -37
- package/dist/input-group.js +1 -1
- package/dist/input-otp.d.ts +4 -20
- package/dist/input-otp.js +2 -2
- package/dist/input.d.ts +3 -11
- package/dist/input.js +1 -1
- package/dist/item.d.ts +14 -51
- package/dist/item.js +17 -11
- package/dist/kbd.d.ts +3 -11
- package/dist/kbd.js +2 -2
- package/dist/label.d.ts +1 -6
- package/dist/label.js +1 -1
- package/dist/lib/focus.d.ts +3 -5
- package/dist/lib/internal-icons.d.ts +19 -22
- package/dist/lib/merge-refs.d.ts +9 -0
- package/dist/lib/merge-refs.js +16 -0
- package/dist/lib/utils.d.ts +3 -5
- package/dist/lib/utils.js +9 -1
- package/dist/masonry.d.ts +2 -16
- package/dist/masonry.js +5 -3
- package/dist/menu.d.ts +17 -65
- package/dist/menu.js +7 -7
- package/dist/menubar.d.ts +16 -55
- package/dist/menubar.js +1 -1
- package/dist/pagination.d.ts +9 -33
- package/dist/pagination.js +1 -1
- package/dist/popover.d.ts +9 -43
- package/dist/popover.js +1 -1
- package/dist/preview-card.d.ts +5 -25
- package/dist/preview-card.js +1 -1
- package/dist/progress.d.ts +5 -24
- package/dist/progress.js +2 -2
- package/dist/radio-group.d.ts +2 -9
- package/dist/radio-group.js +1 -1
- package/dist/radio.d.ts +2 -10
- package/dist/radio.js +2 -2
- package/dist/resizable.d.ts +43 -0
- package/dist/resizable.js +53 -0
- package/dist/scroll-area.d.ts +14 -13
- package/dist/scroll-area.js +26 -7
- package/dist/select.d.ts +15 -64
- package/dist/select.js +4 -4
- package/dist/separator.d.ts +1 -7
- package/dist/separator.js +1 -1
- package/dist/sidebar.d.ts +29 -126
- package/dist/sidebar.js +14 -14
- package/dist/skeleton.d.ts +1 -6
- package/dist/slider.d.ts +1 -14
- package/dist/slider.js +5 -5
- package/dist/spinner.d.ts +8 -6
- package/dist/spinner.js +24 -6
- package/dist/styles.css +575 -182
- package/dist/switch.d.ts +2 -9
- package/dist/switch.js +6 -6
- package/dist/table.d.ts +14 -34
- package/dist/table.js +40 -9
- package/dist/tabs.d.ts +5 -22
- package/dist/tabs.js +3 -3
- package/dist/textarea.d.ts +3 -12
- package/dist/textarea.js +1 -1
- package/dist/toast.d.ts +13 -39
- package/dist/toast.js +4 -4
- package/dist/toggle-group.d.ts +3 -19
- package/dist/toggle-group.js +16 -10
- package/dist/toggle.d.ts +3 -11
- package/dist/toggle.js +11 -6
- package/dist/tooltip.d.ts +6 -24
- package/dist/tooltip.js +10 -6
- package/dist/typewriter.d.ts +1 -14
- package/dist/video-text.d.ts +25 -0
- package/dist/video-text.js +147 -0
- package/package.json +57 -51
package/dist/form.d.ts
CHANGED
|
@@ -1,36 +1,12 @@
|
|
|
1
1
|
import { Field } from "./field.js";
|
|
2
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
2
|
import * as React from "react";
|
|
4
|
-
import * as _$react_hook_form0 from "react-hook-form";
|
|
5
3
|
import { ControllerFieldState, ControllerRenderProps, FieldPath, FieldValues, RegisterOptions, SubmitHandler, UseFormReturn, useForm, useWatch } from "react-hook-form";
|
|
6
|
-
|
|
7
4
|
//#region src/form.d.ts
|
|
8
5
|
type FormProps<TFieldValues extends FieldValues> = {
|
|
9
6
|
form: UseFormReturn<TFieldValues>;
|
|
10
7
|
onSubmit: SubmitHandler<TFieldValues>;
|
|
11
8
|
} & Omit<React.ComponentProps<"form">, "onSubmit">;
|
|
12
9
|
type FormRootProps = React.ComponentProps<"form">;
|
|
13
|
-
type FormErrorProps = React.ComponentProps<"p">;
|
|
14
|
-
type FormActionsProps = React.ComponentProps<"div">;
|
|
15
|
-
type FormMessageProps = React.ComponentProps<"p">;
|
|
16
|
-
declare function Form<TFieldValues extends FieldValues>({
|
|
17
|
-
form,
|
|
18
|
-
onSubmit,
|
|
19
|
-
...props
|
|
20
|
-
}: FormProps<TFieldValues>): _$react_jsx_runtime0.JSX.Element;
|
|
21
|
-
/**
|
|
22
|
-
* Plain `<form>` element with RHF integration.
|
|
23
|
-
*
|
|
24
|
-
* Uses a native `<form>` instead of `@base-ui/react/form` because Base UI
|
|
25
|
-
* Form's internal submit/validation handling conflicts with React Hook Form
|
|
26
|
-
* and blocks button click events inside modal dialogs. Since RHF already
|
|
27
|
-
* provides validation, error handling, and submit management, the Base UI
|
|
28
|
-
* Form wrapper adds no value at the moment.
|
|
29
|
-
*/
|
|
30
|
-
declare function FormRoot({
|
|
31
|
-
className,
|
|
32
|
-
...props
|
|
33
|
-
}: FormRootProps): _$react_jsx_runtime0.JSX.Element;
|
|
34
10
|
type FormFieldRenderArgs<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> = {
|
|
35
11
|
id: string;
|
|
36
12
|
field: ControllerRenderProps<TFieldValues, TName>;
|
|
@@ -53,25 +29,30 @@ type FormFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TF
|
|
|
53
29
|
*/
|
|
54
30
|
render: (args: FormFieldRenderArgs<TFieldValues, TName>) => React.ReactNode;
|
|
55
31
|
} & Omit<React.ComponentProps<typeof Field>, "children" | "name" | "invalid" | "touched" | "dirty" | "render">;
|
|
32
|
+
type FormErrorProps = React.ComponentProps<"p">;
|
|
33
|
+
type FormActionsProps = React.ComponentProps<"div">;
|
|
34
|
+
type FormMessageProps = React.ComponentProps<"p">;
|
|
35
|
+
declare function Form<TFieldValues extends FieldValues>({ form, onSubmit, ...props }: FormProps<TFieldValues>): React.JSX.Element;
|
|
36
|
+
/**
|
|
37
|
+
* Plain `<form>` element with RHF integration.
|
|
38
|
+
*
|
|
39
|
+
* Uses a native `<form>` instead of `@base-ui/react/form` because Base UI
|
|
40
|
+
* Form's internal submit/validation handling conflicts with React Hook Form
|
|
41
|
+
* and blocks button click events inside modal dialogs. Since RHF already
|
|
42
|
+
* provides validation, error handling, and submit management, the Base UI
|
|
43
|
+
* Form wrapper adds no value at the moment.
|
|
44
|
+
*/
|
|
45
|
+
declare function FormRoot({ className, ...props }: FormRootProps): React.JSX.Element;
|
|
56
46
|
/**
|
|
57
47
|
* Base UI + React Hook Form field helper.
|
|
58
48
|
*
|
|
59
49
|
* It maps RHF Controller state onto Base UI's <Field> state so styling can
|
|
60
50
|
* rely on `data-[invalid]`, `data-[touched]`, `data-[dirty]`, etc.
|
|
61
51
|
*/
|
|
62
|
-
declare function FormField<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>(props: FormFieldProps<TFieldValues, TName>):
|
|
63
|
-
declare function FormError({
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}: FormErrorProps): _$react_jsx_runtime0.JSX.Element | null;
|
|
67
|
-
declare function FormActions({
|
|
68
|
-
className,
|
|
69
|
-
...props
|
|
70
|
-
}: FormActionsProps): _$react_jsx_runtime0.JSX.Element;
|
|
71
|
-
declare function FormMessage({
|
|
72
|
-
className,
|
|
73
|
-
...props
|
|
74
|
-
}: FormMessageProps): _$react_jsx_runtime0.JSX.Element;
|
|
52
|
+
declare function FormField<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>(props: FormFieldProps<TFieldValues, TName>): React.JSX.Element;
|
|
53
|
+
declare function FormError({ className, ...props }: FormErrorProps): React.JSX.Element | null;
|
|
54
|
+
declare function FormActions({ className, ...props }: FormActionsProps): React.JSX.Element;
|
|
55
|
+
declare function FormMessage({ className, ...props }: FormMessageProps): React.JSX.Element;
|
|
75
56
|
/**
|
|
76
57
|
* Convenience helper for mapping RHF field props onto either:
|
|
77
58
|
* - Base UI controls (use `onValueChange`)
|
|
@@ -83,15 +64,15 @@ declare function fieldControlProps<TFieldValues extends FieldValues, TName exten
|
|
|
83
64
|
invalid?: boolean;
|
|
84
65
|
native?: boolean;
|
|
85
66
|
}): {
|
|
86
|
-
"aria-describedby": string | undefined;
|
|
87
|
-
"aria-invalid": boolean | undefined;
|
|
88
|
-
onValueChange?: ((...event: any[]) => void) | undefined;
|
|
89
67
|
id: string | undefined;
|
|
90
68
|
name: TName;
|
|
91
|
-
ref:
|
|
69
|
+
ref: import("react-hook-form").RefCallBack;
|
|
92
70
|
value: string;
|
|
93
|
-
onBlur:
|
|
71
|
+
onBlur: import("react-hook-form").Noop;
|
|
94
72
|
onChange: (...event: any[]) => void;
|
|
73
|
+
onValueChange?: ((...event: any[]) => void) | undefined;
|
|
74
|
+
"aria-describedby": string | undefined;
|
|
75
|
+
"aria-invalid": boolean | undefined;
|
|
95
76
|
};
|
|
96
77
|
//#endregion
|
|
97
78
|
export { Form, FormActions, type FormActionsProps, FormError, type FormErrorProps, FormField, type FormFieldProps, type FormFieldRenderArgs, FormMessage, type FormMessageProps, type FormProps, FormRoot, type FormRootProps, fieldControlProps, useForm, useWatch };
|
package/dist/form.js
CHANGED
|
@@ -65,16 +65,19 @@ function FormField(props) {
|
|
|
65
65
|
children: [
|
|
66
66
|
label ? /* @__PURE__ */ jsxs(FieldLabel, { children: [label, isRequired ? /* @__PURE__ */ jsx("span", {
|
|
67
67
|
"aria-hidden": "true",
|
|
68
|
-
className: "text-
|
|
68
|
+
className: "text-danger ms-1",
|
|
69
69
|
children: "*"
|
|
70
70
|
}) : null] }) : null,
|
|
71
|
-
description ? /* @__PURE__ */ jsx(FieldDescription, { children: description }) : null,
|
|
72
71
|
render({
|
|
73
72
|
id: controlId,
|
|
74
73
|
field,
|
|
75
74
|
fieldState
|
|
76
75
|
}),
|
|
77
|
-
fieldState.error ? /* @__PURE__ */ jsx(FieldError, {
|
|
76
|
+
fieldState.error ? /* @__PURE__ */ jsx(FieldError, {
|
|
77
|
+
match: true,
|
|
78
|
+
children: fieldState.error.message
|
|
79
|
+
}) : null,
|
|
80
|
+
description ? /* @__PURE__ */ jsx(FieldDescription, { children: description }) : null
|
|
78
81
|
]
|
|
79
82
|
})
|
|
80
83
|
});
|
|
@@ -86,7 +89,7 @@ function FormError({ className, ...props }) {
|
|
|
86
89
|
return /* @__PURE__ */ jsx("p", {
|
|
87
90
|
"data-slot": "form-error",
|
|
88
91
|
role: "alert",
|
|
89
|
-
className: cn("text-
|
|
92
|
+
className: cn("text-danger rounded-lg border border-danger/30 bg-danger/5 p-4 text-sm", className),
|
|
90
93
|
...props,
|
|
91
94
|
children: message
|
|
92
95
|
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/glyph-matrix.d.ts
|
|
3
|
+
interface GlyphMatrixProps extends React.ComponentProps<"canvas"> {
|
|
4
|
+
/** Characters picked from at random. */
|
|
5
|
+
glyphs?: string;
|
|
6
|
+
/** Multiplies how fast the field changes. 0 holds it still. */
|
|
7
|
+
speed?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Bright flashes, some typing short runs along a row. Off leaves a calm
|
|
10
|
+
* shimmer: glyphs swapping quietly at their resting brightness.
|
|
11
|
+
*/
|
|
12
|
+
glitch?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A field of glitching glyphs, for decorative backgrounds (`glitch={false}`
|
|
16
|
+
* for a calm shimmer behind busy content). Styled with
|
|
17
|
+
* classes: `text-*` sets the glyphs' color and size, `font-*` their typeface,
|
|
18
|
+
* and `accent-*` the color of the flares, which alternate with the text color
|
|
19
|
+
* at full strength. A theme switch re-tints the field. `opacity-*` makes it
|
|
20
|
+
* fainter, and `mask-*` fades it toward an edge (`mask-b-from-40%`) or around
|
|
21
|
+
* content on top (`mask-radial-from-transparent mask-radial-to-black`).
|
|
22
|
+
*/
|
|
23
|
+
declare function GlyphMatrix({ glyphs, speed, glitch, className, ref, ...props }: GlyphMatrixProps): React.JSX.Element;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { GlyphMatrix, type GlyphMatrixProps };
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./lib/utils.js";
|
|
3
|
+
import { mergeRefs } from "./lib/merge-refs.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
//#region src/glyph-matrix.tsx
|
|
7
|
+
const DEFAULT_GLYPHS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$&*()-_+=/[]{};:<>.,0123456789";
|
|
8
|
+
/** Space beside each glyph and the row height, in ems. */
|
|
9
|
+
const CELL_GAP = .6;
|
|
10
|
+
const ROW_HEIGHT = 1.55;
|
|
11
|
+
/** Share of cells left blank. */
|
|
12
|
+
const BLANK_SHARE = .1;
|
|
13
|
+
/** Resting opacity range of the other cells. */
|
|
14
|
+
const REST_MIN = .12;
|
|
15
|
+
const REST_RANGE = .38;
|
|
16
|
+
/** Share of the field that quietly swaps its glyph each second. */
|
|
17
|
+
const SWAP_RATE = .2;
|
|
18
|
+
/** Share of the field that flares each second. */
|
|
19
|
+
const FLARE_RATE = .035;
|
|
20
|
+
/** Chance a flare starts a streak: a run that types along its row. */
|
|
21
|
+
const STREAK_CHANCE = .24;
|
|
22
|
+
/** Share of streaks that run long (10–24 cells instead of 2–8). */
|
|
23
|
+
const LONG_STREAK_CHANCE = 1 / 16;
|
|
24
|
+
/** Seconds between a streak's cells. */
|
|
25
|
+
const STREAK_PACE = .028;
|
|
26
|
+
/** Faint background glyphs gain nothing from more than 2 device pixels per px. */
|
|
27
|
+
const MAX_PIXEL_RATIO = 2;
|
|
28
|
+
/** How often the canvas's color and font are re-read, in seconds. */
|
|
29
|
+
const STYLE_CHECK = .25;
|
|
30
|
+
function randomGlyph(pool) {
|
|
31
|
+
return pool[Math.floor(Math.random() * pool.length)] ?? " ";
|
|
32
|
+
}
|
|
33
|
+
function randomRest() {
|
|
34
|
+
return Math.random() < BLANK_SHARE ? 0 : REST_MIN + Math.random() * REST_RANGE;
|
|
35
|
+
}
|
|
36
|
+
function randomFlare() {
|
|
37
|
+
return {
|
|
38
|
+
peak: .45 + Math.random() * .55,
|
|
39
|
+
hold: .04 + Math.random() * .26,
|
|
40
|
+
fade: .45 + Math.random() * .6,
|
|
41
|
+
accent: Math.random() < .5
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Cells a streak adds after its first one. */
|
|
45
|
+
function streakLength() {
|
|
46
|
+
return Math.random() < LONG_STREAK_CHANCE ? 9 + Math.floor(Math.random() * 15) : 1 + Math.floor(Math.random() * 7);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A field of glitching glyphs, for decorative backgrounds (`glitch={false}`
|
|
50
|
+
* for a calm shimmer behind busy content). Styled with
|
|
51
|
+
* classes: `text-*` sets the glyphs' color and size, `font-*` their typeface,
|
|
52
|
+
* and `accent-*` the color of the flares, which alternate with the text color
|
|
53
|
+
* at full strength. A theme switch re-tints the field. `opacity-*` makes it
|
|
54
|
+
* fainter, and `mask-*` fades it toward an edge (`mask-b-from-40%`) or around
|
|
55
|
+
* content on top (`mask-radial-from-transparent mask-radial-to-black`).
|
|
56
|
+
*/
|
|
57
|
+
function GlyphMatrix({ glyphs = DEFAULT_GLYPHS, speed = 1, glitch = true, className, ref, ...props }) {
|
|
58
|
+
const canvasRef = React.useRef(null);
|
|
59
|
+
const mergedRef = React.useMemo(() => mergeRefs(canvasRef, ref), [ref]);
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
const canvas = canvasRef.current;
|
|
62
|
+
const context = canvas?.getContext("2d");
|
|
63
|
+
if (!canvas || !context) return;
|
|
64
|
+
const pool = Array.from(glyphs.length > 0 ? glyphs : DEFAULT_GLYPHS);
|
|
65
|
+
const pace = Number.isFinite(speed) ? Math.max(0, speed) : 1;
|
|
66
|
+
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
67
|
+
let color = "";
|
|
68
|
+
let accent = "";
|
|
69
|
+
let font = "";
|
|
70
|
+
let cellWidth = 0;
|
|
71
|
+
let cellHeight = 0;
|
|
72
|
+
let cols = 0;
|
|
73
|
+
let total = 0;
|
|
74
|
+
let cells = [];
|
|
75
|
+
let rests = /* @__PURE__ */ new Float32Array(0);
|
|
76
|
+
let heats = /* @__PURE__ */ new Float32Array(0);
|
|
77
|
+
let flares = [];
|
|
78
|
+
const active = /* @__PURE__ */ new Set();
|
|
79
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
80
|
+
const streaks = [];
|
|
81
|
+
let swapCarry = 0;
|
|
82
|
+
let flareCarry = 0;
|
|
83
|
+
let styleCheck = STYLE_CHECK;
|
|
84
|
+
let visible = true;
|
|
85
|
+
let disposed = false;
|
|
86
|
+
let frame = 0;
|
|
87
|
+
let last = 0;
|
|
88
|
+
const drawCell = (index) => {
|
|
89
|
+
const x = index % cols * cellWidth;
|
|
90
|
+
const y = Math.floor(index / cols) * cellHeight;
|
|
91
|
+
const glyph = cells[index] ?? " ";
|
|
92
|
+
const rest = rests[index] ?? 0;
|
|
93
|
+
const heat = heats[index] ?? 0;
|
|
94
|
+
context.clearRect(x, y, cellWidth, cellHeight);
|
|
95
|
+
if (rest * (1 - heat) > .004) {
|
|
96
|
+
context.fillStyle = color;
|
|
97
|
+
context.globalAlpha = rest * (1 - heat);
|
|
98
|
+
context.fillText(glyph, x + cellWidth / 2, y + cellHeight / 2);
|
|
99
|
+
}
|
|
100
|
+
if (heat > .004) {
|
|
101
|
+
context.fillStyle = flares[index]?.accent ? accent : color;
|
|
102
|
+
context.globalAlpha = heat;
|
|
103
|
+
context.fillText(glyph, x + cellWidth / 2, y + cellHeight / 2);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const paintAll = () => {
|
|
107
|
+
context.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight);
|
|
108
|
+
context.font = font;
|
|
109
|
+
context.textAlign = "center";
|
|
110
|
+
context.textBaseline = "middle";
|
|
111
|
+
for (let index = 0; index < total; index++) drawCell(index);
|
|
112
|
+
dirty.clear();
|
|
113
|
+
};
|
|
114
|
+
const build = () => {
|
|
115
|
+
const ratio = Math.min(window.devicePixelRatio || 1, MAX_PIXEL_RATIO);
|
|
116
|
+
const { clientWidth: width, clientHeight: height } = canvas;
|
|
117
|
+
canvas.width = Math.round(width * ratio);
|
|
118
|
+
canvas.height = Math.round(height * ratio);
|
|
119
|
+
context.setTransform(ratio, 0, 0, ratio, 0, 0);
|
|
120
|
+
context.font = font;
|
|
121
|
+
const size = parseFloat(getComputedStyle(canvas).fontSize) || 14;
|
|
122
|
+
let advance = 1;
|
|
123
|
+
for (const glyph of new Set(pool)) advance = Math.max(advance, context.measureText(glyph).width);
|
|
124
|
+
cellWidth = Math.ceil(advance + size * CELL_GAP);
|
|
125
|
+
cellHeight = Math.ceil(size * ROW_HEIGHT);
|
|
126
|
+
cols = Math.ceil(width / cellWidth);
|
|
127
|
+
total = cols * Math.ceil(height / cellHeight);
|
|
128
|
+
cells = Array.from({ length: total }, () => randomGlyph(pool));
|
|
129
|
+
rests = Float32Array.from({ length: total }, randomRest);
|
|
130
|
+
heats = new Float32Array(total);
|
|
131
|
+
flares = [];
|
|
132
|
+
active.clear();
|
|
133
|
+
dirty.clear();
|
|
134
|
+
streaks.length = 0;
|
|
135
|
+
paintAll();
|
|
136
|
+
};
|
|
137
|
+
const syncStyle = () => {
|
|
138
|
+
const computed = getComputedStyle(canvas);
|
|
139
|
+
const nextAccent = computed.accentColor === "auto" ? computed.color : computed.accentColor;
|
|
140
|
+
const nextFont = `${computed.fontWeight} ${computed.fontSize} ${computed.fontFamily}`;
|
|
141
|
+
const colorChanged = computed.color !== color || nextAccent !== accent;
|
|
142
|
+
color = computed.color;
|
|
143
|
+
accent = nextAccent;
|
|
144
|
+
if (nextFont !== font) {
|
|
145
|
+
font = nextFont;
|
|
146
|
+
build();
|
|
147
|
+
if (!document.fonts.check(nextFont)) document.fonts.load(nextFont).then(() => {
|
|
148
|
+
if (!disposed && font === nextFont) build();
|
|
149
|
+
}, () => {});
|
|
150
|
+
} else if (colorChanged) paintAll();
|
|
151
|
+
};
|
|
152
|
+
const ignite = (index, flare) => {
|
|
153
|
+
flares[index] = { ...flare };
|
|
154
|
+
heats[index] = flare.peak;
|
|
155
|
+
active.add(index);
|
|
156
|
+
dirty.add(index);
|
|
157
|
+
};
|
|
158
|
+
const update = (dt) => {
|
|
159
|
+
swapCarry += total * SWAP_RATE * pace * dt;
|
|
160
|
+
for (; swapCarry >= 1; swapCarry--) {
|
|
161
|
+
const index = Math.floor(Math.random() * total);
|
|
162
|
+
if (active.has(index)) continue;
|
|
163
|
+
cells[index] = randomGlyph(pool);
|
|
164
|
+
dirty.add(index);
|
|
165
|
+
}
|
|
166
|
+
if (glitch) flareCarry += total * FLARE_RATE * pace * dt;
|
|
167
|
+
for (; flareCarry >= 1; flareCarry--) {
|
|
168
|
+
const index = Math.floor(Math.random() * total);
|
|
169
|
+
const flare = randomFlare();
|
|
170
|
+
ignite(index, flare);
|
|
171
|
+
if (Math.random() < STREAK_CHANCE) streaks.push({
|
|
172
|
+
index,
|
|
173
|
+
left: streakLength(),
|
|
174
|
+
carry: 0,
|
|
175
|
+
flare
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
for (let s = streaks.length - 1; s >= 0; s--) {
|
|
179
|
+
const streak = streaks[s];
|
|
180
|
+
if (!streak) continue;
|
|
181
|
+
streak.carry += dt * pace / STREAK_PACE;
|
|
182
|
+
while (streak.carry >= 1 && streak.left > 0) {
|
|
183
|
+
streak.carry -= 1;
|
|
184
|
+
streak.left -= 1;
|
|
185
|
+
streak.index += 1;
|
|
186
|
+
if (streak.index % cols === 0 || streak.index >= total) {
|
|
187
|
+
streak.left = 0;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
ignite(streak.index, streak.flare);
|
|
191
|
+
}
|
|
192
|
+
if (streak.left <= 0) streaks.splice(s, 1);
|
|
193
|
+
}
|
|
194
|
+
for (const index of active) {
|
|
195
|
+
const flare = flares[index];
|
|
196
|
+
if (!flare) {
|
|
197
|
+
active.delete(index);
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
if (flare.hold > 0) flare.hold -= dt;
|
|
201
|
+
else heats[index] = (heats[index] ?? 0) * Math.exp(-dt * 4 / flare.fade);
|
|
202
|
+
const heat = heats[index] ?? 0;
|
|
203
|
+
if (heat < .012 && flare.hold <= 0) {
|
|
204
|
+
heats[index] = 0;
|
|
205
|
+
active.delete(index);
|
|
206
|
+
} else if (Math.random() < heat * dt * 12) cells[index] = randomGlyph(pool);
|
|
207
|
+
dirty.add(index);
|
|
208
|
+
}
|
|
209
|
+
for (const index of dirty) drawCell(index);
|
|
210
|
+
dirty.clear();
|
|
211
|
+
};
|
|
212
|
+
const settle = () => {
|
|
213
|
+
for (const index of active) {
|
|
214
|
+
heats[index] = 0;
|
|
215
|
+
drawCell(index);
|
|
216
|
+
}
|
|
217
|
+
active.clear();
|
|
218
|
+
streaks.length = 0;
|
|
219
|
+
};
|
|
220
|
+
const tick = (time) => {
|
|
221
|
+
frame = requestAnimationFrame(tick);
|
|
222
|
+
const dt = last ? Math.min(.05, (time - last) / 1e3) : 0;
|
|
223
|
+
last = time;
|
|
224
|
+
if (!visible || dt === 0) return;
|
|
225
|
+
styleCheck -= dt;
|
|
226
|
+
if (styleCheck <= 0) {
|
|
227
|
+
styleCheck = STYLE_CHECK;
|
|
228
|
+
syncStyle();
|
|
229
|
+
}
|
|
230
|
+
if (reducedMotion.matches) {
|
|
231
|
+
if (active.size > 0) settle();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
update(dt);
|
|
235
|
+
};
|
|
236
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
237
|
+
if (font) build();
|
|
238
|
+
else syncStyle();
|
|
239
|
+
});
|
|
240
|
+
resizeObserver.observe(canvas);
|
|
241
|
+
const intersectionObserver = new IntersectionObserver(([entry]) => {
|
|
242
|
+
if (entry) visible = entry.isIntersecting;
|
|
243
|
+
});
|
|
244
|
+
intersectionObserver.observe(canvas);
|
|
245
|
+
frame = requestAnimationFrame(tick);
|
|
246
|
+
return () => {
|
|
247
|
+
disposed = true;
|
|
248
|
+
cancelAnimationFrame(frame);
|
|
249
|
+
resizeObserver.disconnect();
|
|
250
|
+
intersectionObserver.disconnect();
|
|
251
|
+
};
|
|
252
|
+
}, [
|
|
253
|
+
glyphs,
|
|
254
|
+
speed,
|
|
255
|
+
glitch
|
|
256
|
+
]);
|
|
257
|
+
return /* @__PURE__ */ jsx("canvas", {
|
|
258
|
+
ref: mergedRef,
|
|
259
|
+
"data-slot": "glyph-matrix",
|
|
260
|
+
"aria-hidden": "true",
|
|
261
|
+
className: cn("text-contrast accent-accent font-mono text-sm pointer-events-none block size-full", className),
|
|
262
|
+
...props
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
//#endregion
|
|
266
|
+
export { GlyphMatrix };
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
-
|
|
3
1
|
//#region src/gradient-reveal-text.d.ts
|
|
4
2
|
interface GradientRevealTextProps {
|
|
5
3
|
/** The text to display */
|
|
6
4
|
text: string;
|
|
7
5
|
/** Spotlight follow speed in seconds. Default: 0 (instant) */
|
|
8
6
|
duration?: number;
|
|
9
|
-
/** Gradient colors for the reveal effect. Default: rainbow */
|
|
7
|
+
/** Gradient colors for the reveal effect, any CSS color (`var(--wave-teal-400)` too). Default: rainbow */
|
|
10
8
|
colors?: string[];
|
|
11
9
|
/** Base stroke opacity when not hovered. Default: 0.3 */
|
|
12
10
|
baseOpacity?: number;
|
|
@@ -18,7 +16,7 @@ interface GradientRevealTextProps {
|
|
|
18
16
|
spotlightSize?: number;
|
|
19
17
|
/** Stroke width in px. Default: auto (1.5% of text height) */
|
|
20
18
|
strokeWidth?: number;
|
|
21
|
-
/** Base stroke color. Default:
|
|
19
|
+
/** Base stroke color. Default: the `contour` token, so it follows the theme */
|
|
22
20
|
baseColor?: string;
|
|
23
21
|
className?: string;
|
|
24
22
|
}
|
|
@@ -32,20 +30,9 @@ interface GradientRevealTextProps {
|
|
|
32
30
|
* @example
|
|
33
31
|
* ```tsx
|
|
34
32
|
* <GradientRevealText text="HELLO" />
|
|
35
|
-
* <GradientRevealText text="BRAND" colors={["
|
|
33
|
+
* <GradientRevealText text="BRAND" colors={["var(--wave-red-400)", "var(--wave-green-400)"]} />
|
|
36
34
|
* ```
|
|
37
35
|
*/
|
|
38
|
-
declare function GradientRevealText({
|
|
39
|
-
text,
|
|
40
|
-
duration,
|
|
41
|
-
colors,
|
|
42
|
-
baseOpacity,
|
|
43
|
-
hoverOpacity,
|
|
44
|
-
fontFamily,
|
|
45
|
-
spotlightSize,
|
|
46
|
-
strokeWidth: strokeWidthPx,
|
|
47
|
-
baseColor,
|
|
48
|
-
className
|
|
49
|
-
}: GradientRevealTextProps): _$react_jsx_runtime0.JSX.Element;
|
|
36
|
+
declare function GradientRevealText({ text, duration, colors, baseOpacity, hoverOpacity, fontFamily, spotlightSize, strokeWidth: strokeWidthPx, baseColor, className }: GradientRevealTextProps): import("react").JSX.Element;
|
|
50
37
|
//#endregion
|
|
51
38
|
export { GradientRevealText, type GradientRevealTextProps };
|
|
@@ -4,11 +4,11 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
import { useCallback, useEffect, useId, useRef, useState } from "react";
|
|
5
5
|
//#region src/gradient-reveal-text.tsx
|
|
6
6
|
const DEFAULT_COLORS = [
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
7
|
+
"var(--wave-yellow-400)",
|
|
8
|
+
"var(--wave-red-400)",
|
|
9
|
+
"var(--wave-blue-400)",
|
|
10
|
+
"var(--wave-teal-400)",
|
|
11
|
+
"var(--wave-purple-400)"
|
|
12
12
|
];
|
|
13
13
|
/**
|
|
14
14
|
* Large decorative text with a gradient spotlight that follows the cursor.
|
|
@@ -20,7 +20,7 @@ const DEFAULT_COLORS = [
|
|
|
20
20
|
* @example
|
|
21
21
|
* ```tsx
|
|
22
22
|
* <GradientRevealText text="HELLO" />
|
|
23
|
-
* <GradientRevealText text="BRAND" colors={["
|
|
23
|
+
* <GradientRevealText text="BRAND" colors={["var(--wave-red-400)", "var(--wave-green-400)"]} />
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
26
|
function GradientRevealText({ text, duration = 0, colors = DEFAULT_COLORS, baseOpacity = .3, hoverOpacity = .7, fontFamily = "Helvetica Neue, Helvetica, Arial, sans-serif", spotlightSize = .6, strokeWidth: strokeWidthPx, baseColor, className }) {
|
|
@@ -188,7 +188,7 @@ function GradientRevealText({ text, duration = 0, colors = DEFAULT_COLORS, baseO
|
|
|
188
188
|
y2: "0%",
|
|
189
189
|
children: hovered && stops.map((s) => /* @__PURE__ */ jsx("stop", {
|
|
190
190
|
offset: s.offset,
|
|
191
|
-
stopColor: s.color
|
|
191
|
+
style: { stopColor: s.color }
|
|
192
192
|
}, s.offset))
|
|
193
193
|
}),
|
|
194
194
|
/* @__PURE__ */ jsxs("radialGradient", {
|
|
@@ -236,7 +236,7 @@ function GradientRevealText({ text, duration = 0, colors = DEFAULT_COLORS, baseO
|
|
|
236
236
|
y: "50%",
|
|
237
237
|
textAnchor: "middle",
|
|
238
238
|
dominantBaseline: "central",
|
|
239
|
-
className: baseColor ? "font-bold" : "font-bold stroke-
|
|
239
|
+
className: baseColor ? "font-bold" : "font-bold stroke-contour",
|
|
240
240
|
style: {
|
|
241
241
|
...textStyle,
|
|
242
242
|
...baseColor ? { stroke: baseColor } : {},
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
1
|
import * as React from "react";
|
|
3
|
-
|
|
4
2
|
//#region src/infinite-scroll.d.ts
|
|
5
3
|
type InfiniteScrollProps = React.ComponentProps<"div"> & {
|
|
6
4
|
onLoadMore: () => void;
|
|
@@ -13,19 +11,6 @@ type InfiniteScrollProps = React.ComponentProps<"div"> & {
|
|
|
13
11
|
loader?: React.ReactNode;
|
|
14
12
|
endMessage?: React.ReactNode;
|
|
15
13
|
};
|
|
16
|
-
declare function InfiniteScroll({
|
|
17
|
-
onLoadMore,
|
|
18
|
-
hasMore,
|
|
19
|
-
isLoading,
|
|
20
|
-
direction,
|
|
21
|
-
root,
|
|
22
|
-
rootMargin,
|
|
23
|
-
threshold,
|
|
24
|
-
loader,
|
|
25
|
-
endMessage,
|
|
26
|
-
className,
|
|
27
|
-
children,
|
|
28
|
-
...props
|
|
29
|
-
}: InfiniteScrollProps): _$react_jsx_runtime0.JSX.Element;
|
|
14
|
+
declare function InfiniteScroll({ onLoadMore, hasMore, isLoading, direction, root, rootMargin, threshold, loader, endMessage, className, children, ...props }: InfiniteScrollProps): React.JSX.Element;
|
|
30
15
|
//#endregion
|
|
31
16
|
export { InfiniteScroll, type InfiniteScrollProps };
|
package/dist/input-group.d.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { Button } from "./button.js";
|
|
2
2
|
import { Input } from "./input.js";
|
|
3
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
3
|
import * as React from "react";
|
|
5
4
|
import { VariantProps } from "class-variance-authority";
|
|
6
|
-
import * as _$class_variance_authority_types0 from "class-variance-authority/types";
|
|
7
|
-
|
|
8
5
|
//#region src/input-group.d.ts
|
|
9
6
|
declare const inputGroupVariants: (props?: ({
|
|
10
|
-
size?: "default" | "
|
|
11
|
-
} &
|
|
7
|
+
size?: "default" | "lg" | "sm" | "xs" | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
12
9
|
type InputGroupProps = React.ComponentProps<"div"> & VariantProps<typeof inputGroupVariants>;
|
|
13
10
|
type InputGroupAddonProps = React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>;
|
|
14
11
|
type InputGroupButtonProps = Omit<React.ComponentProps<typeof Button>, "size" | "type"> & VariantProps<typeof inputGroupButtonVariants> & {
|
|
@@ -17,40 +14,17 @@ type InputGroupButtonProps = Omit<React.ComponentProps<typeof Button>, "size" |
|
|
|
17
14
|
type InputGroupTextProps = React.ComponentProps<"span">;
|
|
18
15
|
type InputGroupInputProps = React.ComponentProps<typeof Input>;
|
|
19
16
|
type InputGroupTextareaProps = React.ComponentProps<"textarea">;
|
|
20
|
-
declare function InputGroup({
|
|
21
|
-
className,
|
|
22
|
-
size,
|
|
23
|
-
...props
|
|
24
|
-
}: InputGroupProps): _$react_jsx_runtime0.JSX.Element;
|
|
17
|
+
declare function InputGroup({ className, size, ...props }: InputGroupProps): React.JSX.Element;
|
|
25
18
|
declare const inputGroupAddonVariants: (props?: ({
|
|
26
|
-
align?: "
|
|
27
|
-
} &
|
|
28
|
-
declare function InputGroupAddon({
|
|
29
|
-
className,
|
|
30
|
-
align,
|
|
31
|
-
...props
|
|
32
|
-
}: InputGroupAddonProps): _$react_jsx_runtime0.JSX.Element;
|
|
19
|
+
align?: "block-end" | "block-start" | "inline-end" | "inline-start" | null | undefined;
|
|
20
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
21
|
+
declare function InputGroupAddon({ className, align, ...props }: InputGroupAddonProps): React.JSX.Element;
|
|
33
22
|
declare const inputGroupButtonVariants: (props?: ({
|
|
34
23
|
size?: "default" | "icon" | null | undefined;
|
|
35
|
-
} &
|
|
36
|
-
declare function InputGroupButton({
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
size,
|
|
41
|
-
...props
|
|
42
|
-
}: InputGroupButtonProps): _$react_jsx_runtime0.JSX.Element;
|
|
43
|
-
declare function InputGroupText({
|
|
44
|
-
className,
|
|
45
|
-
...props
|
|
46
|
-
}: InputGroupTextProps): _$react_jsx_runtime0.JSX.Element;
|
|
47
|
-
declare function InputGroupInput({
|
|
48
|
-
className,
|
|
49
|
-
...props
|
|
50
|
-
}: InputGroupInputProps): _$react_jsx_runtime0.JSX.Element;
|
|
51
|
-
declare function InputGroupTextarea({
|
|
52
|
-
className,
|
|
53
|
-
...props
|
|
54
|
-
}: InputGroupTextareaProps): _$react_jsx_runtime0.JSX.Element;
|
|
24
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
25
|
+
declare function InputGroupButton({ className, type, variant, size, ...props }: InputGroupButtonProps): React.JSX.Element;
|
|
26
|
+
declare function InputGroupText({ className, ...props }: InputGroupTextProps): React.JSX.Element;
|
|
27
|
+
declare function InputGroupInput({ className, ...props }: InputGroupInputProps): React.JSX.Element;
|
|
28
|
+
declare function InputGroupTextarea({ className, ...props }: InputGroupTextareaProps): React.JSX.Element;
|
|
55
29
|
//#endregion
|
|
56
30
|
export { InputGroup, InputGroupAddon, type InputGroupAddonProps, InputGroupButton, type InputGroupButtonProps, InputGroupInput, type InputGroupInputProps, type InputGroupProps, InputGroupText, type InputGroupTextProps, InputGroupTextarea, type InputGroupTextareaProps, inputGroupAddonVariants, inputGroupButtonVariants, inputGroupVariants };
|
package/dist/input-group.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Textarea } from "./textarea.js";
|
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
8
8
|
//#region src/input-group.tsx
|
|
9
|
-
const inputGroupVariants = cva("bg-
|
|
9
|
+
const inputGroupVariants = cva("bg-shade hover:border-focus has-[[data-slot=input-group-control]:focus-visible]:border-focus has-[[data-slot=input-group-control]:focus-visible]:ring-focus/50 has-[[data-slot][aria-invalid=true]]:ring-danger/30 has-[[data-slot][aria-invalid=true]]:border-danger group/input-group relative flex w-full min-w-0 items-center rounded-md border border-transparent motion-color outline-hidden in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:pointer-events-none has-disabled:opacity-30 not-has-disabled:has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3", {
|
|
10
10
|
variants: { size: {
|
|
11
11
|
xs: "h-6 rounded-sm",
|
|
12
12
|
sm: "h-8",
|
package/dist/input-otp.d.ts
CHANGED
|
@@ -1,33 +1,17 @@
|
|
|
1
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import { OTPInput } from "input-otp";
|
|
4
|
-
|
|
5
3
|
//#region src/input-otp.d.ts
|
|
6
4
|
type InputOTPProps = React.ComponentProps<typeof OTPInput> & {
|
|
7
5
|
containerClassName?: string;
|
|
8
6
|
};
|
|
9
|
-
declare function InputOTP({
|
|
10
|
-
className,
|
|
11
|
-
containerClassName,
|
|
12
|
-
...props
|
|
13
|
-
}: InputOTPProps): _$react_jsx_runtime0.JSX.Element;
|
|
14
7
|
type InputOTPGroupProps = React.ComponentProps<"div">;
|
|
15
|
-
declare function InputOTPGroup({
|
|
16
|
-
className,
|
|
17
|
-
...props
|
|
18
|
-
}: InputOTPGroupProps): _$react_jsx_runtime0.JSX.Element;
|
|
19
8
|
type InputOTPSlotProps = React.ComponentProps<"div"> & {
|
|
20
9
|
index: number;
|
|
21
10
|
};
|
|
22
|
-
declare function InputOTPSlot({
|
|
23
|
-
index,
|
|
24
|
-
className,
|
|
25
|
-
...props
|
|
26
|
-
}: InputOTPSlotProps): _$react_jsx_runtime0.JSX.Element;
|
|
27
11
|
type InputOTPSeparatorProps = React.ComponentProps<"div">;
|
|
28
|
-
declare function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}: InputOTPSeparatorProps):
|
|
12
|
+
declare function InputOTP({ className, containerClassName, ...props }: InputOTPProps): React.JSX.Element;
|
|
13
|
+
declare function InputOTPGroup({ className, ...props }: InputOTPGroupProps): React.JSX.Element;
|
|
14
|
+
declare function InputOTPSlot({ index, className, ...props }: InputOTPSlotProps): React.JSX.Element;
|
|
15
|
+
declare function InputOTPSeparator({ className, ...props }: InputOTPSeparatorProps): React.JSX.Element;
|
|
32
16
|
//#endregion
|
|
33
17
|
export { InputOTP, InputOTPGroup, type InputOTPGroupProps, type InputOTPProps, InputOTPSeparator, type InputOTPSeparatorProps, InputOTPSlot, type InputOTPSlotProps };
|