@carbonbits/sixr 1.4.0 → 1.5.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 +139 -60
- package/dist/button.cjs +223 -0
- package/dist/button.cjs.map +1 -0
- package/dist/button.d.cts +34 -0
- package/dist/button.d.ts +34 -0
- package/dist/button.js +4 -0
- package/dist/button.js.map +1 -0
- package/dist/chunk-HDTW4FRT.js +111 -0
- package/dist/chunk-HDTW4FRT.js.map +1 -0
- package/dist/email-input.cjs +213 -170
- package/dist/email-input.cjs.map +1 -1
- package/dist/email-input.d.cts +4 -6
- package/dist/email-input.d.ts +4 -6
- package/dist/email-input.js +219 -170
- package/dist/email-input.js.map +1 -1
- package/dist/field.cjs +206 -0
- package/dist/field.cjs.map +1 -0
- package/dist/field.d.cts +80 -0
- package/dist/field.d.ts +80 -0
- package/dist/field.js +186 -0
- package/dist/field.js.map +1 -0
- package/dist/form.cjs +283 -42
- package/dist/form.cjs.map +1 -1
- package/dist/form.d.cts +79 -10
- package/dist/form.d.ts +79 -10
- package/dist/form.js +285 -45
- package/dist/form.js.map +1 -1
- package/dist/index-CdYkd6zz.d.cts +22 -0
- package/dist/index-CdYkd6zz.d.ts +22 -0
- package/dist/index.cjs +138 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +116 -55
- package/dist/index.d.ts +116 -55
- package/dist/index.js +1 -0
- package/dist/password-input.cjs +217 -174
- package/dist/password-input.cjs.map +1 -1
- package/dist/password-input.d.cts +2 -3
- package/dist/password-input.d.ts +2 -3
- package/dist/password-input.js +222 -173
- package/dist/password-input.js.map +1 -1
- package/dist/phone-input.cjs +213 -170
- package/dist/phone-input.cjs.map +1 -1
- package/dist/phone-input.d.cts +5 -5
- package/dist/phone-input.d.ts +5 -5
- package/dist/phone-input.js +219 -170
- package/dist/phone-input.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/text-input.cjs +213 -170
- package/dist/text-input.cjs.map +1 -1
- package/dist/text-input.d.cts +2 -3
- package/dist/text-input.d.ts +2 -3
- package/dist/text-input.js +219 -170
- package/dist/text-input.js.map +1 -1
- package/package.json +26 -2
- package/dist/index-DwjxC4l4.d.cts +0 -62
- package/dist/index-DwjxC4l4.d.ts +0 -62
package/dist/field.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// src/components/field/index.tsx
|
|
5
|
+
import { Label } from "@radix-ui/react-label";
|
|
6
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
7
|
+
import {
|
|
8
|
+
createContext,
|
|
9
|
+
useContext,
|
|
10
|
+
useEffect,
|
|
11
|
+
useId,
|
|
12
|
+
useState
|
|
13
|
+
} from "react";
|
|
14
|
+
import {
|
|
15
|
+
useController,
|
|
16
|
+
useFormContext
|
|
17
|
+
} from "react-hook-form";
|
|
18
|
+
import { jsx } from "react/jsx-runtime";
|
|
19
|
+
var FieldContext = createContext(null);
|
|
20
|
+
function useFieldContext() {
|
|
21
|
+
const context = useContext(FieldContext);
|
|
22
|
+
if (!context) {
|
|
23
|
+
throw new Error("Field primitives must be rendered inside FieldRoot");
|
|
24
|
+
}
|
|
25
|
+
return context;
|
|
26
|
+
}
|
|
27
|
+
function useFieldIds(id) {
|
|
28
|
+
const generated = useId();
|
|
29
|
+
const base = id ?? generated;
|
|
30
|
+
return {
|
|
31
|
+
id: base,
|
|
32
|
+
descriptionId: `${base}-description`,
|
|
33
|
+
messageId: `${base}-message`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function FieldShell({
|
|
37
|
+
value,
|
|
38
|
+
asChild = false,
|
|
39
|
+
children,
|
|
40
|
+
...rest
|
|
41
|
+
}) {
|
|
42
|
+
const [hasDescription, setHasDescription] = useState(false);
|
|
43
|
+
const Component = asChild ? Slot : "div";
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
FieldContext.Provider,
|
|
46
|
+
{
|
|
47
|
+
value: { ...value, hasDescription, setHasDescription },
|
|
48
|
+
children: /* @__PURE__ */ jsx(
|
|
49
|
+
Component,
|
|
50
|
+
{
|
|
51
|
+
...rest,
|
|
52
|
+
"data-invalid": value.invalid ? "" : void 0,
|
|
53
|
+
"data-disabled": value.disabled ? "" : void 0,
|
|
54
|
+
children
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function ConnectedFieldRoot({
|
|
61
|
+
name,
|
|
62
|
+
error,
|
|
63
|
+
required = false,
|
|
64
|
+
disabled = false,
|
|
65
|
+
id,
|
|
66
|
+
...rest
|
|
67
|
+
}) {
|
|
68
|
+
const ids = useFieldIds(id);
|
|
69
|
+
const { field, fieldState } = useController({ name, disabled });
|
|
70
|
+
const shownError = error ?? fieldState.error?.message;
|
|
71
|
+
return /* @__PURE__ */ jsx(
|
|
72
|
+
FieldShell,
|
|
73
|
+
{
|
|
74
|
+
...rest,
|
|
75
|
+
value: {
|
|
76
|
+
...ids,
|
|
77
|
+
name,
|
|
78
|
+
error: shownError,
|
|
79
|
+
invalid: Boolean(shownError),
|
|
80
|
+
required,
|
|
81
|
+
disabled: Boolean(field.disabled ?? disabled),
|
|
82
|
+
bindings: {
|
|
83
|
+
name: field.name,
|
|
84
|
+
value: field.value ?? "",
|
|
85
|
+
onChange: field.onChange,
|
|
86
|
+
onBlur: field.onBlur,
|
|
87
|
+
ref: field.ref
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function StandaloneFieldRoot({
|
|
94
|
+
name,
|
|
95
|
+
error,
|
|
96
|
+
required = false,
|
|
97
|
+
disabled = false,
|
|
98
|
+
id,
|
|
99
|
+
...rest
|
|
100
|
+
}) {
|
|
101
|
+
const ids = useFieldIds(id);
|
|
102
|
+
return /* @__PURE__ */ jsx(
|
|
103
|
+
FieldShell,
|
|
104
|
+
{
|
|
105
|
+
...rest,
|
|
106
|
+
value: {
|
|
107
|
+
...ids,
|
|
108
|
+
name,
|
|
109
|
+
error,
|
|
110
|
+
invalid: Boolean(error),
|
|
111
|
+
required,
|
|
112
|
+
disabled,
|
|
113
|
+
bindings: { name }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
function FieldRoot(props) {
|
|
119
|
+
const form = useFormContext();
|
|
120
|
+
return form ? /* @__PURE__ */ jsx(ConnectedFieldRoot, { ...props }) : /* @__PURE__ */ jsx(StandaloneFieldRoot, { ...props });
|
|
121
|
+
}
|
|
122
|
+
function FieldLabel(props) {
|
|
123
|
+
const { id } = useFieldContext();
|
|
124
|
+
return /* @__PURE__ */ jsx(Label, { ...props, htmlFor: id });
|
|
125
|
+
}
|
|
126
|
+
function describedBy({
|
|
127
|
+
error,
|
|
128
|
+
messageId,
|
|
129
|
+
hasDescription,
|
|
130
|
+
descriptionId
|
|
131
|
+
}) {
|
|
132
|
+
if (error) {
|
|
133
|
+
return messageId;
|
|
134
|
+
}
|
|
135
|
+
return hasDescription ? descriptionId : void 0;
|
|
136
|
+
}
|
|
137
|
+
function FieldControl(props) {
|
|
138
|
+
const context = useFieldContext();
|
|
139
|
+
const { id, invalid, required, disabled, bindings } = context;
|
|
140
|
+
const controlProps = {
|
|
141
|
+
...bindings,
|
|
142
|
+
id,
|
|
143
|
+
"aria-invalid": invalid || void 0,
|
|
144
|
+
"aria-required": required || void 0,
|
|
145
|
+
"aria-describedby": describedBy(context),
|
|
146
|
+
disabled: disabled || void 0
|
|
147
|
+
};
|
|
148
|
+
return /* @__PURE__ */ jsx(Slot, { ...props, ...controlProps });
|
|
149
|
+
}
|
|
150
|
+
function FieldDescription({
|
|
151
|
+
asChild = false,
|
|
152
|
+
...props
|
|
153
|
+
}) {
|
|
154
|
+
const { descriptionId, error, setHasDescription } = useFieldContext();
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
setHasDescription(true);
|
|
157
|
+
return () => setHasDescription(false);
|
|
158
|
+
}, [setHasDescription]);
|
|
159
|
+
if (error) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const Component = asChild ? Slot : "p";
|
|
163
|
+
return /* @__PURE__ */ jsx(Component, { ...props, id: descriptionId });
|
|
164
|
+
}
|
|
165
|
+
function FieldMessage({
|
|
166
|
+
asChild = false,
|
|
167
|
+
children,
|
|
168
|
+
...props
|
|
169
|
+
}) {
|
|
170
|
+
const { messageId, error } = useFieldContext();
|
|
171
|
+
const content = error ?? children;
|
|
172
|
+
if (!content) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const Component = asChild ? Slot : "p";
|
|
176
|
+
return /* @__PURE__ */ jsx(Component, { ...props, id: messageId, role: "alert", children: content });
|
|
177
|
+
}
|
|
178
|
+
export {
|
|
179
|
+
FieldControl,
|
|
180
|
+
FieldDescription,
|
|
181
|
+
FieldLabel,
|
|
182
|
+
FieldMessage,
|
|
183
|
+
FieldRoot,
|
|
184
|
+
useFieldContext
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/field/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { Label } from \"@radix-ui/react-label\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n type ComponentPropsWithoutRef,\n createContext,\n type ReactNode,\n useContext,\n useEffect,\n useId,\n useState,\n} from \"react\";\nimport {\n type FieldValues,\n type UseFormReturn,\n useController,\n useFormContext,\n} from \"react-hook-form\";\n\n/**\n * The structure behind every form field, with no styling of its own: an id\n * shared by label and control, the error and description ids the control is\n * described by, the field's validity, and — inside a `Form` — the\n * react-hook-form bindings (`value`, `onChange`, `onBlur`, `ref`) that keep\n * the control registered.\n *\n * Styled components compose these primitives with their own classes\n * (`TextInput` and friends do), and a screen that needs a control the\n * library does not ship — a select, a code entry, a toggle — composes them\n * the same way. Everything here is a plain element or a Radix `Slot`, so the\n * styling decisions stay with whoever renders the field.\n *\n * Outside a `Form` the primitives still wire label, control and messages\n * together; the control just isn't registered anywhere and the error comes\n * from the `error` prop alone.\n */\n\nexport type FieldBindings = {\n name: string;\n value?: unknown;\n onChange?: (event: unknown) => void;\n onBlur?: () => void;\n ref?: (instance: HTMLElement | null) => void;\n};\n\nexport type FieldContextValue = {\n id: string;\n name: string;\n descriptionId: string;\n messageId: string;\n error: string | undefined;\n invalid: boolean;\n required: boolean;\n disabled: boolean;\n hasDescription: boolean;\n setHasDescription: (present: boolean) => void;\n bindings: FieldBindings;\n};\n\nconst FieldContext = createContext<FieldContextValue | null>(null);\n\n// biome-ignore lint/style/useComponentExportOnlyModules: the hook is the primitives' public API for custom compositions and belongs on the same subpath.\nexport function useFieldContext(): FieldContextValue {\n const context = useContext(FieldContext);\n\n if (!context) {\n throw new Error(\"Field primitives must be rendered inside FieldRoot\");\n }\n\n return context;\n}\n\nexport type FieldRootProps = ComponentPropsWithoutRef<\"div\"> & {\n /** The form field this wires up — the key in the `Form`'s values. */\n name: string;\n /** A caller-supplied error. Outranks whatever the form's schema reports. */\n error?: string;\n required?: boolean;\n disabled?: boolean;\n /** Render the child element as the root instead of a `div`. */\n asChild?: boolean;\n children: ReactNode;\n};\n\ntype FieldShellProps = Omit<\n FieldRootProps,\n \"name\" | \"error\" | \"required\" | \"disabled\"\n> & {\n value: Omit<FieldContextValue, \"hasDescription\" | \"setHasDescription\">;\n};\n\nfunction useFieldIds(id: string | undefined) {\n const generated = useId();\n const base = id ?? generated;\n\n return {\n id: base,\n descriptionId: `${base}-description`,\n messageId: `${base}-message`,\n };\n}\n\nfunction FieldShell({\n value,\n asChild = false,\n children,\n ...rest\n}: FieldShellProps) {\n const [hasDescription, setHasDescription] = useState(false);\n const Component = asChild ? Slot : \"div\";\n\n return (\n <FieldContext.Provider\n value={{ ...value, hasDescription, setHasDescription }}\n >\n <Component\n {...rest}\n data-invalid={value.invalid ? \"\" : undefined}\n data-disabled={value.disabled ? \"\" : undefined}\n >\n {children}\n </Component>\n </FieldContext.Provider>\n );\n}\n\nfunction ConnectedFieldRoot({\n name,\n error,\n required = false,\n disabled = false,\n id,\n ...rest\n}: FieldRootProps) {\n const ids = useFieldIds(id);\n const { field, fieldState } = useController({ name, disabled });\n const shownError = error ?? fieldState.error?.message;\n\n return (\n <FieldShell\n {...rest}\n value={{\n ...ids,\n name,\n error: shownError,\n invalid: Boolean(shownError),\n required,\n disabled: Boolean(field.disabled ?? disabled),\n bindings: {\n name: field.name,\n value: field.value ?? \"\",\n onChange: field.onChange,\n onBlur: field.onBlur,\n ref: field.ref,\n },\n }}\n />\n );\n}\n\nfunction StandaloneFieldRoot({\n name,\n error,\n required = false,\n disabled = false,\n id,\n ...rest\n}: FieldRootProps) {\n const ids = useFieldIds(id);\n\n return (\n <FieldShell\n {...rest}\n value={{\n ...ids,\n name,\n error,\n invalid: Boolean(error),\n required,\n disabled,\n bindings: { name },\n }}\n />\n );\n}\n\nexport function FieldRoot(props: FieldRootProps) {\n const form = useFormContext() as UseFormReturn<FieldValues> | null;\n\n return form ? (\n <ConnectedFieldRoot {...props} />\n ) : (\n <StandaloneFieldRoot {...props} />\n );\n}\n\nexport type FieldLabelProps = ComponentPropsWithoutRef<typeof Label>;\n\nexport function FieldLabel(props: FieldLabelProps) {\n const { id } = useFieldContext();\n\n return <Label {...props} htmlFor={id} />;\n}\n\nexport type FieldControlProps = ComponentPropsWithoutRef<typeof Slot>;\n\nfunction describedBy({\n error,\n messageId,\n hasDescription,\n descriptionId,\n}: Pick<\n FieldContextValue,\n \"error\" | \"messageId\" | \"hasDescription\" | \"descriptionId\"\n>): string | undefined {\n if (error) {\n return messageId;\n }\n\n return hasDescription ? descriptionId : undefined;\n}\n\n/**\n * Wires the field's id, name, validity and bindings onto whatever element it\n * wraps — an `<input>`, a `<select>`, a `<textarea>`, a custom control.\n * Handlers on the child still run; the bindings run after them.\n */\nexport function FieldControl(props: FieldControlProps) {\n const context = useFieldContext();\n const { id, invalid, required, disabled, bindings } = context;\n\n // `disabled` is not on Slot's HTMLAttributes type, but it is what the\n // wrapped control needs, so the bindings are spread untyped on purpose.\n const controlProps: Record<string, unknown> = {\n ...bindings,\n id,\n \"aria-invalid\": invalid || undefined,\n \"aria-required\": required || undefined,\n \"aria-describedby\": describedBy(context),\n disabled: disabled || undefined,\n };\n\n return <Slot {...props} {...controlProps} />;\n}\n\nexport type FieldDescriptionProps = ComponentPropsWithoutRef<\"p\"> & {\n asChild?: boolean;\n};\n\n/** Guidance under the control. Hidden while the field has an error. */\nexport function FieldDescription({\n asChild = false,\n ...props\n}: FieldDescriptionProps) {\n const { descriptionId, error, setHasDescription } = useFieldContext();\n\n useEffect(() => {\n setHasDescription(true);\n\n return () => setHasDescription(false);\n }, [setHasDescription]);\n\n if (error) {\n return null;\n }\n\n const Component = asChild ? Slot : \"p\";\n\n return <Component {...props} id={descriptionId} />;\n}\n\nexport type FieldMessageProps = ComponentPropsWithoutRef<\"p\"> & {\n asChild?: boolean;\n};\n\n/**\n * The field's error, announced as an alert. Renders the error the field\n * currently holds; `children` is a fallback for a message the caller wants to\n * show in its place. Nothing renders while the field is valid.\n */\nexport function FieldMessage({\n asChild = false,\n children,\n ...props\n}: FieldMessageProps) {\n const { messageId, error } = useFieldContext();\n const content = error ?? children;\n\n if (!content) {\n return null;\n }\n\n const Component = asChild ? Slot : \"p\";\n\n return (\n <Component {...props} id={messageId} role=\"alert\">\n {content}\n </Component>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/form.cjs
CHANGED
|
@@ -24,54 +24,172 @@ var form_exports = {};
|
|
|
24
24
|
__export(form_exports, {
|
|
25
25
|
Form: () => Form,
|
|
26
26
|
FormError: () => FormError,
|
|
27
|
-
SubmitButton: () => SubmitButton
|
|
27
|
+
SubmitButton: () => SubmitButton,
|
|
28
|
+
useFormInstance: () => useFormInstance
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(form_exports);
|
|
30
|
-
var
|
|
31
|
+
var import_standard_schema = require("@hookform/resolvers/standard-schema");
|
|
32
|
+
var import_react_hook_form = require("react-hook-form");
|
|
33
|
+
|
|
34
|
+
// src/components/button/index.tsx
|
|
35
|
+
var import_react_slot2 = require("@radix-ui/react-slot");
|
|
36
|
+
|
|
37
|
+
// src/components/typography/index.tsx
|
|
38
|
+
var import_react_slot = require("@radix-ui/react-slot");
|
|
31
39
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
var DEFAULT_ELEMENT = {
|
|
41
|
+
display: "h1",
|
|
42
|
+
heading: "h2",
|
|
43
|
+
subheading: "h3",
|
|
44
|
+
body: "p",
|
|
45
|
+
label: "span",
|
|
46
|
+
hint: "p",
|
|
47
|
+
code: "code"
|
|
48
|
+
};
|
|
49
|
+
var DEFAULT_WEIGHT = {
|
|
50
|
+
display: "semibold",
|
|
51
|
+
heading: "semibold",
|
|
52
|
+
subheading: "medium",
|
|
53
|
+
body: "regular",
|
|
54
|
+
label: "semibold",
|
|
55
|
+
hint: "regular",
|
|
56
|
+
code: "regular"
|
|
57
|
+
};
|
|
58
|
+
var VARIANT_CLASSES = {
|
|
59
|
+
display: "text-display leading-tight tracking-tight",
|
|
60
|
+
heading: "text-heading leading-tight tracking-tight",
|
|
61
|
+
subheading: "text-subheading leading-snug",
|
|
62
|
+
body: "text-field leading-normal",
|
|
63
|
+
label: "text-label leading-normal",
|
|
64
|
+
hint: "text-hint leading-normal",
|
|
65
|
+
code: "font-code text-field leading-normal"
|
|
66
|
+
};
|
|
67
|
+
var TONE_CLASSES = {
|
|
68
|
+
default: "text-fg",
|
|
69
|
+
muted: "text-fg-muted",
|
|
70
|
+
subtle: "text-fg-subtle",
|
|
71
|
+
accent: "text-accent",
|
|
72
|
+
"on-accent": "text-on-accent",
|
|
73
|
+
success: "text-success",
|
|
74
|
+
warning: "text-warning",
|
|
75
|
+
info: "text-info",
|
|
76
|
+
danger: "text-danger"
|
|
77
|
+
};
|
|
78
|
+
var WEIGHT_CLASSES = {
|
|
79
|
+
regular: "font-normal",
|
|
80
|
+
medium: "font-medium",
|
|
81
|
+
semibold: "font-semibold",
|
|
82
|
+
bold: "font-bold"
|
|
83
|
+
};
|
|
84
|
+
var ALIGN_CLASSES = {
|
|
85
|
+
start: "text-start",
|
|
86
|
+
center: "text-center",
|
|
87
|
+
end: "text-end"
|
|
88
|
+
};
|
|
89
|
+
var ICON_CLASSES = "inline-flex shrink-0 items-center [&>svg]:h-[1em] [&>svg]:w-[1em]";
|
|
90
|
+
function typographyClassName({
|
|
91
|
+
variant,
|
|
92
|
+
tone,
|
|
93
|
+
weight,
|
|
94
|
+
align,
|
|
95
|
+
truncate,
|
|
96
|
+
hasIcon,
|
|
97
|
+
className
|
|
98
|
+
}) {
|
|
99
|
+
return [
|
|
100
|
+
VARIANT_CLASSES[variant],
|
|
101
|
+
TONE_CLASSES[tone],
|
|
102
|
+
WEIGHT_CLASSES[weight],
|
|
103
|
+
align ? ALIGN_CLASSES[align] : "",
|
|
104
|
+
hasIcon ? "inline-flex items-center gap-1.5" : "",
|
|
105
|
+
// With an icon the root is a flex container, and text-overflow only
|
|
106
|
+
// clips block text, so the text span carries the truncation instead.
|
|
107
|
+
truncate && !hasIcon ? "truncate" : "",
|
|
108
|
+
className ?? ""
|
|
109
|
+
].filter(Boolean).join(" ");
|
|
110
|
+
}
|
|
111
|
+
function Typography({
|
|
112
|
+
variant = "body",
|
|
113
|
+
tone = "default",
|
|
114
|
+
weight,
|
|
115
|
+
align,
|
|
116
|
+
truncate = false,
|
|
117
|
+
icon,
|
|
118
|
+
iconPosition = "leading",
|
|
119
|
+
as,
|
|
120
|
+
asChild = false,
|
|
121
|
+
className,
|
|
122
|
+
children,
|
|
123
|
+
...rest
|
|
124
|
+
}) {
|
|
125
|
+
const hasIcon = icon !== void 0 && icon !== null;
|
|
126
|
+
const Component = asChild ? import_react_slot.Slot : as ?? DEFAULT_ELEMENT[variant];
|
|
127
|
+
const iconNode = hasIcon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", className: ICON_CLASSES, children: icon }) : null;
|
|
128
|
+
const content = hasIcon ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
129
|
+
iconPosition === "leading" ? iconNode : null,
|
|
130
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: truncate ? "min-w-0 truncate" : void 0, children }),
|
|
131
|
+
iconPosition === "trailing" ? iconNode : null
|
|
132
|
+
] }) : children;
|
|
48
133
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
49
|
-
|
|
134
|
+
Component,
|
|
50
135
|
{
|
|
51
|
-
noValidate: true,
|
|
52
136
|
...rest,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
137
|
+
className: typographyClassName({
|
|
138
|
+
variant,
|
|
139
|
+
tone,
|
|
140
|
+
weight: weight ?? DEFAULT_WEIGHT[variant],
|
|
141
|
+
align,
|
|
142
|
+
truncate,
|
|
143
|
+
hasIcon,
|
|
144
|
+
className
|
|
145
|
+
}),
|
|
146
|
+
children: content
|
|
56
147
|
}
|
|
57
148
|
);
|
|
58
149
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
150
|
+
|
|
151
|
+
// src/components/button/index.tsx
|
|
152
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
153
|
+
var BASE_CLASSES = "inline-flex shrink-0 items-center justify-center gap-2 rounded-field border font-[inherit] text-field font-semibold outline-none transition-colors focus-visible:ring-3 focus-visible:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-45";
|
|
154
|
+
var VARIANT_CLASSES2 = {
|
|
155
|
+
primary: "border-transparent bg-accent text-on-accent enabled:hover:bg-accent-2",
|
|
156
|
+
secondary: "border-line bg-surface text-fg enabled:hover:bg-surface-2",
|
|
157
|
+
ghost: "border-transparent bg-transparent text-fg enabled:hover:bg-surface-2"
|
|
158
|
+
};
|
|
159
|
+
var SIZE_CLASSES = {
|
|
160
|
+
md: "h-10 px-4",
|
|
161
|
+
lg: "h-11 px-5"
|
|
162
|
+
};
|
|
163
|
+
var LABEL_TONE = {
|
|
164
|
+
primary: "on-accent",
|
|
165
|
+
secondary: "default",
|
|
166
|
+
ghost: "default"
|
|
167
|
+
};
|
|
168
|
+
function buttonClassName({
|
|
169
|
+
variant,
|
|
170
|
+
size,
|
|
171
|
+
fullWidth,
|
|
172
|
+
className
|
|
173
|
+
}) {
|
|
174
|
+
return [
|
|
175
|
+
BASE_CLASSES,
|
|
176
|
+
VARIANT_CLASSES2[variant],
|
|
177
|
+
SIZE_CLASSES[size],
|
|
178
|
+
fullWidth ? "w-full" : "",
|
|
179
|
+
className ?? ""
|
|
180
|
+
].filter(Boolean).join(" ");
|
|
64
181
|
}
|
|
65
182
|
function Spinner() {
|
|
66
|
-
return /* @__PURE__ */ (0,
|
|
183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
67
184
|
"svg",
|
|
68
185
|
{
|
|
69
186
|
className: "h-4 w-4 animate-spin",
|
|
70
187
|
viewBox: "0 0 24 24",
|
|
71
188
|
fill: "none",
|
|
72
189
|
"aria-hidden": "true",
|
|
190
|
+
"data-testid": "button-spinner",
|
|
73
191
|
children: [
|
|
74
|
-
/* @__PURE__ */ (0,
|
|
192
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
75
193
|
"circle",
|
|
76
194
|
{
|
|
77
195
|
className: "opacity-25",
|
|
@@ -82,7 +200,7 @@ function Spinner() {
|
|
|
82
200
|
strokeWidth: "4"
|
|
83
201
|
}
|
|
84
202
|
),
|
|
85
|
-
/* @__PURE__ */ (0,
|
|
203
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
86
204
|
"path",
|
|
87
205
|
{
|
|
88
206
|
className: "opacity-75",
|
|
@@ -94,31 +212,154 @@ function Spinner() {
|
|
|
94
212
|
}
|
|
95
213
|
);
|
|
96
214
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
215
|
+
function Button({
|
|
216
|
+
variant = "primary",
|
|
217
|
+
size = "md",
|
|
218
|
+
fullWidth = false,
|
|
219
|
+
loading = false,
|
|
100
220
|
loadingLabel,
|
|
221
|
+
asChild = false,
|
|
222
|
+
type = "button",
|
|
223
|
+
disabled,
|
|
101
224
|
className,
|
|
225
|
+
children,
|
|
102
226
|
...rest
|
|
103
227
|
}) {
|
|
104
|
-
const
|
|
105
|
-
|
|
228
|
+
const classes = buttonClassName({ variant, size, fullWidth, className });
|
|
229
|
+
if (asChild) {
|
|
230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_slot2.Slot, { ...rest, className: classes, children });
|
|
231
|
+
}
|
|
232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
106
233
|
"button",
|
|
107
234
|
{
|
|
108
235
|
...rest,
|
|
109
|
-
type
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
236
|
+
type,
|
|
237
|
+
disabled: disabled || loading,
|
|
238
|
+
"aria-busy": loading || void 0,
|
|
239
|
+
className: classes,
|
|
240
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
241
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
|
|
113
242
|
loadingLabel
|
|
114
|
-
] }) :
|
|
243
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
244
|
+
Typography,
|
|
245
|
+
{
|
|
246
|
+
as: "span",
|
|
247
|
+
variant: "body",
|
|
248
|
+
weight: "semibold",
|
|
249
|
+
tone: LABEL_TONE[variant],
|
|
250
|
+
children
|
|
251
|
+
}
|
|
252
|
+
)
|
|
115
253
|
}
|
|
116
254
|
);
|
|
117
255
|
}
|
|
256
|
+
|
|
257
|
+
// src/components/form/index.tsx
|
|
258
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
259
|
+
function useFormInstance({
|
|
260
|
+
schema,
|
|
261
|
+
defaultValues,
|
|
262
|
+
mode = "onTouched"
|
|
263
|
+
}) {
|
|
264
|
+
return (0, import_react_hook_form.useForm)({
|
|
265
|
+
resolver: schema ? (0, import_standard_schema.standardSchemaResolver)(schema) : void 0,
|
|
266
|
+
defaultValues,
|
|
267
|
+
mode,
|
|
268
|
+
reValidateMode: "onChange"
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
var FORM_CLASSES = "flex flex-col gap-4";
|
|
272
|
+
var FIELDSET_CLASSES = "contents border-0 p-0 m-0 min-w-0";
|
|
273
|
+
function errorMessage(error) {
|
|
274
|
+
return error instanceof Error ? error.message : String(error);
|
|
275
|
+
}
|
|
276
|
+
function Form({
|
|
277
|
+
schema,
|
|
278
|
+
defaultValues,
|
|
279
|
+
mode,
|
|
280
|
+
onSubmit,
|
|
281
|
+
form: external,
|
|
282
|
+
children,
|
|
283
|
+
className,
|
|
284
|
+
...rest
|
|
285
|
+
}) {
|
|
286
|
+
const internal = useFormInstance({ schema, defaultValues, mode });
|
|
287
|
+
const form = external ?? internal;
|
|
288
|
+
const { isSubmitting } = form.formState;
|
|
289
|
+
const submit = form.handleSubmit(async (values) => {
|
|
290
|
+
try {
|
|
291
|
+
await onSubmit(values, form);
|
|
292
|
+
} catch (error) {
|
|
293
|
+
form.setError("root", { type: "submit", message: errorMessage(error) });
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_hook_form.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
297
|
+
"form",
|
|
298
|
+
{
|
|
299
|
+
noValidate: true,
|
|
300
|
+
...rest,
|
|
301
|
+
onSubmit: submit,
|
|
302
|
+
className: [FORM_CLASSES, className ?? ""].filter(Boolean).join(" "),
|
|
303
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("fieldset", { disabled: isSubmitting, className: FIELDSET_CLASSES, children })
|
|
304
|
+
}
|
|
305
|
+
) });
|
|
306
|
+
}
|
|
307
|
+
function FormErrorMessage({ children, className }) {
|
|
308
|
+
if (!children) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
312
|
+
Typography,
|
|
313
|
+
{
|
|
314
|
+
as: "p",
|
|
315
|
+
variant: "hint",
|
|
316
|
+
tone: "danger",
|
|
317
|
+
role: "alert",
|
|
318
|
+
className,
|
|
319
|
+
children
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
function ConnectedFormError({ children, className }) {
|
|
324
|
+
const { errors } = (0, import_react_hook_form.useFormState)();
|
|
325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FormErrorMessage, { className, children: children ?? errors.root?.message });
|
|
326
|
+
}
|
|
327
|
+
function FormError(props) {
|
|
328
|
+
const form = (0, import_react_hook_form.useFormContext)();
|
|
329
|
+
return form ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConnectedFormError, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FormErrorMessage, { ...props });
|
|
330
|
+
}
|
|
331
|
+
function ConnectedSubmitButton({
|
|
332
|
+
children,
|
|
333
|
+
loadingLabel,
|
|
334
|
+
fullWidth = true,
|
|
335
|
+
...rest
|
|
336
|
+
}) {
|
|
337
|
+
const { isSubmitting } = (0, import_react_hook_form.useFormState)();
|
|
338
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
339
|
+
Button,
|
|
340
|
+
{
|
|
341
|
+
...rest,
|
|
342
|
+
type: "submit",
|
|
343
|
+
fullWidth,
|
|
344
|
+
loading: isSubmitting,
|
|
345
|
+
loadingLabel,
|
|
346
|
+
children
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
function SubmitButton(props) {
|
|
351
|
+
const form = (0, import_react_hook_form.useFormContext)();
|
|
352
|
+
if (form) {
|
|
353
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConnectedSubmitButton, { ...props });
|
|
354
|
+
}
|
|
355
|
+
const { fullWidth = true, ...rest } = props;
|
|
356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { ...rest, type: "submit", fullWidth });
|
|
357
|
+
}
|
|
118
358
|
// Annotate the CommonJS export names for ESM import in node:
|
|
119
359
|
0 && (module.exports = {
|
|
120
360
|
Form,
|
|
121
361
|
FormError,
|
|
122
|
-
SubmitButton
|
|
362
|
+
SubmitButton,
|
|
363
|
+
useFormInstance
|
|
123
364
|
});
|
|
124
365
|
//# sourceMappingURL=form.cjs.map
|
package/dist/form.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/form/index.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ButtonHTMLAttributes,\n createContext,\n type FormHTMLAttributes,\n type ReactNode,\n type SubmitEvent,\n useCallback,\n useContext,\n useState,\n} from \"react\";\n\nconst SubmittingContext = createContext(false);\n\nexport type FormProps = Omit<\n FormHTMLAttributes<HTMLFormElement>,\n \"onSubmit\"\n> & {\n onSubmit: () => void | Promise<void>;\n children: ReactNode;\n};\n\nconst FORM_CLASSES = \"flex flex-col gap-4\";\nconst FIELDSET_CLASSES = \"contents border-0 p-0 m-0 min-w-0\";\n\nexport function Form({ onSubmit, children, className, ...rest }: FormProps) {\n const [submitting, setSubmitting] = useState(false);\n\n const handleSubmit = useCallback(\n (event: SubmitEvent<HTMLFormElement>) => {\n event.preventDefault();\n const result = onSubmit();\n if (result && typeof result.then === \"function\") {\n setSubmitting(true);\n result.finally(() => setSubmitting(false)).catch(() => undefined);\n }\n },\n [onSubmit],\n );\n\n return (\n <form\n noValidate\n {...rest}\n onSubmit={handleSubmit}\n className={[FORM_CLASSES, className ?? \"\"].filter(Boolean).join(\" \")}\n >\n <SubmittingContext.Provider value={submitting}>\n <fieldset disabled={submitting} className={FIELDSET_CLASSES}>\n {children}\n </fieldset>\n </SubmittingContext.Provider>\n </form>\n );\n}\n\nexport function FormError({ children }: { children?: ReactNode }) {\n if (!children) {\n return null;\n }\n\n return (\n <p role=\"alert\" className=\"text-hint text-danger\">\n {children}\n </p>\n );\n}\n\nfunction Spinner() {\n return (\n <svg\n className=\"h-4 w-4 animate-spin\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12H4Z\"\n />\n </svg>\n );\n}\n\nexport type SubmitButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"type\"\n> & {\n loadingLabel?: ReactNode;\n};\n\nconst BUTTON_CLASSES =\n \"flex h-10 w-full items-center justify-center gap-2 rounded-field bg-accent font-[inherit] text-field font-semibold text-on-accent outline-none focus:ring-3 focus:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-45\";\n\nexport function SubmitButton({\n children,\n loadingLabel,\n className,\n ...rest\n}: SubmitButtonProps) {\n const submitting = useContext(SubmittingContext);\n\n return (\n <button\n {...rest}\n type=\"submit\"\n className={[BUTTON_CLASSES, className ?? \"\"].filter(Boolean).join(\" \")}\n >\n {submitting ? (\n <>\n <Spinner />\n {loadingLabel}\n </>\n ) : (\n children\n )}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mBASO;AAsCC;AApCR,IAAM,wBAAoB,4BAAc,KAAK;AAU7C,IAAM,eAAe;AACrB,IAAM,mBAAmB;AAElB,SAAS,KAAK,EAAE,UAAU,UAAU,WAAW,GAAG,KAAK,GAAc;AAC1E,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAElD,QAAM,mBAAe;AAAA,IACnB,CAAC,UAAwC;AACvC,YAAM,eAAe;AACrB,YAAM,SAAS,SAAS;AACxB,UAAI,UAAU,OAAO,OAAO,SAAS,YAAY;AAC/C,sBAAc,IAAI;AAClB,eAAO,QAAQ,MAAM,cAAc,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,MAClE;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,YAAU;AAAA,MACT,GAAG;AAAA,MACJ,UAAU;AAAA,MACV,WAAW,CAAC,cAAc,aAAa,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAEnE,sDAAC,kBAAkB,UAAlB,EAA2B,OAAO,YACjC,sDAAC,cAAS,UAAU,YAAY,WAAW,kBACxC,UACH,GACF;AAAA;AAAA,EACF;AAEJ;AAEO,SAAS,UAAU,EAAE,SAAS,GAA6B;AAChE,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,SACE,4CAAC,OAAE,MAAK,SAAQ,WAAU,yBACvB,UACH;AAEJ;AAEA,SAAS,UAAU;AACjB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,eAAY;AAAA,MAEZ;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA;AAAA,QACd;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,GAAE;AAAA;AAAA,QACJ;AAAA;AAAA;AAAA,EACF;AAEJ;AASA,IAAM,iBACJ;AAEK,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,iBAAa,yBAAW,iBAAiB;AAE/C,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,MAAK;AAAA,MACL,WAAW,CAAC,gBAAgB,aAAa,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAEpE,uBACC,4EACE;AAAA,oDAAC,WAAQ;AAAA,QACR;AAAA,SACH,IAEA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/components/form/index.tsx","../src/components/button/index.tsx","../src/components/typography/index.tsx"],"sourcesContent":["\"use client\";\n\nimport { standardSchemaResolver } from \"@hookform/resolvers/standard-schema\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type { FormHTMLAttributes, ReactNode } from \"react\";\nimport {\n type DefaultValues,\n type FieldValues,\n FormProvider,\n type Mode,\n type UseFormReturn,\n useForm,\n useFormContext,\n useFormState,\n} from \"react-hook-form\";\nimport { Button, type ButtonProps } from \"@/components/button\";\nimport { Typography } from \"@/components/typography\";\n\n/**\n * A `<form>` on react-hook-form. The schema — any Standard Schema, which\n * every zod 4 schema is — validates the whole form: on first blur per field,\n * then on every change once a field has gone invalid, and again on submit.\n * Fields register themselves through `FieldRoot` (and so through every\n * input in this library), so a form is the schema, the inputs and a submit.\n *\n * `onSubmit` only runs with values the schema accepted, typed as its output.\n * Throwing from it — or calling `form.setError(\"root\", …)` — surfaces the\n * message through `FormError`. While it is pending the fields are disabled\n * and `SubmitButton` shows its spinner.\n *\n * Pass your own `form` (from `useFormInstance`) when a screen needs to reach\n * the instance itself, for `setError`, `reset` or `watch`.\n */\n\nexport type FormSchema = StandardSchemaV1<FieldValues, FieldValues>;\n\nexport type FormInput<Schema extends FormSchema> =\n StandardSchemaV1.InferInput<Schema>;\nexport type FormOutput<Schema extends FormSchema> =\n StandardSchemaV1.InferOutput<Schema>;\n\nexport type FormInstance<Schema extends FormSchema> = UseFormReturn<\n FormInput<Schema>,\n unknown,\n FormOutput<Schema>\n>;\n\nexport type UseFormInstanceOptions<Schema extends FormSchema> = {\n schema?: Schema;\n defaultValues?: DefaultValues<FormInput<Schema>>;\n /** When a field first validates. `onTouched`: first blur, then every change. */\n mode?: Mode;\n};\n\n// biome-ignore lint/style/useComponentExportOnlyModules: the hook is how a screen holds the instance Form would otherwise create, and belongs on the same subpath.\nexport function useFormInstance<Schema extends FormSchema>({\n schema,\n defaultValues,\n mode = \"onTouched\",\n}: UseFormInstanceOptions<Schema>): FormInstance<Schema> {\n return useForm<FormInput<Schema>, unknown, FormOutput<Schema>>({\n resolver: schema ? standardSchemaResolver(schema) : undefined,\n defaultValues,\n mode,\n reValidateMode: \"onChange\",\n });\n}\n\nexport type FormProps<Schema extends FormSchema = FormSchema> = Omit<\n FormHTMLAttributes<HTMLFormElement>,\n \"onSubmit\"\n> &\n UseFormInstanceOptions<Schema> & {\n onSubmit: (\n values: FormOutput<Schema>,\n form: FormInstance<Schema>,\n ) => void | Promise<void>;\n /** An instance from `useFormInstance`, when the screen needs it too. */\n form?: FormInstance<Schema>;\n children: ReactNode;\n };\n\nconst FORM_CLASSES = \"flex flex-col gap-4\";\nconst FIELDSET_CLASSES = \"contents border-0 p-0 m-0 min-w-0\";\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function Form<Schema extends FormSchema = FormSchema>({\n schema,\n defaultValues,\n mode,\n onSubmit,\n form: external,\n children,\n className,\n ...rest\n}: FormProps<Schema>) {\n const internal = useFormInstance<Schema>({ schema, defaultValues, mode });\n const form = external ?? internal;\n const { isSubmitting } = form.formState;\n\n const submit = form.handleSubmit(async (values) => {\n try {\n await onSubmit(values, form);\n } catch (error) {\n form.setError(\"root\", { type: \"submit\", message: errorMessage(error) });\n }\n });\n\n return (\n <FormProvider {...form}>\n <form\n noValidate\n {...rest}\n onSubmit={submit}\n className={[FORM_CLASSES, className ?? \"\"].filter(Boolean).join(\" \")}\n >\n <fieldset disabled={isSubmitting} className={FIELDSET_CLASSES}>\n {children}\n </fieldset>\n </form>\n </FormProvider>\n );\n}\n\nexport type FormErrorProps = {\n /** A message to show in place of the form's own root error. */\n children?: ReactNode;\n className?: string;\n};\n\nfunction FormErrorMessage({ children, className }: FormErrorProps) {\n if (!children) {\n return null;\n }\n\n return (\n <Typography\n as=\"p\"\n variant=\"hint\"\n tone=\"danger\"\n role=\"alert\"\n className={className}\n >\n {children}\n </Typography>\n );\n}\n\nfunction ConnectedFormError({ children, className }: FormErrorProps) {\n const { errors } = useFormState();\n\n return (\n <FormErrorMessage className={className}>\n {children ?? errors.root?.message}\n </FormErrorMessage>\n );\n}\n\n/**\n * The form-level error: a rejected credential, a failed request. Shows\n * `children` when given, otherwise whatever `onSubmit` threw or\n * `form.setError(\"root\", …)` recorded. Renders nothing while there is none.\n */\nexport function FormError(props: FormErrorProps) {\n const form = useFormContext() as UseFormReturn<FieldValues> | null;\n\n return form ? (\n <ConnectedFormError {...props} />\n ) : (\n <FormErrorMessage {...props} />\n );\n}\n\nexport type SubmitButtonProps = Omit<\n ButtonProps,\n \"type\" | \"loading\" | \"asChild\"\n>;\n\nfunction ConnectedSubmitButton({\n children,\n loadingLabel,\n fullWidth = true,\n ...rest\n}: SubmitButtonProps) {\n const { isSubmitting } = useFormState();\n\n return (\n <Button\n {...rest}\n type=\"submit\"\n fullWidth={fullWidth}\n loading={isSubmitting}\n loadingLabel={loadingLabel}\n >\n {children}\n </Button>\n );\n}\n\n/**\n * `Button` bound to the enclosing `Form`: always `type=\"submit\"`, full width\n * as the design's forms are, and loading for as long as `onSubmit` runs.\n */\nexport function SubmitButton(props: SubmitButtonProps) {\n const form = useFormContext() as UseFormReturn<FieldValues> | null;\n\n if (form) {\n return <ConnectedSubmitButton {...props} />;\n }\n\n const { fullWidth = true, ...rest } = props;\n\n return <Button {...rest} type=\"submit\" fullWidth={fullWidth} />;\n}\n","import { Slot } from \"@radix-ui/react-slot\";\nimport type { ButtonHTMLAttributes, ReactNode, Ref } from \"react\";\nimport { Typography, type TypographyTone } from \"@/components/typography\";\n\n/**\n * The design's primary action, as the auth screens use it: a 40px (or 44px)\n * accent-filled control with the field type scale, a 4px radius and the\n * shared 45% disabled opacity. `secondary` and `ghost` cover the quieter\n * actions that sit beside it.\n *\n * Server-safe: no state, no handlers of its own. `asChild` composes onto a\n * consumer's element — a `next/link` for a navigation styled as a button —\n * through Radix `Slot`, so the link keeps its own semantics. `loading` swaps\n * the label for a spinner and disables the control; it applies to the\n * rendered `<button>` only, since a child element owns its own content.\n */\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"ghost\";\nexport type ButtonSize = \"md\" | \"lg\";\n\nexport type ButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> & {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** Stretch to the container, as the auth forms' submit does. */\n fullWidth?: boolean;\n /** Shows a spinner in place of the label and disables the control. */\n loading?: boolean;\n /** Shown next to the spinner while `loading`; nothing but the spinner otherwise. */\n loadingLabel?: ReactNode;\n /** Merge the styles onto the child element instead of rendering a button. */\n asChild?: boolean;\n ref?: Ref<HTMLButtonElement>;\n children: ReactNode;\n};\n\nconst BASE_CLASSES =\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-field border font-[inherit] text-field font-semibold outline-none transition-colors focus-visible:ring-3 focus-visible:ring-accent-soft disabled:cursor-not-allowed disabled:opacity-45\";\n\nconst VARIANT_CLASSES: Record<ButtonVariant, string> = {\n primary:\n \"border-transparent bg-accent text-on-accent enabled:hover:bg-accent-2\",\n secondary: \"border-line bg-surface text-fg enabled:hover:bg-surface-2\",\n ghost: \"border-transparent bg-transparent text-fg enabled:hover:bg-surface-2\",\n};\n\nconst SIZE_CLASSES: Record<ButtonSize, string> = {\n md: \"h-10 px-4\",\n lg: \"h-11 px-5\",\n};\n\nconst LABEL_TONE: Record<ButtonVariant, TypographyTone> = {\n primary: \"on-accent\",\n secondary: \"default\",\n ghost: \"default\",\n};\n\nfunction buttonClassName({\n variant,\n size,\n fullWidth,\n className,\n}: {\n variant: ButtonVariant;\n size: ButtonSize;\n fullWidth: boolean;\n className: string | undefined;\n}): string {\n return [\n BASE_CLASSES,\n VARIANT_CLASSES[variant],\n SIZE_CLASSES[size],\n fullWidth ? \"w-full\" : \"\",\n className ?? \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n}\n\nfunction Spinner() {\n return (\n <svg\n className=\"h-4 w-4 animate-spin\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n data-testid=\"button-spinner\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12H4Z\"\n />\n </svg>\n );\n}\n\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n fullWidth = false,\n loading = false,\n loadingLabel,\n asChild = false,\n type = \"button\",\n disabled,\n className,\n children,\n ...rest\n}: ButtonProps) {\n const classes = buttonClassName({ variant, size, fullWidth, className });\n\n if (asChild) {\n return (\n <Slot {...rest} className={classes}>\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n {...rest}\n type={type}\n disabled={disabled || loading}\n aria-busy={loading || undefined}\n className={classes}\n >\n {loading ? (\n <>\n <Spinner />\n {loadingLabel}\n </>\n ) : (\n <Typography\n as=\"span\"\n variant=\"body\"\n weight=\"semibold\"\n tone={LABEL_TONE[variant]}\n >\n {children}\n </Typography>\n )}\n </button>\n );\n}\n","import { Slot } from \"@radix-ui/react-slot\";\nimport type { ElementType, HTMLAttributes, ReactNode, Ref } from \"react\";\n\n/**\n * The library's type scale. Everything that renders text — field labels, hints,\n * form errors, headings — goes through here, so a size or colour lives in one\n * place and the tokens in `src/styles/index.css` stay the single source of\n * truth for what \"hint\" or \"muted\" means.\n *\n * Server-safe: no state, no handlers, no directive. It composes Radix `Slot`\n * for `asChild`, which is how a consumer puts these styles on their own\n * element (a `next/link`, a Radix `Label`) without an extra wrapper.\n */\n\nexport type TypographyVariant =\n | \"display\"\n | \"heading\"\n | \"subheading\"\n | \"body\"\n | \"label\"\n | \"hint\"\n | \"code\";\n\nexport type TypographyTone =\n | \"default\"\n | \"muted\"\n | \"subtle\"\n | \"accent\"\n | \"on-accent\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"danger\";\n\nexport type TypographyWeight = \"regular\" | \"medium\" | \"semibold\" | \"bold\";\n\nexport type TypographyElement =\n | \"p\"\n | \"span\"\n | \"div\"\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"label\"\n | \"code\"\n | \"strong\"\n | \"em\"\n | \"small\";\n\nexport type TypographyProps = Omit<HTMLAttributes<HTMLElement>, \"color\"> & {\n /** Size and default element. `body` unless told otherwise. */\n variant?: TypographyVariant;\n /** Colour role, from the design tokens. */\n tone?: TypographyTone;\n /** Overrides the variant's default weight. */\n weight?: TypographyWeight;\n align?: \"start\" | \"center\" | \"end\";\n /** Clip to one line with an ellipsis. */\n truncate?: boolean;\n /**\n * An icon rendered beside the text, hidden from assistive tech. Sized to the\n * text with `1em`, so the same SVG fits every variant.\n */\n icon?: ReactNode;\n iconPosition?: \"leading\" | \"trailing\";\n /** The element to render. Defaults per variant (`h2` for a heading, and so on). */\n as?: TypographyElement;\n /**\n * Radix-style composition: render the child element itself, with these\n * styles merged onto it, instead of a wrapper. Takes precedence over `as`.\n */\n asChild?: boolean;\n ref?: Ref<HTMLElement>;\n children?: ReactNode;\n};\n\nconst DEFAULT_ELEMENT: Record<TypographyVariant, TypographyElement> = {\n display: \"h1\",\n heading: \"h2\",\n subheading: \"h3\",\n body: \"p\",\n label: \"span\",\n hint: \"p\",\n code: \"code\",\n};\n\nconst DEFAULT_WEIGHT: Record<TypographyVariant, TypographyWeight> = {\n display: \"semibold\",\n heading: \"semibold\",\n subheading: \"medium\",\n body: \"regular\",\n label: \"semibold\",\n hint: \"regular\",\n code: \"regular\",\n};\n\nconst VARIANT_CLASSES: Record<TypographyVariant, string> = {\n display: \"text-display leading-tight tracking-tight\",\n heading: \"text-heading leading-tight tracking-tight\",\n subheading: \"text-subheading leading-snug\",\n body: \"text-field leading-normal\",\n label: \"text-label leading-normal\",\n hint: \"text-hint leading-normal\",\n code: \"font-code text-field leading-normal\",\n};\n\nconst TONE_CLASSES: Record<TypographyTone, string> = {\n default: \"text-fg\",\n muted: \"text-fg-muted\",\n subtle: \"text-fg-subtle\",\n accent: \"text-accent\",\n \"on-accent\": \"text-on-accent\",\n success: \"text-success\",\n warning: \"text-warning\",\n info: \"text-info\",\n danger: \"text-danger\",\n};\n\nconst WEIGHT_CLASSES: Record<TypographyWeight, string> = {\n regular: \"font-normal\",\n medium: \"font-medium\",\n semibold: \"font-semibold\",\n bold: \"font-bold\",\n};\n\nconst ALIGN_CLASSES = {\n start: \"text-start\",\n center: \"text-center\",\n end: \"text-end\",\n} as const;\n\nconst ICON_CLASSES =\n \"inline-flex shrink-0 items-center [&>svg]:h-[1em] [&>svg]:w-[1em]\";\n\nfunction typographyClassName({\n variant,\n tone,\n weight,\n align,\n truncate,\n hasIcon,\n className,\n}: {\n variant: TypographyVariant;\n tone: TypographyTone;\n weight: TypographyWeight;\n align: \"start\" | \"center\" | \"end\" | undefined;\n truncate: boolean;\n hasIcon: boolean;\n className: string | undefined;\n}): string {\n return [\n VARIANT_CLASSES[variant],\n TONE_CLASSES[tone],\n WEIGHT_CLASSES[weight],\n align ? ALIGN_CLASSES[align] : \"\",\n hasIcon ? \"inline-flex items-center gap-1.5\" : \"\",\n // With an icon the root is a flex container, and text-overflow only\n // clips block text, so the text span carries the truncation instead.\n truncate && !hasIcon ? \"truncate\" : \"\",\n className ?? \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n}\n\nexport function Typography({\n variant = \"body\",\n tone = \"default\",\n weight,\n align,\n truncate = false,\n icon,\n iconPosition = \"leading\",\n as,\n asChild = false,\n className,\n children,\n ...rest\n}: TypographyProps) {\n const hasIcon = icon !== undefined && icon !== null;\n // Widened to `ElementType`: the union of intrinsic tags would otherwise\n // demand a `ref` typed to one specific element.\n const Component: ElementType = asChild\n ? Slot\n : (as ?? DEFAULT_ELEMENT[variant]);\n\n const iconNode = hasIcon ? (\n <span aria-hidden=\"true\" className={ICON_CLASSES}>\n {icon}\n </span>\n ) : null;\n\n const content = hasIcon ? (\n <>\n {iconPosition === \"leading\" ? iconNode : null}\n <span className={truncate ? \"min-w-0 truncate\" : undefined}>\n {children}\n </span>\n {iconPosition === \"trailing\" ? iconNode : null}\n </>\n ) : (\n children\n );\n\n return (\n <Component\n {...rest}\n className={typographyClassName({\n variant,\n tone,\n weight: weight ?? DEFAULT_WEIGHT[variant],\n align,\n truncate,\n hasIcon,\n className,\n })}\n >\n {content}\n </Component>\n );\n}\n"],"mappings":"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","names":["import_react_slot","import_jsx_runtime","VARIANT_CLASSES","import_jsx_runtime"]}
|