@agentero/design-system 0.33.0 → 0.34.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/mcp/manifests/components.html +384 -103
- package/mcp/manifests/components.json +191 -20
- package/package.json +5 -1
- package/src/combobox/combobox.d.ts +12 -7
- package/src/combobox/combobox.js +79 -62
- package/src/field/context.d.ts +6 -2
- package/src/field/field.d.ts +4 -2
- package/src/field/field.js +30 -27
- package/src/field/index.d.ts +1 -1
- package/src/field-text/field-text.d.ts +1 -1
- package/src/form-text/form-text.d.ts +4 -4
- package/src/form-text/form-text.js +2 -2
- package/src/input-search/icons.d.ts +16 -0
- package/src/input-search/icons.js +23 -0
- package/src/input-search/index.d.ts +2 -0
- package/src/input-search/index.js +2 -0
- package/src/input-search/input-search.d.ts +96 -0
- package/src/input-search/input-search.js +53 -0
package/src/combobox/combobox.js
CHANGED
|
@@ -5,13 +5,14 @@ import { useFieldContext as n } from "../field/context.js";
|
|
|
5
5
|
import { InputContext as r } from "../input/context.js";
|
|
6
6
|
import { inputRecipe as i } from "../input/input.js";
|
|
7
7
|
import { InputGroup as a } from "../input-group/index.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { InputSearch as o } from "../input-search/input-search.js";
|
|
9
|
+
import { IconCancel as s, IconCheck as c, IconKeyboardArrowDown as l, IconSearch as u } from "./icons.js";
|
|
10
|
+
import { tv as d } from "tailwind-variants";
|
|
11
|
+
import { createContext as f, use as p, useRef as m, useState as h } from "react";
|
|
12
|
+
import { jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
13
|
+
import { Combobox as v } from "@base-ui/react/combobox";
|
|
13
14
|
//#region src/combobox/combobox.tsx
|
|
14
|
-
var
|
|
15
|
+
var y = d({ slots: {
|
|
15
16
|
action: [
|
|
16
17
|
"flex size-6 shrink-0 cursor-pointer items-center justify-center self-center rounded-sm",
|
|
17
18
|
"[&>svg>path]:fill-icon-input-default hover:[&>svg>path]:fill-icon-default-base-primary",
|
|
@@ -47,78 +48,94 @@ var v = u({ slots: {
|
|
|
47
48
|
"group-data-disabled/item:data-selected:bg-bg-checkbox-disabled"
|
|
48
49
|
],
|
|
49
50
|
message: ["mx-2 my-px px-3 py-2 text-sm text-text-default-base-tertiary", "empty:m-0 empty:p-0"]
|
|
50
|
-
} }),
|
|
51
|
-
let s = !!o.multiple, [c, l] =
|
|
51
|
+
} }), b = y(), x = f(!1), S = ({ minInputLength: e = 0, open: t, defaultOpen: n = !1, onOpenChange: r, onOpenChangeComplete: i, onInputValueChange: a, ...o }) => {
|
|
52
|
+
let s = !!o.multiple, [c, l] = h(n), u = m(String(o.inputValue ?? o.defaultInputValue ?? ""));
|
|
52
53
|
o.inputValue !== void 0 && (u.current = String(o.inputValue));
|
|
53
|
-
let d = (t) => t.trim().length < e, f =
|
|
54
|
+
let d = (t) => t.trim().length < e, f = m(!1), p = m(!1), _ = (e, t) => {
|
|
54
55
|
if (e && d(u.current)) {
|
|
55
56
|
t.cancel();
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
f.current = !1, r?.(e, t), s && !e && t.reason === "item-press" && t.cancel(), t.isCanceled || l(e);
|
|
59
60
|
}, y = (e) => {
|
|
60
|
-
i?.(e), !e && f.current && (f.current = !1,
|
|
61
|
-
},
|
|
62
|
-
if (
|
|
63
|
-
|
|
61
|
+
i?.(e), !e && f.current && (f.current = !1, p.current = !0, queueMicrotask(() => p.current = !1));
|
|
62
|
+
}, b = (e, n) => {
|
|
63
|
+
if (p.current) {
|
|
64
|
+
p.current = !1, n.cancel();
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
67
|
u.current = e, a?.(e, n), d(e) && t === void 0 && c && (f.current = !0, l(!1));
|
|
67
68
|
}, S = t ?? (e > 0 ? c : void 0);
|
|
68
|
-
return /* @__PURE__ */
|
|
69
|
+
return /* @__PURE__ */ g(x, {
|
|
69
70
|
value: s,
|
|
70
|
-
children: /* @__PURE__ */
|
|
71
|
+
children: /* @__PURE__ */ g(v.Root, {
|
|
71
72
|
open: S,
|
|
72
73
|
defaultOpen: n,
|
|
73
|
-
onOpenChange:
|
|
74
|
+
onOpenChange: _,
|
|
74
75
|
onOpenChangeComplete: y,
|
|
75
|
-
onInputValueChange:
|
|
76
|
+
onInputValueChange: b,
|
|
76
77
|
...o
|
|
77
78
|
})
|
|
78
79
|
});
|
|
79
80
|
};
|
|
80
|
-
|
|
81
|
-
var
|
|
81
|
+
S.displayName = "Combobox.Root";
|
|
82
|
+
var C = /* @__PURE__ */ new Set([
|
|
82
83
|
"value",
|
|
83
84
|
"defaultValue",
|
|
84
85
|
"onChange"
|
|
85
|
-
]),
|
|
86
|
-
let i =
|
|
86
|
+
]), w = (e) => {
|
|
87
|
+
let i = p(r), a = n(), o = i ? Object.fromEntries(Object.entries(i).filter(([e]) => !C.has(e))) : null, s = !("aria-label" in e || "aria-labelledby" in e) && a ? { "aria-labelledby": a.labelId } : null;
|
|
87
88
|
return t({
|
|
88
89
|
...o,
|
|
89
90
|
...s
|
|
90
91
|
}, e);
|
|
91
|
-
},
|
|
92
|
-
let { className:
|
|
93
|
-
return /* @__PURE__ */ g(
|
|
94
|
-
render: /* @__PURE__ */
|
|
92
|
+
}, T = ({ variant: t = "search", showClear: n = t === "search", clearLabel: c = "Clear", triggerLabel: d = "Show options", ...f }) => {
|
|
93
|
+
let { className: m, size: h = "md", ...y } = w(f), S = p(x);
|
|
94
|
+
return t === "search" && n && !S ? /* @__PURE__ */ g(v.InputGroup, {
|
|
95
|
+
render: /* @__PURE__ */ g("div", {}),
|
|
96
|
+
"data-slot": "combobox-field",
|
|
97
|
+
children: /* @__PURE__ */ g(r, {
|
|
98
|
+
value: null,
|
|
99
|
+
children: /* @__PURE__ */ g(v.Input, {
|
|
100
|
+
"data-slot": "combobox-input",
|
|
101
|
+
className: m,
|
|
102
|
+
...y,
|
|
103
|
+
render: (e) => /* @__PURE__ */ g(o, {
|
|
104
|
+
...e,
|
|
105
|
+
size: h,
|
|
106
|
+
clearLabel: c
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
}) : /* @__PURE__ */ _(v.InputGroup, {
|
|
111
|
+
render: /* @__PURE__ */ g(a.Root, {}),
|
|
95
112
|
"data-slot": "combobox-field",
|
|
96
113
|
className: t === "plain" ? "px-4" : void 0,
|
|
97
114
|
children: [
|
|
98
|
-
t === "search" && /* @__PURE__ */
|
|
99
|
-
/* @__PURE__ */
|
|
115
|
+
t === "search" && /* @__PURE__ */ g(a.Addon, { children: /* @__PURE__ */ g(u, {}) }),
|
|
116
|
+
/* @__PURE__ */ g(v.Input, {
|
|
100
117
|
"data-slot": "combobox-input",
|
|
101
|
-
"data-size":
|
|
102
|
-
className: e(i({ size:
|
|
103
|
-
...
|
|
118
|
+
"data-size": h,
|
|
119
|
+
className: e(i({ size: h }), m),
|
|
120
|
+
...y
|
|
104
121
|
}),
|
|
105
|
-
n && !
|
|
122
|
+
n && !S && /* @__PURE__ */ g(v.Clear, {
|
|
106
123
|
"data-slot": "combobox-clear",
|
|
107
|
-
"aria-label":
|
|
108
|
-
className:
|
|
109
|
-
children: /* @__PURE__ */
|
|
124
|
+
"aria-label": c,
|
|
125
|
+
className: b.action(),
|
|
126
|
+
children: /* @__PURE__ */ g(s, {})
|
|
110
127
|
}),
|
|
111
|
-
t === "select" && !
|
|
128
|
+
t === "select" && !S && /* @__PURE__ */ g(v.Trigger, {
|
|
112
129
|
"data-slot": "combobox-trigger",
|
|
113
|
-
"aria-label":
|
|
114
|
-
className: e(
|
|
115
|
-
children: /* @__PURE__ */
|
|
130
|
+
"aria-label": d,
|
|
131
|
+
className: e(b.action(), b.trigger(), n && b.triggerReplaced()),
|
|
132
|
+
children: /* @__PURE__ */ g(l, {})
|
|
116
133
|
})
|
|
117
134
|
]
|
|
118
135
|
});
|
|
119
136
|
};
|
|
120
|
-
|
|
121
|
-
var
|
|
137
|
+
T.displayName = "Combobox.Input";
|
|
138
|
+
var E = ({ className: t, side: n = "bottom", align: r = "start", sideOffset: i = 12, alignOffset: a, anchor: o, collisionPadding: s = 8, ...c }) => /* @__PURE__ */ g(v.Portal, { children: /* @__PURE__ */ g(v.Positioner, {
|
|
122
139
|
side: n,
|
|
123
140
|
align: r,
|
|
124
141
|
sideOffset: i,
|
|
@@ -126,49 +143,49 @@ var T = ({ className: t, side: n = "bottom", align: r = "start", sideOffset: i =
|
|
|
126
143
|
anchor: o,
|
|
127
144
|
collisionPadding: s,
|
|
128
145
|
className: "isolate z-(--z-index-top-layer) pointer-events-auto",
|
|
129
|
-
children: /* @__PURE__ */
|
|
146
|
+
children: /* @__PURE__ */ g(v.Popup, {
|
|
130
147
|
"data-slot": "combobox-content",
|
|
131
|
-
className: e(
|
|
148
|
+
className: e(b.content(), t),
|
|
132
149
|
...c
|
|
133
150
|
})
|
|
134
151
|
}) });
|
|
135
|
-
|
|
136
|
-
var
|
|
152
|
+
E.displayName = "Combobox.Content";
|
|
153
|
+
var D = ({ className: t, ...n }) => {
|
|
137
154
|
let r = "aria-label" in n || "aria-labelledby" in n;
|
|
138
|
-
return /* @__PURE__ */
|
|
155
|
+
return /* @__PURE__ */ g(v.List, {
|
|
139
156
|
"data-slot": "combobox-list",
|
|
140
157
|
"aria-label": r ? void 0 : "Suggestions",
|
|
141
|
-
className: e(
|
|
158
|
+
className: e(b.list(), t),
|
|
142
159
|
...n
|
|
143
160
|
});
|
|
144
161
|
};
|
|
145
|
-
|
|
146
|
-
var
|
|
147
|
-
let i =
|
|
148
|
-
return /* @__PURE__ */
|
|
162
|
+
D.displayName = "Combobox.List";
|
|
163
|
+
var O = ({ className: t, children: n, ...r }) => {
|
|
164
|
+
let i = p(x);
|
|
165
|
+
return /* @__PURE__ */ _(v.Item, {
|
|
149
166
|
"data-slot": "combobox-item",
|
|
150
|
-
className: e(
|
|
167
|
+
className: e(b.item(), t),
|
|
151
168
|
...r,
|
|
152
|
-
children: [i && /* @__PURE__ */
|
|
169
|
+
children: [i && /* @__PURE__ */ g(v.ItemIndicator, {
|
|
153
170
|
keepMounted: !0,
|
|
154
171
|
"data-slot": "combobox-item-indicator",
|
|
155
|
-
className:
|
|
156
|
-
children: /* @__PURE__ */
|
|
172
|
+
className: b.indicator(),
|
|
173
|
+
children: /* @__PURE__ */ g(c, { className: "size-3.5" })
|
|
157
174
|
}), n]
|
|
158
175
|
});
|
|
159
176
|
};
|
|
160
|
-
|
|
161
|
-
var
|
|
177
|
+
O.displayName = "Combobox.Item";
|
|
178
|
+
var k = ({ className: t, ...n }) => /* @__PURE__ */ g(v.Empty, {
|
|
162
179
|
"data-slot": "combobox-empty",
|
|
163
|
-
className: e(
|
|
180
|
+
className: e(b.message(), t),
|
|
164
181
|
...n
|
|
165
182
|
});
|
|
166
|
-
|
|
167
|
-
var
|
|
183
|
+
k.displayName = "Combobox.Empty";
|
|
184
|
+
var A = ({ className: t, ...n }) => /* @__PURE__ */ g(v.Status, {
|
|
168
185
|
"data-slot": "combobox-status",
|
|
169
|
-
className: e(
|
|
186
|
+
className: e(b.message(), t),
|
|
170
187
|
...n
|
|
171
188
|
});
|
|
172
|
-
|
|
189
|
+
A.displayName = "Combobox.Status";
|
|
173
190
|
//#endregion
|
|
174
|
-
export {
|
|
191
|
+
export { E as Content, k as Empty, T as Input, O as Item, D as List, S as Root, A as Status, y as comboboxRecipe };
|
package/src/field/context.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export type FieldErrorLike = {
|
|
|
11
11
|
*/
|
|
12
12
|
types?: Record<string, string | string[] | boolean | undefined>;
|
|
13
13
|
} | undefined;
|
|
14
|
+
/** What a registered message is, which sets its place in `aria-describedby`. */
|
|
15
|
+
export type FieldMessageKind = 'error' | 'description';
|
|
14
16
|
/**
|
|
15
17
|
* State of the surrounding `Field.Root`, shared with the Field family
|
|
16
18
|
* (`Field.Description`, `Field.Error`) and with controls that have no context
|
|
@@ -39,9 +41,11 @@ export type FieldContextValue = {
|
|
|
39
41
|
/**
|
|
40
42
|
* Adds a message element to `describedBy` and returns the function that
|
|
41
43
|
* removes it. `Field.Description` and `Field.Error` call it from a layout
|
|
42
|
-
* effect; a custom message element can do the same.
|
|
44
|
+
* effect; a custom message element can do the same. Errors are listed first,
|
|
45
|
+
* then descriptions, then messages registered without a `kind`, each in the
|
|
46
|
+
* order they registered.
|
|
43
47
|
*/
|
|
44
|
-
registerMessage: (id: string) => () => void;
|
|
48
|
+
registerMessage: (id: string, kind?: FieldMessageKind) => () => void;
|
|
45
49
|
invalid: boolean;
|
|
46
50
|
disabled: boolean;
|
|
47
51
|
readOnly: boolean;
|
package/src/field/field.d.ts
CHANGED
|
@@ -141,8 +141,8 @@ export type FieldRootProps = ComponentPropsWithRef<'div'> & {
|
|
|
141
141
|
* <Field.Root invalid={!!error} required>
|
|
142
142
|
* <Field.Label>Email</Field.Label>
|
|
143
143
|
* <Input type="email" />
|
|
144
|
-
* <Field.Description>We only use this for policy documents.</Field.Description>
|
|
145
144
|
* <Field.Error errors={[error]} />
|
|
145
|
+
* <Field.Description>We only use this for policy documents.</Field.Description>
|
|
146
146
|
* </Field.Root>
|
|
147
147
|
*/
|
|
148
148
|
export declare const Root: {
|
|
@@ -201,7 +201,9 @@ export declare const Description: {
|
|
|
201
201
|
};
|
|
202
202
|
/**
|
|
203
203
|
* Validation feedback for the field, announced as an alert when it appears.
|
|
204
|
-
*
|
|
204
|
+
* Place it right after the control, before `Field.Description`: the control's
|
|
205
|
+
* `aria-describedby` reads the error first as well. Renders nothing without a
|
|
206
|
+
* message, so it can stay mounted unconditionally;
|
|
205
207
|
* set `invalid` on `Field.Root` alongside it. Takes `children` or an `errors`
|
|
206
208
|
* array, and a form adapter can supply `errors` through `FieldContext` so a
|
|
207
209
|
* bare `<Field.Error />` renders them. One per field: it takes the field's
|
package/src/field/field.js
CHANGED
|
@@ -38,31 +38,34 @@ var m = s({
|
|
|
38
38
|
] }
|
|
39
39
|
} },
|
|
40
40
|
defaultVariants: { orientation: "vertical" }
|
|
41
|
-
}), h = m(), g = ({ className: t, ...n }) => /* @__PURE__ */ f("div", {
|
|
41
|
+
}), h = m(), g = (e) => e === "error" ? 0 : e === "description" ? 1 : 2, _ = ({ className: t, ...n }) => /* @__PURE__ */ f("div", {
|
|
42
42
|
"data-slot": "field-group",
|
|
43
43
|
className: e(h.group(), t),
|
|
44
44
|
...n
|
|
45
45
|
});
|
|
46
|
-
|
|
47
|
-
var
|
|
48
|
-
let
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
46
|
+
_.displayName = "Field.Group";
|
|
47
|
+
var v = ({ className: n, orientation: r = "vertical", invalid: a = !1, disabled: o = !1, readOnly: s = !1, required: u = !1, controlId: p, ...m }) => {
|
|
48
|
+
let _ = l(), v = p ?? `${_}-control`, y = `${_}-label`, b = `${_}-description`, x = `${_}-error`, [S, C] = d([]), w = c((e, t) => (C((n) => n.some((t) => t.id === e) ? n : [...n, {
|
|
49
|
+
id: e,
|
|
50
|
+
kind: t
|
|
51
|
+
}]), () => C((t) => t.filter((t) => t.id !== e))), []), T = {
|
|
52
|
+
controlId: v,
|
|
53
|
+
labelId: y,
|
|
54
|
+
descriptionId: b,
|
|
55
|
+
errorId: x,
|
|
56
|
+
describedBy: [...S].sort((e, t) => g(e.kind) - g(t.kind)).map((e) => e.id).join(" ") || void 0,
|
|
57
|
+
registerMessage: w,
|
|
55
58
|
invalid: a,
|
|
56
59
|
disabled: o,
|
|
57
60
|
readOnly: s,
|
|
58
61
|
required: u
|
|
59
62
|
};
|
|
60
63
|
return /* @__PURE__ */ f(i, {
|
|
61
|
-
value:
|
|
64
|
+
value: T,
|
|
62
65
|
children: /* @__PURE__ */ f(t, {
|
|
63
66
|
value: {
|
|
64
|
-
id:
|
|
65
|
-
htmlFor:
|
|
67
|
+
id: y,
|
|
68
|
+
htmlFor: v,
|
|
66
69
|
required: u || void 0
|
|
67
70
|
},
|
|
68
71
|
children: /* @__PURE__ */ f("div", {
|
|
@@ -77,14 +80,14 @@ var _ = ({ className: n, orientation: r = "vertical", invalid: a = !1, disabled:
|
|
|
77
80
|
})
|
|
78
81
|
});
|
|
79
82
|
};
|
|
80
|
-
|
|
81
|
-
var
|
|
83
|
+
v.displayName = "Field.Root";
|
|
84
|
+
var y = ({ className: t, ...n }) => /* @__PURE__ */ f("div", {
|
|
82
85
|
"data-slot": "field-content",
|
|
83
86
|
className: e(h.content(), t),
|
|
84
87
|
...n
|
|
85
88
|
});
|
|
86
|
-
|
|
87
|
-
var
|
|
89
|
+
y.displayName = "Field.Content";
|
|
90
|
+
var b = ({ tooltip: e, tooltipSide: t, ...i }) => /* @__PURE__ */ p("div", {
|
|
88
91
|
"data-slot": "field-label",
|
|
89
92
|
className: h.label(),
|
|
90
93
|
children: [/* @__PURE__ */ f(n, { ...i }), e && /* @__PURE__ */ f(r, {
|
|
@@ -100,23 +103,23 @@ var y = ({ tooltip: e, tooltipSide: t, ...i }) => /* @__PURE__ */ p("div", {
|
|
|
100
103
|
})
|
|
101
104
|
})]
|
|
102
105
|
});
|
|
103
|
-
|
|
104
|
-
var
|
|
106
|
+
b.displayName = "Field.Label";
|
|
107
|
+
var x = ({ className: t, id: n, ...r }) => {
|
|
105
108
|
let i = a(), o = n ?? i?.descriptionId, s = i?.registerMessage;
|
|
106
|
-
return u(() => o ? s?.(o) : void 0, [s, o]), /* @__PURE__ */ f("p", {
|
|
109
|
+
return u(() => o ? s?.(o, "description") : void 0, [s, o]), /* @__PURE__ */ f("p", {
|
|
107
110
|
"data-slot": "field-description",
|
|
108
111
|
id: o,
|
|
109
112
|
className: e(h.description(), t),
|
|
110
113
|
...r
|
|
111
114
|
});
|
|
112
115
|
};
|
|
113
|
-
|
|
114
|
-
var
|
|
116
|
+
x.displayName = "Field.Description";
|
|
117
|
+
var S = (e) => {
|
|
115
118
|
let t = Object.values(e?.types ?? {}).flat().filter((e) => typeof e == "string" && e.length > 0);
|
|
116
119
|
return t.length ? t : e?.message ? [e.message] : [];
|
|
117
|
-
},
|
|
118
|
-
let s = a(), c = i ?? s?.errorId, l = r ?? s?.errors, d = s?.registerMessage, p = [...new Set(l?.flatMap(
|
|
119
|
-
return u(() => g && c ? d?.(c) : void 0, [
|
|
120
|
+
}, C = ({ className: t, children: n, errors: r, id: i, ...o }) => {
|
|
121
|
+
let s = a(), c = i ?? s?.errorId, l = r ?? s?.errors, d = s?.registerMessage, p = [...new Set(l?.flatMap(S))], m = n ?? (p.length > 1 ? /* @__PURE__ */ f("ul", { children: p.map((e) => /* @__PURE__ */ f("li", { children: e }, e)) }) : p[0]), g = !!m;
|
|
122
|
+
return u(() => g && c ? d?.(c, "error") : void 0, [
|
|
120
123
|
d,
|
|
121
124
|
g,
|
|
122
125
|
c
|
|
@@ -129,6 +132,6 @@ var x = (e) => {
|
|
|
129
132
|
children: m
|
|
130
133
|
}) : null;
|
|
131
134
|
};
|
|
132
|
-
|
|
135
|
+
C.displayName = "Field.Error";
|
|
133
136
|
//#endregion
|
|
134
|
-
export {
|
|
137
|
+
export { y as Content, x as Description, C as Error, _ as Group, b as Label, v as Root, m as fieldRecipe };
|
package/src/field/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { fieldRecipe } from './field';
|
|
2
2
|
export { FieldContext, useFieldContext } from './context';
|
|
3
3
|
export type { FieldContentProps, FieldGroupProps, FieldLabelProps, FieldRootProps, FieldVariants } from './field';
|
|
4
|
-
export type { FieldContextValue, FieldDescriptionProps, FieldErrorLike, FieldErrorProps } from './context';
|
|
4
|
+
export type { FieldContextValue, FieldDescriptionProps, FieldErrorLike, FieldErrorProps, FieldMessageKind } from './context';
|
|
5
5
|
export declare const Field: {
|
|
6
6
|
Root: {
|
|
7
7
|
({ className, orientation, invalid, disabled, readOnly, required, controlId: controlIdProp, ...props }: import('./field').FieldRootProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -18,8 +18,8 @@ export type FieldTextProps = FieldRootProps;
|
|
|
18
18
|
* <FieldText invalid={!!error} required>
|
|
19
19
|
* <Label>Email</Label>
|
|
20
20
|
* <Input type="email" />
|
|
21
|
-
* <Field.Description>We only use this for policy documents.</Field.Description>
|
|
22
21
|
* <Field.Error errors={[error]} />
|
|
22
|
+
* <Field.Description>We only use this for policy documents.</Field.Description>
|
|
23
23
|
* </FieldText>
|
|
24
24
|
*/
|
|
25
25
|
export declare const FieldText: {
|
|
@@ -55,9 +55,9 @@ export type FormTextProps<TFieldValues extends FieldValues = FieldValues, TName
|
|
|
55
55
|
/** The caption, rendered as the field's label. Text in almost every case. */
|
|
56
56
|
label: ReactNode;
|
|
57
57
|
/**
|
|
58
|
-
* Helper text shown under the control
|
|
59
|
-
* `aria-describedby`. Use it for guidance the
|
|
60
|
-
* details worth a click in `tooltip` instead.
|
|
58
|
+
* Helper text shown under the control, below the error when there is one,
|
|
59
|
+
* and announced through its `aria-describedby`. Use it for guidance the
|
|
60
|
+
* user needs before typing; put details worth a click in `tooltip` instead.
|
|
61
61
|
*/
|
|
62
62
|
description?: ReactNode;
|
|
63
63
|
/**
|
|
@@ -96,7 +96,7 @@ export type FormTextProps<TFieldValues extends FieldValues = FieldValues, TName
|
|
|
96
96
|
};
|
|
97
97
|
/**
|
|
98
98
|
* A complete text field bound to one react-hook-form value: label, `Input`,
|
|
99
|
-
*
|
|
99
|
+
* validation error and helper text, laid out in the standard order and wired
|
|
100
100
|
* through `useController`. It renders inside a `Form.Root`, which provides the
|
|
101
101
|
* form, and needs only a `name`, which on a typed form must point at a string
|
|
102
102
|
* (`FormTextPath`). The `required`, `invalid` and error states
|
|
@@ -30,8 +30,8 @@ var s = ({ name: s, control: c, rules: l, shouldUnregister: u, disabled: d, labe
|
|
|
30
30
|
children: f
|
|
31
31
|
}), /* @__PURE__ */ a(t.Content, { children: [
|
|
32
32
|
/* @__PURE__ */ i(n, { ...e(x, _ ?? {}) }),
|
|
33
|
-
|
|
34
|
-
/* @__PURE__ */ i(t.
|
|
33
|
+
/* @__PURE__ */ i(t.Error, { errors: b.error ? [b.error] : void 0 }),
|
|
34
|
+
p && /* @__PURE__ */ i(t.Description, { children: p })
|
|
35
35
|
] })]
|
|
36
36
|
});
|
|
37
37
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Magnifier leading InputSearch, the same glyph `Combobox` uses. Fill color
|
|
4
|
+
* comes from the input group addon, so the icon follows the field's state.
|
|
5
|
+
*
|
|
6
|
+
* @summary 24px search icon leading the InputSearch field
|
|
7
|
+
*/
|
|
8
|
+
export declare const IconSearch: (props: SVGProps<SVGSVGElement>) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Circled cross on the InputSearch clear button, the same glyph `Combobox`
|
|
11
|
+
* uses. Fill color comes from the button's class, so the icon follows its
|
|
12
|
+
* hover and disabled states.
|
|
13
|
+
*
|
|
14
|
+
* @summary 24px cancel icon on the InputSearch clear button
|
|
15
|
+
*/
|
|
16
|
+
export declare const IconCancel: (props: SVGProps<SVGSVGElement>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
//#region src/input-search/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
|
+
"aria-hidden": "true",
|
|
9
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
10
|
+
...t,
|
|
11
|
+
children: /* @__PURE__ */ e("path", { d: "M9.52 15.615q-2.562 0-4.34-1.777Q3.405 12.062 3.405 9.5T5.18 5.162q1.776-1.777 4.338-1.777t4.339 1.777q1.777 1.776 1.777 4.338 0 1.071-.36 2.046a5.7 5.7 0 0 1-.96 1.696l5.754 5.754q.209.209.213.522a.7.7 0 0 1-.213.532.72.72 0 0 1-.527.217.72.72 0 0 1-.527-.217l-5.753-5.754q-.75.62-1.725.97t-2.018.35m0-1.5q1.933 0 3.273-1.341 1.342-1.34 1.342-3.274 0-1.932-1.342-3.274-1.34-1.341-3.274-1.341-1.932 0-3.274 1.34Q4.904 7.569 4.904 9.5q0 1.933 1.341 3.274 1.342 1.341 3.274 1.341" })
|
|
12
|
+
}), n = (t) => /* @__PURE__ */ e("svg", {
|
|
13
|
+
width: "24",
|
|
14
|
+
height: "24",
|
|
15
|
+
viewBox: "0 0 24 24",
|
|
16
|
+
fill: "none",
|
|
17
|
+
"aria-hidden": "true",
|
|
18
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
19
|
+
...t,
|
|
20
|
+
children: /* @__PURE__ */ e("path", { d: "M12 13.0538L15.0731 16.1269C15.2115 16.2654 15.3856 16.3362 15.5952 16.3394C15.8048 16.3426 15.982 16.2718 16.1269 16.1269C16.2718 15.982 16.3442 15.8064 16.3442 15.6C16.3442 15.3936 16.2718 15.218 16.1269 15.0731L13.0538 12L16.1269 8.9269C16.2653 8.78845 16.3362 8.61442 16.3394 8.4048C16.3426 8.1952 16.2718 8.01797 16.1269 7.8731C15.982 7.72822 15.8064 7.65577 15.6 7.65577C15.3936 7.65577 15.2179 7.72822 15.0731 7.8731L12 10.9462L8.92688 7.8731C8.78842 7.73463 8.61439 7.6638 8.40478 7.6606C8.19518 7.65738 8.01794 7.72822 7.87308 7.8731C7.72819 8.01797 7.65575 8.1936 7.65575 8.4C7.65575 8.6064 7.72819 8.78203 7.87308 8.9269L10.9461 12L7.87308 15.0731C7.73461 15.2115 7.66378 15.3856 7.66058 15.5952C7.65736 15.8048 7.72819 15.982 7.87308 16.1269C8.01794 16.2718 8.19358 16.3442 8.39998 16.3442C8.60638 16.3442 8.78201 16.2718 8.92688 16.1269L12 13.0538ZM12.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.29657C3.74667 7.14042 4.42342 6.13474 5.27825 5.27952C6.1331 4.42429 7.13834 3.74723 8.29398 3.24835C9.44959 2.74947 10.6844 2.50002 11.9983 2.50002C13.3122 2.50002 14.5473 2.74936 15.7034 3.24802C16.8596 3.74669 17.8652 4.42344 18.7205 5.27827C19.5757 6.13312 20.2527 7.13837 20.7516 8.294C21.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.7516C14.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.875 17.675 6.325C16.125 4.775 14.2333 4 12 4C9.76664 4 7.87498 4.775 6.32498 6.325C4.77498 7.875 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" })
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
export { n as IconCancel, t as IconSearch };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { InputProps } from '../input';
|
|
2
|
+
/**
|
|
3
|
+
* Style recipe for InputSearch. Slots: `input` (hides the browser's own
|
|
4
|
+
* cancel button and search decoration, so the field shows only the clear
|
|
5
|
+
* button it draws) and `clear` (the clear button, the same 24px icon button
|
|
6
|
+
* as the Combobox clear, removed while the input is disabled).
|
|
7
|
+
*
|
|
8
|
+
* @summary tailwind-variants recipe backing the InputSearch input and clear button
|
|
9
|
+
*/
|
|
10
|
+
export declare const inputSearchRecipe: import('tailwind-variants').TVReturnType<{
|
|
11
|
+
[key: string]: {
|
|
12
|
+
[key: string]: import('tailwind-merge').ClassNameValue | {
|
|
13
|
+
input?: import('tailwind-merge').ClassNameValue;
|
|
14
|
+
clear?: import('tailwind-merge').ClassNameValue;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
} | {
|
|
18
|
+
[x: string]: {
|
|
19
|
+
[x: string]: import('tailwind-merge').ClassNameValue | {
|
|
20
|
+
input?: import('tailwind-merge').ClassNameValue;
|
|
21
|
+
clear?: import('tailwind-merge').ClassNameValue;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
} | {}, {
|
|
25
|
+
input: string;
|
|
26
|
+
clear: string[];
|
|
27
|
+
}, undefined, {
|
|
28
|
+
[key: string]: {
|
|
29
|
+
[key: string]: import('tailwind-merge').ClassNameValue | {
|
|
30
|
+
input?: import('tailwind-merge').ClassNameValue;
|
|
31
|
+
clear?: import('tailwind-merge').ClassNameValue;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
} | {}, {
|
|
35
|
+
input: string;
|
|
36
|
+
clear: string[];
|
|
37
|
+
}, import('tailwind-variants').TVReturnType<unknown, {
|
|
38
|
+
input: string;
|
|
39
|
+
clear: string[];
|
|
40
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
41
|
+
export type InputSearchProps = Omit<InputProps, 'type'> & {
|
|
42
|
+
/**
|
|
43
|
+
* Shows a spinner at the end of the frame, in place of the clear button,
|
|
44
|
+
* while the results for the current text are on their way. Defaults to
|
|
45
|
+
* `false`.
|
|
46
|
+
*/
|
|
47
|
+
isLoading?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Accessible name of the clear button. Defaults to `'Clear search'`; name it
|
|
50
|
+
* after what is searched (`'Clear agency search'`) when a page carries
|
|
51
|
+
* several search fields.
|
|
52
|
+
*/
|
|
53
|
+
clearLabel?: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* InputSearch is a search field: a magnifier in front of the text and, once
|
|
57
|
+
* there is text, a clear button after it, named "Clear search" unless
|
|
58
|
+
* `clearLabel` says otherwise. The clear button empties the field
|
|
59
|
+
* and puts focus back in it, and it reports the change through `onChange` like
|
|
60
|
+
* a keystroke would: a real change event whose `event.target.value` is `''`,
|
|
61
|
+
* so a controlled field, an uncontrolled one and one registered with
|
|
62
|
+
* react-hook-form all clear the same way. While `isLoading` is set, a spinner
|
|
63
|
+
* takes the clear button's place. The clear button is not rendered while the
|
|
64
|
+
* input is disabled, whether `disabled` comes from the prop, from a
|
|
65
|
+
* surrounding `FieldText` or from a `<fieldset disabled>`.
|
|
66
|
+
*
|
|
67
|
+
* It is an [Input](?path=/docs/components-input--docs) of `type="search"`
|
|
68
|
+
* inside an [InputGroup](?path=/docs/components-inputgroup--docs) frame, so
|
|
69
|
+
* it is announced as a search box. `className` styles the frame. Every other
|
|
70
|
+
* prop goes to the `<input>`: the `ref`, `id`, `name`, `value`, `onChange`,
|
|
71
|
+
* `aria-*` and every other standard attribute. Only `type` is not accepted.
|
|
72
|
+
* `placeholder` defaults to `'Search'`. Inside a `FieldText` the input takes
|
|
73
|
+
* its label, messages and states from the field as a plain `Input` does. The
|
|
74
|
+
* invalid state comes from `aria-invalid`, and the frame paints the
|
|
75
|
+
* destructive border.
|
|
76
|
+
*
|
|
77
|
+
* Do not use it to pick a value from a list; that is
|
|
78
|
+
* [Combobox](?path=/docs/components-combobox--docs), whose `search` field is
|
|
79
|
+
* drawn by InputSearch. For a filter that should
|
|
80
|
+
* run only once the user pauses typing, use `DebouncedInputSearch`.
|
|
81
|
+
*
|
|
82
|
+
* @summary Search input with a leading icon, a clear button and a loading slot
|
|
83
|
+
* @dataAttribute {string} data-slot - Always set to "input-search" on the frame
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* <InputSearch
|
|
87
|
+
* aria-label="Search agencies"
|
|
88
|
+
* value={query}
|
|
89
|
+
* onChange={event => setQuery(event.target.value)}
|
|
90
|
+
* isLoading={isFetching}
|
|
91
|
+
* />
|
|
92
|
+
*/
|
|
93
|
+
export declare const InputSearch: {
|
|
94
|
+
({ className, isLoading, clearLabel, placeholder, ref, onChange, ...props }: InputSearchProps): import("react/jsx-runtime").JSX.Element;
|
|
95
|
+
displayName: string;
|
|
96
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { chain as e, mergeRefs as t } from "../../lib/merge-props.js";
|
|
3
|
+
import { InputContext as n } from "../input/context.js";
|
|
4
|
+
import { Input as r } from "../input/input.js";
|
|
5
|
+
import { InputGroup as i } from "../input-group/index.js";
|
|
6
|
+
import { Loading as a } from "../loading/loading.js";
|
|
7
|
+
import { IconCancel as o, IconSearch as s } from "./icons.js";
|
|
8
|
+
import { tv as c } from "tailwind-variants";
|
|
9
|
+
import { use as l, useMemo as u, useRef as d, useState as f } from "react";
|
|
10
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
11
|
+
//#region src/input-search/input-search.tsx
|
|
12
|
+
var h = c({ slots: {
|
|
13
|
+
input: "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
|
|
14
|
+
clear: [
|
|
15
|
+
"flex size-6 shrink-0 cursor-pointer items-center justify-center self-center rounded-sm",
|
|
16
|
+
"[&>svg>path]:fill-icon-input-default hover:[&>svg>path]:fill-icon-default-base-primary",
|
|
17
|
+
"focus-visible:outline-2 focus-visible:outline-border-input-focus",
|
|
18
|
+
"disabled:cursor-default disabled:[&>svg>path]:fill-icon-input-disable",
|
|
19
|
+
"group-has-[input:disabled]/input-group:hidden"
|
|
20
|
+
]
|
|
21
|
+
} }), g = h(), _ = (e) => e !== void 0 && String(e) !== "", v = ({ className: c, isLoading: h = !1, clearLabel: v = "Clear search", placeholder: y = "Search", ref: b, onChange: x, ...S }) => {
|
|
22
|
+
let C = d(null), w = l(n)?.value, [T, E] = f(() => _(S.defaultValue)), D = S.value === void 0 ? w : S.value, O = D === void 0 ? T : _(D), k = (e) => E(e.target.value !== ""), A = u(() => t(C, b, (e) => {
|
|
23
|
+
e && E(e.value !== "");
|
|
24
|
+
}), [b]), j = () => {
|
|
25
|
+
let e = C.current;
|
|
26
|
+
e && (Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set?.call(e, ""), e.dispatchEvent(new Event("input", { bubbles: !0 })), e.focus());
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ m(i.Root, {
|
|
29
|
+
"data-slot": "input-search",
|
|
30
|
+
className: c,
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ p(i.Addon, { children: /* @__PURE__ */ p(s, {}) }),
|
|
33
|
+
/* @__PURE__ */ p(r, {
|
|
34
|
+
ref: A,
|
|
35
|
+
type: "search",
|
|
36
|
+
placeholder: y,
|
|
37
|
+
...S,
|
|
38
|
+
className: g.input(),
|
|
39
|
+
onChange: e(k, x)
|
|
40
|
+
}),
|
|
41
|
+
h ? /* @__PURE__ */ p(i.Addon, { children: /* @__PURE__ */ p(a, { size: "sm" }) }) : O && /* @__PURE__ */ p(i.Addon, { children: /* @__PURE__ */ p("button", {
|
|
42
|
+
type: "button",
|
|
43
|
+
className: g.clear(),
|
|
44
|
+
"aria-label": v,
|
|
45
|
+
onClick: j,
|
|
46
|
+
children: /* @__PURE__ */ p(o, {})
|
|
47
|
+
}) })
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
v.displayName = "InputSearch";
|
|
52
|
+
//#endregion
|
|
53
|
+
export { v as InputSearch, h as inputSearchRecipe };
|