@agentero/design-system 0.27.1 → 0.28.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/lib/index.d.ts +1 -0
- package/lib/index.js +2 -1
- package/lib/merge-props.d.ts +42 -0
- package/lib/merge-props.js +24 -0
- package/mcp/manifests/components.html +796 -71
- package/mcp/manifests/components.json +500 -9
- package/package.json +10 -1
- package/src/alert/alert.js +28 -28
- package/src/avatar/avatar.js +22 -22
- package/src/avatar-group/avatar-group.js +6 -6
- package/src/button/button.js +7 -7
- package/src/data-table/data-table.js +36 -36
- package/src/field/context.d.ts +62 -0
- package/src/field/context.js +6 -0
- package/src/field/field.d.ts +214 -0
- package/src/field/field.js +129 -0
- package/src/field/icons.d.ts +9 -0
- package/src/field/icons.js +14 -0
- package/src/field/index.d.ts +30 -0
- package/src/field/index.js +13 -0
- package/src/field-text/field-text.d.ts +28 -0
- package/src/field-text/field-text.js +26 -0
- package/src/field-text/index.d.ts +2 -0
- package/src/field-text/index.js +2 -0
- package/src/input/context.d.ts +17 -0
- package/src/input/context.js +10 -0
- package/src/input/index.d.ts +1 -0
- package/src/input/index.js +3 -2
- package/src/input/input.d.ts +7 -7
- package/src/input/input.js +16 -11
- package/src/label/context.d.ts +13 -0
- package/src/label/context.js +7 -0
- package/src/label/index.d.ts +1 -0
- package/src/label/index.js +3 -2
- package/src/label/label.d.ts +6 -1
- package/src/label/label.js +19 -17
- package/src/modal/modal.js +23 -23
- package/src/progress/progress.js +9 -9
- package/src/switch/switch.js +7 -7
- package/src/table/table.js +28 -28
- package/src/tabs/tabs.js +26 -26
- package/src/tag/tag.js +7 -7
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
import { VariantProps } from 'tailwind-variants';
|
|
3
|
+
import { LabelProps } from '../label';
|
|
4
|
+
import { TooltipProps } from '../tooltip';
|
|
5
|
+
import { FieldDescriptionProps, FieldErrorProps } from './context';
|
|
6
|
+
/**
|
|
7
|
+
* Style recipe for Field. Slots: `group`, `root`, `content`, `label`,
|
|
8
|
+
* `labelTooltip`, `description`, `error`. The `orientation` variant applies to
|
|
9
|
+
* `root`.
|
|
10
|
+
*
|
|
11
|
+
* @summary tailwind-variants recipe backing the Field parts
|
|
12
|
+
*/
|
|
13
|
+
export declare const fieldRecipe: import('tailwind-variants').TVReturnType<{
|
|
14
|
+
orientation: {
|
|
15
|
+
vertical: {
|
|
16
|
+
root: string;
|
|
17
|
+
};
|
|
18
|
+
horizontal: {
|
|
19
|
+
root: string[];
|
|
20
|
+
};
|
|
21
|
+
responsive: {
|
|
22
|
+
root: string[];
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}, {
|
|
26
|
+
group: string;
|
|
27
|
+
root: string;
|
|
28
|
+
content: string[];
|
|
29
|
+
label: string;
|
|
30
|
+
labelTooltip: string[];
|
|
31
|
+
description: string[];
|
|
32
|
+
error: string[];
|
|
33
|
+
}, undefined, {
|
|
34
|
+
orientation: {
|
|
35
|
+
vertical: {
|
|
36
|
+
root: string;
|
|
37
|
+
};
|
|
38
|
+
horizontal: {
|
|
39
|
+
root: string[];
|
|
40
|
+
};
|
|
41
|
+
responsive: {
|
|
42
|
+
root: string[];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
}, {
|
|
46
|
+
group: string;
|
|
47
|
+
root: string;
|
|
48
|
+
content: string[];
|
|
49
|
+
label: string;
|
|
50
|
+
labelTooltip: string[];
|
|
51
|
+
description: string[];
|
|
52
|
+
error: string[];
|
|
53
|
+
}, import('tailwind-variants').TVReturnType<{
|
|
54
|
+
orientation: {
|
|
55
|
+
vertical: {
|
|
56
|
+
root: string;
|
|
57
|
+
};
|
|
58
|
+
horizontal: {
|
|
59
|
+
root: string[];
|
|
60
|
+
};
|
|
61
|
+
responsive: {
|
|
62
|
+
root: string[];
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
}, {
|
|
66
|
+
group: string;
|
|
67
|
+
root: string;
|
|
68
|
+
content: string[];
|
|
69
|
+
label: string;
|
|
70
|
+
labelTooltip: string[];
|
|
71
|
+
description: string[];
|
|
72
|
+
error: string[];
|
|
73
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
74
|
+
export type FieldVariants = VariantProps<typeof fieldRecipe>;
|
|
75
|
+
export type FieldGroupProps = ComponentPropsWithRef<'div'>;
|
|
76
|
+
/**
|
|
77
|
+
* Stacks sibling fields and owns the space between them. The gap lives here
|
|
78
|
+
* rather than as a margin on each field, so a field never carries spacing it
|
|
79
|
+
* cannot control. Nest a `Field.Group` to tighten a sub-set of fields.
|
|
80
|
+
*
|
|
81
|
+
* @summary Stacks sibling fields and owns the space between them
|
|
82
|
+
*/
|
|
83
|
+
export declare const Group: {
|
|
84
|
+
({ className, ...props }: FieldGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
85
|
+
displayName: string;
|
|
86
|
+
};
|
|
87
|
+
export type FieldRootProps = ComponentPropsWithRef<'div'> & {
|
|
88
|
+
/**
|
|
89
|
+
* Layout of the field. `vertical` (default) stacks label, control and
|
|
90
|
+
* messages. `horizontal` is one row at every width: the first child fills it
|
|
91
|
+
* and the rest keep their natural width, aligned to the right, so the
|
|
92
|
+
* controls of stacked fields line up. `responsive` stacks below `28rem` and
|
|
93
|
+
* behaves like `horizontal` from there, measured on the field itself, so it
|
|
94
|
+
* needs no particular wrapper. In both, `Field.Content` groups a control with
|
|
95
|
+
* its messages, or a label with its description.
|
|
96
|
+
*/
|
|
97
|
+
orientation?: FieldVariants['orientation'];
|
|
98
|
+
/**
|
|
99
|
+
* Marks the field as failing validation: sets `data-invalid` on the root and
|
|
100
|
+
* `aria-invalid` on the control through its context, which drives the
|
|
101
|
+
* control's destructive border. The label keeps its color by design.
|
|
102
|
+
*/
|
|
103
|
+
invalid?: boolean;
|
|
104
|
+
/** Disables the control through its context and sets `data-disabled` on the root. */
|
|
105
|
+
disabled?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Makes the control read-only through its context (focusable and copyable,
|
|
108
|
+
* not editable, still submitted) and sets `data-readonly` on the root.
|
|
109
|
+
*/
|
|
110
|
+
readOnly?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Single source of truth for a required field: the `Label` shows its
|
|
113
|
+
* asterisk and the control receives `required`, both through context.
|
|
114
|
+
*/
|
|
115
|
+
required?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* `id` for the control. Generated when omitted. Set it here, not on the
|
|
118
|
+
* control, so the label and the messages keep pointing at the right element.
|
|
119
|
+
*/
|
|
120
|
+
controlId?: string;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Wraps one label, control, description and error into a single field and
|
|
124
|
+
* wires the accessibility relationships between them. It generates the ids
|
|
125
|
+
* and shares them through context: `Label` reads `LabelContext`,
|
|
126
|
+
* `Field.Description` and `Field.Error` read `FieldContext` and register
|
|
127
|
+
* themselves so the control's `aria-describedby` lists exactly the messages on
|
|
128
|
+
* screen, and a `Field<X>` such as `FieldText` provides the control's context so
|
|
129
|
+
* the control associates itself too. Nobody passes an `id` by hand.
|
|
130
|
+
*
|
|
131
|
+
* Presentational and form-library agnostic: pass `invalid` and the error
|
|
132
|
+
* messages from whatever validates the form. Deliberately not a `role="group"`:
|
|
133
|
+
* one field is not a set of related controls, and an unnamed group only adds
|
|
134
|
+
* screen-reader verbosity. Real groupings belong to a fieldset with a legend.
|
|
135
|
+
*
|
|
136
|
+
* @summary Wraps a label, control, description and error into one field
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* <Field.Root invalid={!!error} required>
|
|
140
|
+
* <Field.Label>Email</Field.Label>
|
|
141
|
+
* <Input type="email" />
|
|
142
|
+
* <Field.Description>We only use this for policy documents.</Field.Description>
|
|
143
|
+
* <Field.Error errors={[error]} />
|
|
144
|
+
* </Field.Root>
|
|
145
|
+
*/
|
|
146
|
+
export declare const Root: {
|
|
147
|
+
({ className, orientation, invalid, disabled, readOnly, required, controlId: controlIdProp, ...props }: FieldRootProps): import("react/jsx-runtime").JSX.Element;
|
|
148
|
+
displayName: string;
|
|
149
|
+
};
|
|
150
|
+
export type FieldContentProps = ComponentPropsWithRef<'div'>;
|
|
151
|
+
/**
|
|
152
|
+
* Stacks parts vertically inside a `horizontal` or `responsive` field: a label
|
|
153
|
+
* with its description on the left, or a control with its messages on the
|
|
154
|
+
* right. Takes its natural width unless it comes first; give it a width, or
|
|
155
|
+
* `flex-1` to grow.
|
|
156
|
+
*
|
|
157
|
+
* @summary Stacks control, description and error beside the label
|
|
158
|
+
*/
|
|
159
|
+
export declare const Content: {
|
|
160
|
+
({ className, ...props }: FieldContentProps): import("react/jsx-runtime").JSX.Element;
|
|
161
|
+
displayName: string;
|
|
162
|
+
};
|
|
163
|
+
export type FieldLabelProps = LabelProps & {
|
|
164
|
+
/**
|
|
165
|
+
* Hint revealed on hover or focus from an info icon beside the caption. The
|
|
166
|
+
* icon is a sibling of the `<label>`, never inside it, so it keeps its own
|
|
167
|
+
* accessible name and clicking it does not focus the control.
|
|
168
|
+
*/
|
|
169
|
+
tooltip?: ReactNode;
|
|
170
|
+
/** Preferred side of the tooltip. Defaults to `'top'`. */
|
|
171
|
+
tooltipSide?: TooltipProps['side'];
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* The field's caption row: a `Label` and, when `tooltip` is given, an info
|
|
175
|
+
* button beside it. The `Label` associates itself with the control through the
|
|
176
|
+
* field's context, so no `htmlFor` is passed by hand. A bare `Label` inside a
|
|
177
|
+
* field works too; use `Field.Label` when you need the tooltip.
|
|
178
|
+
*
|
|
179
|
+
* @summary The field's caption, with an optional tooltip beside it
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* <Field.Label required tooltip="Issued by the IRS">Tax ID</Field.Label>
|
|
183
|
+
*/
|
|
184
|
+
export declare const Label: {
|
|
185
|
+
({ tooltip, tooltipSide, ...props }: FieldLabelProps): import("react/jsx-runtime").JSX.Element;
|
|
186
|
+
displayName: string;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Helper text explaining what the field expects, announced through the
|
|
190
|
+
* control's `aria-describedby`. One per field: it takes the field's single
|
|
191
|
+
* description id, so put several hints in one `Field.Description`. For
|
|
192
|
+
* validation feedback use `Field.Error`.
|
|
193
|
+
*
|
|
194
|
+
* @summary Helper text explaining what the field expects
|
|
195
|
+
*/
|
|
196
|
+
export declare const Description: {
|
|
197
|
+
({ className, id: idProp, ...props }: FieldDescriptionProps): import("react/jsx-runtime").JSX.Element;
|
|
198
|
+
displayName: string;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Validation feedback for the field, announced as an alert when it appears.
|
|
202
|
+
* Renders nothing without a message, so it can stay mounted unconditionally;
|
|
203
|
+
* set `invalid` on `Field.Root` alongside it. Takes `children` or an `errors`
|
|
204
|
+
* array, and a form adapter can supply `errors` through `FieldContext` so a
|
|
205
|
+
* bare `<Field.Error />` renders them. One per field: it takes the field's
|
|
206
|
+
* single error id, and several errors render as one list.
|
|
207
|
+
*
|
|
208
|
+
* @summary Validation feedback for the field, announced as an alert
|
|
209
|
+
*/
|
|
210
|
+
declare const FieldError: {
|
|
211
|
+
({ className, children, errors: errorsProp, id: idProp, ...props }: FieldErrorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
212
|
+
displayName: string;
|
|
213
|
+
};
|
|
214
|
+
export { FieldError as Error };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { LabelContext as t } from "../label/context.js";
|
|
4
|
+
import { Label as n } from "../label/label.js";
|
|
5
|
+
import { Tooltip as r } from "../tooltip/tooltip.js";
|
|
6
|
+
import { FieldContext as i, useFieldContext as a } from "./context.js";
|
|
7
|
+
import { IconInfoOutline as o } from "./icons.js";
|
|
8
|
+
import { tv as s } from "tailwind-variants";
|
|
9
|
+
import { useCallback as c, useId as l, useLayoutEffect as u, useState as d } from "react";
|
|
10
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
11
|
+
//#region src/field/field.tsx
|
|
12
|
+
var m = s({
|
|
13
|
+
slots: {
|
|
14
|
+
group: "flex w-full flex-col gap-7 [&>[data-slot=field-group]]:gap-4",
|
|
15
|
+
root: "group/field flex w-full gap-2",
|
|
16
|
+
content: ["flex flex-col gap-2 leading-snug", "[&>:is([data-slot=label],[data-slot=field-label])+[data-slot=field-description]]:-mt-1.5"],
|
|
17
|
+
label: "flex flex-wrap items-center gap-1",
|
|
18
|
+
labelTooltip: [
|
|
19
|
+
"inline-flex shrink-0 cursor-pointer items-center justify-center rounded-sm",
|
|
20
|
+
"text-icon-default-base-secondary [&_svg]:size-5 [&_path]:fill-current",
|
|
21
|
+
"focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring-button-primary"
|
|
22
|
+
],
|
|
23
|
+
description: [
|
|
24
|
+
"text-sm leading-normal font-normal text-text-input-placeholder",
|
|
25
|
+
"group-data-[orientation=horizontal]/field:text-balance @md/field:text-balance",
|
|
26
|
+
"[&>a]:underline [&>a]:underline-offset-4"
|
|
27
|
+
],
|
|
28
|
+
error: ["text-sm font-normal text-text-input-destructive", "[&>ul]:ml-4 [&>ul]:flex [&>ul]:list-disc [&>ul]:flex-col [&>ul]:gap-1"]
|
|
29
|
+
},
|
|
30
|
+
variants: { orientation: {
|
|
31
|
+
vertical: { root: "flex-col [&>*]:w-full [&>.sr-only]:w-auto" },
|
|
32
|
+
horizontal: { root: ["flex-row items-center [&>:first-child]:flex-1", "has-[>[data-slot=field-content]]:items-start"] },
|
|
33
|
+
responsive: { root: [
|
|
34
|
+
"@container/field flex-row flex-wrap items-start",
|
|
35
|
+
"@max-md/field:[&>*]:w-full @max-md/field:[&>.sr-only]:w-auto",
|
|
36
|
+
"@md/field:[&>*]:self-center @md/field:[&>:first-child]:flex-1",
|
|
37
|
+
"@md/field:has-[>[data-slot=field-content]]:[&>*]:self-start"
|
|
38
|
+
] }
|
|
39
|
+
} },
|
|
40
|
+
defaultVariants: { orientation: "vertical" }
|
|
41
|
+
}), h = m(), g = ({ className: t, ...n }) => /* @__PURE__ */ f("div", {
|
|
42
|
+
"data-slot": "field-group",
|
|
43
|
+
className: e(h.group(), t),
|
|
44
|
+
...n
|
|
45
|
+
});
|
|
46
|
+
g.displayName = "Field.Group";
|
|
47
|
+
var _ = ({ className: n, orientation: r = "vertical", invalid: a = !1, disabled: o = !1, readOnly: s = !1, required: u = !1, controlId: p, ...m }) => {
|
|
48
|
+
let g = l(), _ = p ?? `${g}-control`, v = `${g}-description`, y = `${g}-error`, [b, x] = d([]), S = c((e) => (x((t) => t.includes(e) ? t : [...t, e]), () => x((t) => t.filter((t) => t !== e))), []);
|
|
49
|
+
return /* @__PURE__ */ f(i, {
|
|
50
|
+
value: {
|
|
51
|
+
controlId: _,
|
|
52
|
+
descriptionId: v,
|
|
53
|
+
errorId: y,
|
|
54
|
+
describedBy: [...[v, y].filter((e) => b.includes(e)), ...b.filter((e) => e !== v && e !== y)].join(" ") || void 0,
|
|
55
|
+
registerMessage: S,
|
|
56
|
+
invalid: a,
|
|
57
|
+
disabled: o,
|
|
58
|
+
readOnly: s,
|
|
59
|
+
required: u
|
|
60
|
+
},
|
|
61
|
+
children: /* @__PURE__ */ f(t, {
|
|
62
|
+
value: {
|
|
63
|
+
htmlFor: _,
|
|
64
|
+
required: u || void 0
|
|
65
|
+
},
|
|
66
|
+
children: /* @__PURE__ */ f("div", {
|
|
67
|
+
"data-slot": "field",
|
|
68
|
+
"data-orientation": r,
|
|
69
|
+
"data-invalid": a || void 0,
|
|
70
|
+
"data-disabled": o || void 0,
|
|
71
|
+
"data-readonly": s || void 0,
|
|
72
|
+
className: e(h.root({ orientation: r }), n),
|
|
73
|
+
...m
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
_.displayName = "Field.Root";
|
|
79
|
+
var v = ({ className: t, ...n }) => /* @__PURE__ */ f("div", {
|
|
80
|
+
"data-slot": "field-content",
|
|
81
|
+
className: e(h.content(), t),
|
|
82
|
+
...n
|
|
83
|
+
});
|
|
84
|
+
v.displayName = "Field.Content";
|
|
85
|
+
var y = ({ tooltip: e, tooltipSide: t, ...i }) => /* @__PURE__ */ p("div", {
|
|
86
|
+
"data-slot": "field-label",
|
|
87
|
+
className: h.label(),
|
|
88
|
+
children: [/* @__PURE__ */ f(n, { ...i }), e && /* @__PURE__ */ f(r, {
|
|
89
|
+
content: e,
|
|
90
|
+
side: t,
|
|
91
|
+
asChild: !0,
|
|
92
|
+
children: /* @__PURE__ */ f("button", {
|
|
93
|
+
type: "button",
|
|
94
|
+
"data-slot": "field-label-tooltip",
|
|
95
|
+
"aria-label": "More information",
|
|
96
|
+
className: h.labelTooltip(),
|
|
97
|
+
children: /* @__PURE__ */ f(o, {})
|
|
98
|
+
})
|
|
99
|
+
})]
|
|
100
|
+
});
|
|
101
|
+
y.displayName = "Field.Label";
|
|
102
|
+
var b = ({ className: t, id: n, ...r }) => {
|
|
103
|
+
let i = a(), o = n ?? i?.descriptionId, s = i?.registerMessage;
|
|
104
|
+
return u(() => o ? s?.(o) : void 0, [s, o]), /* @__PURE__ */ f("p", {
|
|
105
|
+
"data-slot": "field-description",
|
|
106
|
+
id: o,
|
|
107
|
+
className: e(h.description(), t),
|
|
108
|
+
...r
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
b.displayName = "Field.Description";
|
|
112
|
+
var x = ({ className: t, children: n, errors: r, id: i, ...o }) => {
|
|
113
|
+
let s = a(), c = i ?? s?.errorId, l = r ?? s?.errors, d = s?.registerMessage, p = [...new Set(l?.flatMap((e) => e?.message || []))], m = n ?? (p.length > 1 ? /* @__PURE__ */ f("ul", { children: p.map((e) => /* @__PURE__ */ f("li", { children: e }, e)) }) : p[0]), g = !!m;
|
|
114
|
+
return u(() => g && c ? d?.(c) : void 0, [
|
|
115
|
+
d,
|
|
116
|
+
g,
|
|
117
|
+
c
|
|
118
|
+
]), m ? /* @__PURE__ */ f("div", {
|
|
119
|
+
role: "alert",
|
|
120
|
+
"data-slot": "field-error",
|
|
121
|
+
id: c,
|
|
122
|
+
className: e(h.error(), t),
|
|
123
|
+
...o,
|
|
124
|
+
children: m
|
|
125
|
+
}) : null;
|
|
126
|
+
};
|
|
127
|
+
x.displayName = "Field.Error";
|
|
128
|
+
//#endregion
|
|
129
|
+
export { v as Content, b as Description, x as FieldError, g as Group, y as Label, _ as Root, m as fieldRecipe };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Outlined info icon for the `Field.Label` tooltip trigger. Inherits color from
|
|
4
|
+
* the surrounding text via `currentColor` when paired with `fill-current` on
|
|
5
|
+
* the `<path>`.
|
|
6
|
+
*
|
|
7
|
+
* @summary 24px outlined info icon for the field tooltip trigger
|
|
8
|
+
*/
|
|
9
|
+
export declare const IconInfoOutline: (props: SVGProps<SVGSVGElement>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
//#region src/field/icons.tsx
|
|
3
|
+
var t = (t) => /* @__PURE__ */ e("svg", {
|
|
4
|
+
width: "24",
|
|
5
|
+
height: "24",
|
|
6
|
+
viewBox: "0 0 24 24",
|
|
7
|
+
fill: "none",
|
|
8
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
9
|
+
"aria-hidden": !0,
|
|
10
|
+
...t,
|
|
11
|
+
children: /* @__PURE__ */ e("path", { d: "M12.0003 16.75C12.2129 16.75 12.391 16.6781 12.5346 16.5344C12.6782 16.3906 12.75 16.2125 12.75 16V11.75C12.75 11.5375 12.6781 11.3594 12.5343 11.2156C12.3904 11.0719 12.2122 11 11.9997 11C11.7871 11 11.609 11.0719 11.4654 11.2156C11.3218 11.3594 11.25 11.5375 11.25 11.75V16C11.25 16.2125 11.3219 16.3906 11.4657 16.5344C11.6095 16.6781 11.7877 16.75 12.0003 16.75ZM12 9.28848C12.2288 9.28848 12.4207 9.21108 12.5755 9.05628C12.7303 8.90148 12.8077 8.70966 12.8077 8.48081C12.8077 8.25197 12.7303 8.06015 12.5755 7.90533C12.4207 7.75053 12.2288 7.67313 12 7.67313C11.7711 7.67313 11.5793 7.75053 11.4245 7.90533C11.2697 8.06015 11.1923 8.25197 11.1923 8.48081C11.1923 8.70966 11.2697 8.90148 11.4245 9.05628C11.5793 9.21108 11.7711 9.28848 12 9.28848ZM12.0016 21.5C10.6877 21.5 9.45268 21.2506 8.29655 20.752C7.1404 20.2533 6.13472 19.5766 5.2795 18.7217C4.42427 17.8669 3.74721 16.8616 3.24833 15.706C2.74944 14.5504 2.5 13.3156 2.5 12.0017C2.5 10.6877 2.74933 9.45271 3.248 8.29658C3.74667 7.14043 4.42342 6.13475 5.27825 5.27953C6.1331 4.4243 7.13834 3.74724 8.29398 3.24836C9.44959 2.74947 10.6844 2.50003 11.9983 2.50003C13.3122 2.50003 14.5473 2.74936 15.7034 3.24803C16.8596 3.7467 17.8652 4.42345 18.7205 5.27828C19.5757 6.13313 20.2527 7.13837 20.7516 8.29401C21.2505 9.44962 21.5 10.6844 21.5 11.9983C21.5 13.3123 21.2506 14.5473 20.752 15.7034C20.2533 16.8596 19.5765 17.8653 18.7217 18.7205C17.8669 19.5757 16.8616 20.2528 15.706 20.7517C14.5504 21.2505 13.3156 21.5 12.0016 21.5ZM12 20C14.2333 20 16.125 19.225 17.675 17.675C19.225 16.125 20 14.2333 20 12C20 9.76667 19.225 7.87501 17.675 6.32501C16.125 4.77501 14.2333 4.00001 12 4.00001C9.76664 4.00001 7.87498 4.77501 6.32498 6.32501C4.77498 7.87501 3.99998 9.76667 3.99998 12C3.99998 14.2333 4.77498 16.125 6.32498 17.675C7.87498 19.225 9.76664 20 12 20Z" })
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { t as IconInfoOutline };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export { fieldRecipe } from './field';
|
|
2
|
+
export { FieldContext, useFieldContext } from './context';
|
|
3
|
+
export type { FieldContentProps, FieldGroupProps, FieldLabelProps, FieldRootProps, FieldVariants } from './field';
|
|
4
|
+
export type { FieldContextValue, FieldDescriptionProps, FieldErrorLike, FieldErrorProps } from './context';
|
|
5
|
+
export declare const Field: {
|
|
6
|
+
Root: {
|
|
7
|
+
({ className, orientation, invalid, disabled, readOnly, required, controlId: controlIdProp, ...props }: import('./field').FieldRootProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
displayName: string;
|
|
9
|
+
};
|
|
10
|
+
Group: {
|
|
11
|
+
({ className, ...props }: import('./field').FieldGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
displayName: string;
|
|
13
|
+
};
|
|
14
|
+
Content: {
|
|
15
|
+
({ className, ...props }: import('./field').FieldContentProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
displayName: string;
|
|
17
|
+
};
|
|
18
|
+
Label: {
|
|
19
|
+
({ tooltip, tooltipSide, ...props }: import('./field').FieldLabelProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
displayName: string;
|
|
21
|
+
};
|
|
22
|
+
Description: {
|
|
23
|
+
({ className, id: idProp, ...props }: import('./context').FieldDescriptionProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
displayName: string;
|
|
25
|
+
};
|
|
26
|
+
Error: {
|
|
27
|
+
({ className, children, errors: errorsProp, id: idProp, ...props }: import('./context').FieldErrorProps): import("react/jsx-runtime").JSX.Element | null;
|
|
28
|
+
displayName: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FieldContext as e, useFieldContext as t } from "./context.js";
|
|
2
|
+
import { Content as n, Description as r, FieldError as i, Group as a, Label as o, Root as s, fieldRecipe as c } from "./field.js";
|
|
3
|
+
//#region src/field/index.ts
|
|
4
|
+
var l = {
|
|
5
|
+
Root: s,
|
|
6
|
+
Group: a,
|
|
7
|
+
Content: n,
|
|
8
|
+
Label: o,
|
|
9
|
+
Description: r,
|
|
10
|
+
Error: i
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { l as Field, e as FieldContext, c as fieldRecipe, t as useFieldContext };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { FieldRootProps } from '../field';
|
|
2
|
+
export type FieldTextProps = FieldRootProps;
|
|
3
|
+
/**
|
|
4
|
+
* A `Field.Root` for a single-line text control: it provides `InputContext`,
|
|
5
|
+
* so the `Input` inside associates itself with the label and the messages and
|
|
6
|
+
* takes `invalid`, `required`, `disabled` and `readOnly` from the field. Every
|
|
7
|
+
* other part (`Label`, `Field.Description`, `Field.Error`) works as in any
|
|
8
|
+
* field.
|
|
9
|
+
*
|
|
10
|
+
* Form-library agnostic, and its contexts compose: a provider nested inside it
|
|
11
|
+
* can extend `InputContext` with `name`, `value`, `onChange`, `onBlur` and
|
|
12
|
+
* `ref` to control the `Input`, and `FieldContext` with the errors, on top of
|
|
13
|
+
* the wiring `FieldText` already set.
|
|
14
|
+
*
|
|
15
|
+
* @summary Field for a single-line text control, wiring the Input inside it
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <FieldText invalid={!!error} required>
|
|
19
|
+
* <Label>Email</Label>
|
|
20
|
+
* <Input type="email" />
|
|
21
|
+
* <Field.Description>We only use this for policy documents.</Field.Description>
|
|
22
|
+
* <Field.Error errors={[error]} />
|
|
23
|
+
* </FieldText>
|
|
24
|
+
*/
|
|
25
|
+
export declare const FieldText: {
|
|
26
|
+
({ children, ...props }: FieldTextProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
displayName: string;
|
|
28
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useFieldContext as e } from "../field/context.js";
|
|
3
|
+
import { Field as t } from "../field/index.js";
|
|
4
|
+
import { InputContext as n } from "../input/context.js";
|
|
5
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
6
|
+
//#region src/field-text/field-text.tsx
|
|
7
|
+
var i = ({ children: t }) => {
|
|
8
|
+
let i = e();
|
|
9
|
+
return /* @__PURE__ */ r(n, {
|
|
10
|
+
value: i && {
|
|
11
|
+
id: i.controlId,
|
|
12
|
+
"aria-describedby": i.describedBy,
|
|
13
|
+
"aria-invalid": i.invalid || void 0,
|
|
14
|
+
required: i.required || void 0,
|
|
15
|
+
disabled: i.disabled || void 0,
|
|
16
|
+
readOnly: i.readOnly || void 0
|
|
17
|
+
},
|
|
18
|
+
children: t
|
|
19
|
+
});
|
|
20
|
+
}, a = ({ children: e, ...n }) => /* @__PURE__ */ r(t.Root, {
|
|
21
|
+
...n,
|
|
22
|
+
children: /* @__PURE__ */ r(i, { children: e })
|
|
23
|
+
});
|
|
24
|
+
a.displayName = "FieldText";
|
|
25
|
+
//#endregion
|
|
26
|
+
export { a as FieldText };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { InputProps } from './input';
|
|
2
|
+
/**
|
|
3
|
+
* Props a container hands to every `Input` rendered inside it: the wiring
|
|
4
|
+
* (`id`, `aria-describedby`, `aria-invalid`, `required`, `disabled`,
|
|
5
|
+
* `readOnly`) and, from a form adapter, `name`, `value`, `onChange`, `onBlur`
|
|
6
|
+
* and `ref`. An `Input` with no provider above it reads `null` and uses only
|
|
7
|
+
* its own props.
|
|
8
|
+
*/
|
|
9
|
+
export declare const InputContext: import('react').Context<Partial<InputProps> | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Merges the surrounding `InputContext`, if any, under the input's own props.
|
|
12
|
+
* Own props win; handlers present on both sides are chained and
|
|
13
|
+
* `aria-describedby` ids are concatenated. In development it warns when the
|
|
14
|
+
* input carries an `id` that differs from the one the container provides,
|
|
15
|
+
* since the label would then point elsewhere.
|
|
16
|
+
*/
|
|
17
|
+
export declare const useInputContext: (props: InputProps) => InputProps;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMergeProps as e } from "../../lib/merge-props.js";
|
|
3
|
+
import { createContext as t, use as n } from "react";
|
|
4
|
+
//#region src/input/context.ts
|
|
5
|
+
var r = t(null), i = (t) => {
|
|
6
|
+
let i = n(r);
|
|
7
|
+
return process.env.NODE_ENV !== "production" && i?.id && t.id && i.id !== t.id && console.warn(`Input: its id "${t.id}" differs from the one its field provides ("${i.id}"), so the label and messages point elsewhere. Set \`controlId\` on the container instead.`), e(i, t);
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { r as InputContext, i as useInputContext };
|
package/src/input/index.d.ts
CHANGED
package/src/input/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { InputContext as e, useInputContext as t } from "./context.js";
|
|
2
|
+
import { Input as n, inputRecipe as r } from "./input.js";
|
|
3
|
+
export { n as Input, e as InputContext, r as inputRecipe, t as useInputContext };
|
package/src/input/input.d.ts
CHANGED
|
@@ -82,18 +82,18 @@ export type InputProps = Omit<ComponentPropsWithRef<'input'>, 'size'> & {
|
|
|
82
82
|
* [Label](?path=/docs/components-label--docs) so the control has an accessible
|
|
83
83
|
* name.
|
|
84
84
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* There is no `status` prop — mark the control `aria-invalid` and the
|
|
85
|
+
* When a container provides `InputContext`, the input takes its wiring (`id`,
|
|
86
|
+
* `aria-describedby`, `aria-invalid`, `required`, `disabled`, `readOnly`) from
|
|
87
|
+
* it with nothing passed by hand; `FieldText` is one such container. Standalone it
|
|
88
|
+
* renders exactly the props it is given, and its own props always win over the
|
|
89
|
+
* context. There is no `status` prop — mark the control `aria-invalid` and the
|
|
90
90
|
* destructive border follows.
|
|
91
91
|
*
|
|
92
92
|
* Do not use Input for multi-line text; that is TextArea's job. It also has no
|
|
93
93
|
* slots for leading or trailing addons — an input with a currency prefix or a
|
|
94
94
|
* unit suffix belongs in an input group, not here.
|
|
95
95
|
*
|
|
96
|
-
* @summary Base single-line text control
|
|
96
|
+
* @summary Base single-line text control that takes its wiring from InputContext
|
|
97
97
|
*
|
|
98
98
|
* @example
|
|
99
99
|
* <Label htmlFor="email">Email</Label>
|
|
@@ -104,6 +104,6 @@ export type InputProps = Omit<ComponentPropsWithRef<'input'>, 'size'> & {
|
|
|
104
104
|
* <span id="email-error">Enter a valid email address.</span>
|
|
105
105
|
*/
|
|
106
106
|
export declare const Input: {
|
|
107
|
-
(
|
|
107
|
+
(props: InputProps): import("react/jsx-runtime").JSX.Element;
|
|
108
108
|
displayName: string;
|
|
109
109
|
};
|
package/src/input/input.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { cn as e } from "../../lib/utils.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
3
|
+
import { useInputContext as t } from "./context.js";
|
|
4
|
+
import { tv as n } from "tailwind-variants";
|
|
5
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
4
6
|
//#region src/input/input.tsx
|
|
5
|
-
var
|
|
7
|
+
var i = n({
|
|
6
8
|
base: [
|
|
7
9
|
"box-border w-full min-w-0 appearance-none rounded-md px-4 shadow-sm",
|
|
8
10
|
"border border-solid border-border-input-default bg-bg-input-normal text-text-input-normal",
|
|
@@ -24,12 +26,15 @@ var r = t({
|
|
|
24
26
|
lg: "h-12 rounded-lg text-base"
|
|
25
27
|
} },
|
|
26
28
|
defaultVariants: { size: "md" }
|
|
27
|
-
}),
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
})
|
|
33
|
-
|
|
29
|
+
}), a = (n) => {
|
|
30
|
+
let { className: a, size: o, ...s } = t(n);
|
|
31
|
+
return /* @__PURE__ */ r("input", {
|
|
32
|
+
"data-slot": "input",
|
|
33
|
+
"data-size": o,
|
|
34
|
+
className: e(i({ size: o }), a),
|
|
35
|
+
...s
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
a.displayName = "Input";
|
|
34
39
|
//#endregion
|
|
35
|
-
export {
|
|
40
|
+
export { a as Input, i as inputRecipe };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LabelProps } from './label';
|
|
2
|
+
/**
|
|
3
|
+
* Props a container hands to every `Label` rendered inside it, typically
|
|
4
|
+
* `htmlFor` (the control's id) and `required`. A `Label` with no provider above
|
|
5
|
+
* it reads `null` and uses only its own props.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LabelContext: import('react').Context<Partial<LabelProps> | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Merges the surrounding `LabelContext`, if any, under the label's own props.
|
|
10
|
+
* Own props win, so an explicit `htmlFor` or `required={false}` overrides
|
|
11
|
+
* whatever the container provides.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useLabelContext: (props: LabelProps) => LabelProps;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useMergeProps as e } from "../../lib/merge-props.js";
|
|
3
|
+
import { createContext as t, use as n } from "react";
|
|
4
|
+
//#region src/label/context.ts
|
|
5
|
+
var r = t(null), i = (t) => e(n(r), t);
|
|
6
|
+
//#endregion
|
|
7
|
+
export { r as LabelContext, i as useLabelContext };
|
package/src/label/index.d.ts
CHANGED
package/src/label/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { LabelContext as e, useLabelContext as t } from "./context.js";
|
|
2
|
+
import { Label as n, labelRecipe as r } from "./label.js";
|
|
3
|
+
export { n as Label, e as LabelContext, r as labelRecipe, t as useLabelContext };
|
package/src/label/label.d.ts
CHANGED
|
@@ -49,6 +49,11 @@ export type LabelProps = ComponentPropsWithRef<typeof LabelPrimitive.Root> & Lab
|
|
|
49
49
|
* button) inside a `<label>` gives that element the label's accessible name and
|
|
50
50
|
* makes a click focus the control — render it as a sibling instead.
|
|
51
51
|
*
|
|
52
|
+
* When a container provides `LabelContext`, the label takes `htmlFor` and
|
|
53
|
+
* `required` from it and associates itself with the control without an explicit
|
|
54
|
+
* `htmlFor`; `Field.Root` is one such container. Standalone it behaves as a
|
|
55
|
+
* plain label. Its own props always win over the context.
|
|
56
|
+
*
|
|
52
57
|
* @summary Accessible caption for a form control
|
|
53
58
|
*
|
|
54
59
|
* @example
|
|
@@ -56,6 +61,6 @@ export type LabelProps = ComponentPropsWithRef<typeof LabelPrimitive.Root> & Lab
|
|
|
56
61
|
* <Input id="phone" type="tel" />
|
|
57
62
|
*/
|
|
58
63
|
export declare const Label: {
|
|
59
|
-
(
|
|
64
|
+
(props: LabelProps): import("react/jsx-runtime").JSX.Element;
|
|
60
65
|
displayName: string;
|
|
61
66
|
};
|