@alfadocs/ui-kit-debug 1.81.0 → 1.83.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.
Files changed (143) hide show
  1. package/dist/_chunks/{anamnesis-summary-rows-BYtpwCyn.js → anamnesis-summary-rows-6gMuu0ZK.js} +2 -2
  2. package/dist/_chunks/{anamnesis-summary-rows-BYtpwCyn.js.map → anamnesis-summary-rows-6gMuu0ZK.js.map} +1 -1
  3. package/dist/_chunks/{balance-badge-cell-NoEPeFdj.js → balance-badge-cell-BHXJS8Ga.js} +2 -2
  4. package/dist/_chunks/{balance-badge-cell-NoEPeFdj.js.map → balance-badge-cell-BHXJS8Ga.js.map} +1 -1
  5. package/dist/_chunks/booking-dsgiuhKg.js +4304 -0
  6. package/dist/_chunks/booking-dsgiuhKg.js.map +1 -0
  7. package/dist/_chunks/{link-cell-renderer-Dwp_DCYT.js → link-cell-renderer-C0ynDik7.js} +2 -2
  8. package/dist/_chunks/{link-cell-renderer-Dwp_DCYT.js.map → link-cell-renderer-C0ynDik7.js.map} +1 -1
  9. package/dist/_chunks/login-dev-card-DYwbL5sD.js +385 -0
  10. package/dist/_chunks/login-dev-card-DYwbL5sD.js.map +1 -0
  11. package/dist/_chunks/{multi-select-IOVnOGlP.js → multi-select-i5MFRpXg.js} +153 -146
  12. package/dist/_chunks/multi-select-i5MFRpXg.js.map +1 -0
  13. package/dist/_chunks/{otp-input-BgEZi0py.js → otp-input-gV1446Dw.js} +70 -70
  14. package/dist/_chunks/otp-input-gV1446Dw.js.map +1 -0
  15. package/dist/_chunks/{registration-form-e9oYscB7.js → registration-form-DmP3YUfp.js} +2 -2
  16. package/dist/_chunks/{registration-form-e9oYscB7.js.map → registration-form-DmP3YUfp.js.map} +1 -1
  17. package/dist/agent-catalog.json +5 -5
  18. package/dist/agent-i18n/en.json +2 -2
  19. package/dist/components/booking/booking-types.d.ts +35 -2
  20. package/dist/components/booking/booking-types.d.ts.map +1 -1
  21. package/dist/components/booking/booking.d.ts.map +1 -1
  22. package/dist/components/booking/code-step.d.ts +4 -2
  23. package/dist/components/booking/code-step.d.ts.map +1 -1
  24. package/dist/components/booking/details-form.d.ts +2 -0
  25. package/dist/components/booking/details-form.d.ts.map +1 -1
  26. package/dist/components/booking/handover.d.ts +12 -0
  27. package/dist/components/booking/handover.d.ts.map +1 -0
  28. package/dist/components/booking/index.js +1 -1
  29. package/dist/components/booking/reserved.d.ts +24 -0
  30. package/dist/components/booking/reserved.d.ts.map +1 -0
  31. package/dist/components/booking/use-booking-payment.d.ts +3 -1
  32. package/dist/components/booking/use-booking-payment.d.ts.map +1 -1
  33. package/dist/components/data-table/index.js +1 -1
  34. package/dist/components/multi-select/index.js +1 -1
  35. package/dist/components/multi-select/multi-select.d.ts.map +1 -1
  36. package/dist/components/otp-input/index.js +1 -1
  37. package/dist/components/otp-input/otp-input.d.ts +1 -1
  38. package/dist/components/otp-input/otp-input.d.ts.map +1 -1
  39. package/dist/components/patient-table/index.js +1 -1
  40. package/dist/i18n/locales/ar.d.ts +8 -0
  41. package/dist/i18n/locales/ar.d.ts.map +1 -1
  42. package/dist/i18n/locales/ar.js +8 -0
  43. package/dist/i18n/locales/ar.js.map +1 -1
  44. package/dist/i18n/locales/de.d.ts +8 -0
  45. package/dist/i18n/locales/de.d.ts.map +1 -1
  46. package/dist/i18n/locales/de.js +8 -0
  47. package/dist/i18n/locales/de.js.map +1 -1
  48. package/dist/i18n/locales/el.d.ts +8 -0
  49. package/dist/i18n/locales/el.d.ts.map +1 -1
  50. package/dist/i18n/locales/el.js +8 -0
  51. package/dist/i18n/locales/el.js.map +1 -1
  52. package/dist/i18n/locales/en.d.ts +8 -0
  53. package/dist/i18n/locales/en.d.ts.map +1 -1
  54. package/dist/i18n/locales/en.js +8 -0
  55. package/dist/i18n/locales/en.js.map +1 -1
  56. package/dist/i18n/locales/es.d.ts +8 -0
  57. package/dist/i18n/locales/es.d.ts.map +1 -1
  58. package/dist/i18n/locales/es.js +8 -0
  59. package/dist/i18n/locales/es.js.map +1 -1
  60. package/dist/i18n/locales/fr.d.ts +8 -0
  61. package/dist/i18n/locales/fr.d.ts.map +1 -1
  62. package/dist/i18n/locales/fr.js +8 -0
  63. package/dist/i18n/locales/fr.js.map +1 -1
  64. package/dist/i18n/locales/hi.d.ts +8 -0
  65. package/dist/i18n/locales/hi.d.ts.map +1 -1
  66. package/dist/i18n/locales/hi.js +8 -0
  67. package/dist/i18n/locales/hi.js.map +1 -1
  68. package/dist/i18n/locales/it.d.ts +8 -0
  69. package/dist/i18n/locales/it.d.ts.map +1 -1
  70. package/dist/i18n/locales/it.js +8 -0
  71. package/dist/i18n/locales/it.js.map +1 -1
  72. package/dist/i18n/locales/ja.d.ts +8 -0
  73. package/dist/i18n/locales/ja.d.ts.map +1 -1
  74. package/dist/i18n/locales/ja.js +8 -0
  75. package/dist/i18n/locales/ja.js.map +1 -1
  76. package/dist/i18n/locales/nl.d.ts +8 -0
  77. package/dist/i18n/locales/nl.d.ts.map +1 -1
  78. package/dist/i18n/locales/nl.js +8 -0
  79. package/dist/i18n/locales/nl.js.map +1 -1
  80. package/dist/i18n/locales/pl.d.ts +8 -0
  81. package/dist/i18n/locales/pl.d.ts.map +1 -1
  82. package/dist/i18n/locales/pl.js +8 -0
  83. package/dist/i18n/locales/pl.js.map +1 -1
  84. package/dist/i18n/locales/pt.d.ts +8 -0
  85. package/dist/i18n/locales/pt.d.ts.map +1 -1
  86. package/dist/i18n/locales/pt.js +8 -0
  87. package/dist/i18n/locales/pt.js.map +1 -1
  88. package/dist/i18n/locales/ro.d.ts +8 -0
  89. package/dist/i18n/locales/ro.d.ts.map +1 -1
  90. package/dist/i18n/locales/ro.js +8 -0
  91. package/dist/i18n/locales/ro.js.map +1 -1
  92. package/dist/i18n/locales/ru.d.ts +8 -0
  93. package/dist/i18n/locales/ru.d.ts.map +1 -1
  94. package/dist/i18n/locales/ru.js +8 -0
  95. package/dist/i18n/locales/ru.js.map +1 -1
  96. package/dist/i18n/locales/sq.d.ts +8 -0
  97. package/dist/i18n/locales/sq.d.ts.map +1 -1
  98. package/dist/i18n/locales/sq.js +8 -0
  99. package/dist/i18n/locales/sq.js.map +1 -1
  100. package/dist/i18n/locales/sv.d.ts +8 -0
  101. package/dist/i18n/locales/sv.d.ts.map +1 -1
  102. package/dist/i18n/locales/sv.js +8 -0
  103. package/dist/i18n/locales/sv.js.map +1 -1
  104. package/dist/i18n/locales/tr.d.ts +8 -0
  105. package/dist/i18n/locales/tr.d.ts.map +1 -1
  106. package/dist/i18n/locales/tr.js +8 -0
  107. package/dist/i18n/locales/tr.js.map +1 -1
  108. package/dist/i18n/locales/zh.d.ts +8 -0
  109. package/dist/i18n/locales/zh.d.ts.map +1 -1
  110. package/dist/i18n/locales/zh.js +8 -0
  111. package/dist/i18n/locales/zh.js.map +1 -1
  112. package/dist/index.js +8 -8
  113. package/dist/locales/ar.json +8 -0
  114. package/dist/locales/de.json +8 -0
  115. package/dist/locales/el.json +8 -0
  116. package/dist/locales/en.json +8 -0
  117. package/dist/locales/es.json +8 -0
  118. package/dist/locales/fr.json +8 -0
  119. package/dist/locales/hi.json +8 -0
  120. package/dist/locales/it.json +8 -0
  121. package/dist/locales/ja.json +8 -0
  122. package/dist/locales/nl.json +8 -0
  123. package/dist/locales/pl.json +8 -0
  124. package/dist/locales/pt.json +8 -0
  125. package/dist/locales/ro.json +8 -0
  126. package/dist/locales/ru.json +8 -0
  127. package/dist/locales/sq.json +8 -0
  128. package/dist/locales/sv.json +8 -0
  129. package/dist/locales/tr.json +8 -0
  130. package/dist/locales/zh.json +8 -0
  131. package/dist/patterns/anamnesis/index.js +1 -1
  132. package/dist/patterns/login-form/index.js +1 -1
  133. package/dist/patterns/login-form/login-form.d.ts +7 -0
  134. package/dist/patterns/login-form/login-form.d.ts.map +1 -1
  135. package/dist/patterns/registration-form/index.js +1 -1
  136. package/dist/tokens.css +1 -1
  137. package/package.json +1 -1
  138. package/dist/_chunks/booking-CxrB0e6d.js +0 -4079
  139. package/dist/_chunks/booking-CxrB0e6d.js.map +0 -1
  140. package/dist/_chunks/login-dev-card-CvLHj-_N.js +0 -353
  141. package/dist/_chunks/login-dev-card-CvLHj-_N.js.map +0 -1
  142. package/dist/_chunks/multi-select-IOVnOGlP.js.map +0 -1
  143. package/dist/_chunks/otp-input-BgEZi0py.js.map +0 -1
@@ -1,353 +0,0 @@
1
- import { jsxs as f, jsx as s } from "react/jsx-runtime";
2
- import { forwardRef as ge, useId as M, useState as l, useEffect as le, useRef as ie } from "react";
3
- import { useTranslation as Se } from "react-i18next";
4
- import { c as E } from "./index-D2ZczOXr.js";
5
- import { i as me, E as qe } from "./email-input-C7THAwh2.js";
6
- import { B as pe } from "./button-DohK_Ak_.js";
7
- import { C as Pe } from "./checkbox-BjDv-r3o.js";
8
- import { C as v } from "./card-BA4Ig_kn.js";
9
- import { E as je } from "./error-summary-mGxIyDAY.js";
10
- import { F as ce } from "./form-field-CyHfOVKF.js";
11
- import { P as ze } from "./password-input-BokZ_rnT.js";
12
- import { i as De } from "./is-development-CLUAnsU7.js";
13
- import { i as he } from "./safe-href-5dbsfbQn.js";
14
- import { u as He } from "./use-state-backed-input-DhRQo6gM.js";
15
- import { u as Oe, a as Te, A as $e, b as _e, d as O, E as Ge, c as Ue } from "./auth-form-parts-B3GWChvG.js";
16
- import { u as We, b as Je, a as Ke } from "./use-registration-submit-CLGHxwoT.js";
17
- import { M as Qe } from "./matrix-rain-sDOUUwZp.js";
18
- import { a as Xe } from "./error-page-illustration-BdJLuMdV.js";
19
- const $ = ["email", "password"], Ye = E(
20
- "ds:flex ds:w-full ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-lg)] ds:text-start ds:text-[var(--foreground)] ds:lg:flex-row ds:lg:items-stretch"
21
- ), ue = E("ds:w-full ds:max-w-[400px]"), Ze = E(
22
- "ds:flex ds:flex-wrap ds:justify-center ds:gap-x-[var(--spacing-lg)] ds:gap-y-[var(--spacing-lg)]"
23
- ), T = (r) => r && he(r) ? r : void 0, Ve = (r) => Object.values(r).some(Boolean), es = (r) => $.some((i) => !!r[i]), fe = (r) => $.find((i) => r[i]) ?? (r.form ? "password" : void 0), ss = ge(
24
- ({
25
- title: r,
26
- description: i,
27
- headingLevel: b = 1,
28
- showLogo: I = !0,
29
- logoMotion: k = "assemble",
30
- children: w,
31
- initialValues: o,
32
- errors: u,
33
- forgotPasswordHref: L,
34
- showRememberMe: d = !1,
35
- registerDoctorHref: C,
36
- registerPatientHref: ve,
37
- submitLabel: be,
38
- submitting: we = !1,
39
- onSubmit: B,
40
- fieldNames: t,
41
- action: xe,
42
- hiddenFields: Fe,
43
- devCard: _,
44
- className: ye,
45
- ...Me
46
- }, Ee) => {
47
- const { t: n } = Se("ui"), G = M(), R = M(), Ie = M(), A = (e) => `${Ie}-${e}`, m = t !== void 0, [g, N] = l(() => (o == null ? void 0 : o.email) ?? ""), [x, F] = l(""), [U, ke] = l(
48
- () => (o == null ? void 0 : o.rememberMe) === !0
49
- ), S = d || !!(t != null && t.rememberMe), W = m && S && !(t != null && t.rememberMe);
50
- le(() => {
51
- W && De() && console.warn(
52
- "LoginForm: the remember-me box is shown but `fieldNames.rememberMe` is not set, so the server will not read it."
53
- );
54
- }, [W]);
55
- const [Le, J] = l(() => ({ email: !!(o != null && o.email) })), [Ce, K] = l(!1), [Q, X] = l(
56
- () => u ?? {}
57
- ), Y = (e) => J(
58
- (a) => a[e] ? a : { ...a, [e]: !0 }
59
- ), Z = (e) => X(
60
- (a) => a[e] ? { ...a, [e]: void 0 } : a
61
- ), q = ie(null), P = ie(null), V = He(g, q), ee = () => {
62
- F(""), J((e) => ({ ...e, password: !1 }));
63
- }, se = () => {
64
- var a, h;
65
- const e = {
66
- email: ((a = q.current) == null ? void 0 : a.value) ?? g,
67
- password: ((h = P.current) == null ? void 0 : h.value) ?? x,
68
- rememberMe: S && U
69
- };
70
- return e.email !== g && N(e.email), e.password !== x && F(e.password), e;
71
- }, re = {
72
- email: !me(g),
73
- password: x === ""
74
- }, ae = (e) => Ce || Le[e] === !0, Be = {
75
- email: ae("email") && re.email ? n(g === "" ? "loginForm.emailRequired" : "inputs.email.invalid") : void 0,
76
- password: ae("password") && re.password ? n("loginForm.passwordRequired") : void 0
77
- }, y = (e) => Q[e] ?? Be[e], [oe] = l(
78
- () => es(u ?? {})
79
- ), c = We(
80
- $,
81
- y,
82
- oe
83
- ), [j, te] = l(() => {
84
- const e = oe ? void 0 : fe(u ?? {});
85
- return e ? { target: e } : null;
86
- });
87
- le(() => {
88
- var e;
89
- j && ((e = (j.target === "email" ? q : P).current) == null || e.focus());
90
- }, [j]);
91
- const ne = Je({
92
- errors: u,
93
- submitting: we,
94
- native: m,
95
- captcha: !1,
96
- firstProblem: () => {
97
- const e = se();
98
- return me(e.email) ? e.password === "" ? "password" : void 0 : "email";
99
- },
100
- onRefused: (e) => {
101
- K(!0), c.open(() => te({ target: e }));
102
- },
103
- // Only a React host gets here: a native post is the browser's own.
104
- deliver: () => B == null ? void 0 : B(se()),
105
- onAnswer: (e) => {
106
- const a = e;
107
- X(a), Ve(a) && (ee(), K(!1), c.open(() => {
108
- const h = fe(a);
109
- h && te({ target: h });
110
- }));
111
- },
112
- // The page came back from the browser's cache as it was left: the
113
- // password must not come back with it.
114
- onRestore: ee
115
- }), { busy: z } = ne, Re = Oe("LoginForm", m, xe), de = T(L), D = T(C), H = T(ve), Ae = Te(
116
- "LoginForm",
117
- m,
118
- t,
119
- Fe
120
- ), p = Q.form, Ne = Ke(
121
- p,
122
- c.listed.length > 0
123
- );
124
- return /* @__PURE__ */ f(
125
- "div",
126
- {
127
- ref: Ee,
128
- ...Me,
129
- "data-component": "login-form",
130
- className: Ye({ className: ye }),
131
- children: [
132
- /* @__PURE__ */ s("div", { className: ue(), children: /* @__PURE__ */ s(v, { variant: "elevated", className: "ds:h-full", children: /* @__PURE__ */ f(v.Body, { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]", children: [
133
- /* @__PURE__ */ s(
134
- $e,
135
- {
136
- id: G,
137
- title: r ?? n("loginForm.title"),
138
- description: i,
139
- level: b,
140
- showLogo: I,
141
- logoMotion: k
142
- }
143
- ),
144
- w ? /* @__PURE__ */ s(
145
- "div",
146
- {
147
- "data-slot": "host-content",
148
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]",
149
- children: w
150
- }
151
- ) : null,
152
- /* @__PURE__ */ f(
153
- "form",
154
- {
155
- noValidate: !0,
156
- method: "post",
157
- action: Re,
158
- "aria-labelledby": G,
159
- "aria-busy": z || void 0,
160
- onSubmit: ne.handleSubmit,
161
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]",
162
- children: [
163
- /* @__PURE__ */ s(
164
- je,
165
- {
166
- ref: c.ref,
167
- headingLevel: b + 1,
168
- "aria-describedby": p ? R : void 0,
169
- errors: c.listed.map((e) => ({
170
- field: e,
171
- message: y(e) ?? "",
172
- targetId: A(e)
173
- }))
174
- }
175
- ),
176
- p && /* @__PURE__ */ s(
177
- _e,
178
- {
179
- id: R,
180
- announce: Ne,
181
- children: p
182
- }
183
- ),
184
- /* @__PURE__ */ s(
185
- ce,
186
- {
187
- id: A("email"),
188
- label: n("loginForm.email"),
189
- required: !0,
190
- error: y("email"),
191
- announceError: !c.lists("email"),
192
- "data-field": "email",
193
- children: /* @__PURE__ */ s(
194
- qe,
195
- {
196
- ref: V.ref,
197
- name: m ? t.email : "email",
198
- autoComplete: "username",
199
- disableBuiltInValidation: !0,
200
- onChange: V.quiet((e) => {
201
- N(e.target.value), Z("email");
202
- }),
203
- onBlur: (e) => {
204
- N(e.target.value), e.target.value !== "" && Y("email");
205
- }
206
- }
207
- )
208
- }
209
- ),
210
- /* @__PURE__ */ s(
211
- ce,
212
- {
213
- id: A("password"),
214
- label: n("loginForm.password"),
215
- required: !0,
216
- error: y("password"),
217
- announceError: !c.lists("password"),
218
- "data-field": "password",
219
- children: /* @__PURE__ */ s(
220
- ze,
221
- {
222
- ref: P,
223
- name: m ? t.password : "password",
224
- autoComplete: "current-password",
225
- "aria-describedby": p ? R : void 0,
226
- value: x,
227
- onChange: (e) => {
228
- F(e.target.value), Z("password");
229
- },
230
- onBlur: (e) => {
231
- F(e.target.value), e.target.value !== "" && Y("password");
232
- }
233
- }
234
- )
235
- }
236
- ),
237
- de && /* @__PURE__ */ s(
238
- O,
239
- {
240
- href: de,
241
- action: "forgot-password",
242
- align: "end",
243
- children: n("loginForm.forgot")
244
- }
245
- ),
246
- S && /* @__PURE__ */ s("div", { "data-field": "remember-me", children: /* @__PURE__ */ s(
247
- Pe,
248
- {
249
- name: m && t.rememberMe || "rememberMe",
250
- checked: U,
251
- onCheckedChange: (e) => ke(e === !0),
252
- label: n("loginForm.rememberMe")
253
- }
254
- ) }),
255
- /* @__PURE__ */ s(Ge, { fields: Ae }),
256
- /* @__PURE__ */ s(
257
- pe,
258
- {
259
- type: "submit",
260
- intent: "primary",
261
- size: "lg",
262
- loading: z,
263
- className: "ds:w-full",
264
- "data-action": "submit",
265
- children: be ?? n("loginForm.submit")
266
- }
267
- )
268
- ]
269
- }
270
- ),
271
- (D || H) && /* @__PURE__ */ f(
272
- "div",
273
- {
274
- "data-slot": "register-links",
275
- className: Ze(),
276
- children: [
277
- D && /* @__PURE__ */ s(O, { href: D, action: "register-doctor", children: n("signedOutHeader.registerDoctor") }),
278
- H && /* @__PURE__ */ s(O, { href: H, action: "register-patient", children: n("signedOutHeader.registerPatient") })
279
- ]
280
- }
281
- ),
282
- /* @__PURE__ */ s(Ue, { busy: z })
283
- ] }) }) }),
284
- _ ? /* @__PURE__ */ s("div", { className: ue(), children: _ }) : null
285
- ]
286
- }
287
- );
288
- }
289
- );
290
- ss.displayName = "LoginForm";
291
- const rs = E("ds:h-full ds:w-full"), as = ge(
292
- ({ title: r, options: i, headingLevel: b = 2, className: I, ...k }, w) => {
293
- const o = M(), u = `h${b}`, L = i.filter((d) => he(d.href));
294
- return /* @__PURE__ */ s(
295
- "div",
296
- {
297
- ref: w,
298
- ...k,
299
- "data-component": "login-dev-card",
300
- className: rs({ className: I }),
301
- children: /* @__PURE__ */ f(
302
- v,
303
- {
304
- variant: "elevated",
305
- "aria-labelledby": o,
306
- className: "ds:relative ds:isolate ds:flex ds:h-full ds:flex-col ds:overflow-hidden",
307
- children: [
308
- /* @__PURE__ */ s("div", { className: "ds:absolute ds:inset-0 ds:z-0 ds:[display:var(--accessible-off,block)]", children: /* @__PURE__ */ s(
309
- Qe,
310
- {
311
- glyphs: "hex",
312
- decay: "fast",
313
- mask: "center",
314
- maskRadius: "xl",
315
- className: "ds:size-full"
316
- }
317
- ) }),
318
- /* @__PURE__ */ s(v.Header, { className: "ds:relative ds:z-[1]", children: /* @__PURE__ */ f("div", { className: "ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-center", children: [
319
- /* @__PURE__ */ s("div", { className: "ds:[&>div]:w-24", children: /* @__PURE__ */ s(Xe, { mood: "melt" }) }),
320
- /* @__PURE__ */ s(
321
- u,
322
- {
323
- id: o,
324
- className: "type-title-card ds:text-[var(--foreground)]",
325
- children: r
326
- }
327
- )
328
- ] }) }),
329
- /* @__PURE__ */ s(v.Body, { className: "ds:relative ds:z-[1] ds:flex ds:flex-1 ds:flex-col ds:justify-center", children: /* @__PURE__ */ s("div", { className: "ds:mt-[var(--spacing-md)] ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]", children: L.map((d, C) => /* @__PURE__ */ s(
330
- pe,
331
- {
332
- asChild: !0,
333
- intent: "primary",
334
- startIcon: d.icon,
335
- className: "ds:min-h-[var(--min-target-size)] ds:w-full",
336
- children: /* @__PURE__ */ s("a", { href: d.href, "data-action": "dev-login", children: d.label })
337
- },
338
- `${C}:${d.href}`
339
- )) }) })
340
- ]
341
- }
342
- )
343
- }
344
- );
345
- }
346
- );
347
- as.displayName = "LoginDevCard";
348
- export {
349
- $ as L,
350
- as as a,
351
- ss as b
352
- };
353
- //# sourceMappingURL=login-dev-card-CvLHj-_N.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"login-dev-card-CvLHj-_N.js","sources":["../../src/patterns/login-form/login-form.tsx","../../src/patterns/login-form/login-dev-card.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* LoginForm — the sign-in card. */\n/* */\n/* One export for the card: the mark, the heading, email and password, */\n/* the way to a new password, the button and the ways to register. The */\n/* host keeps the page around it and every server rule. The card checks */\n/* what a browser can check, then hands the values to `onSubmit` or */\n/* posts a real form to the host's own field names. */\n/* */\n/* The email must be an email address. A server that also signs people */\n/* in by a username cannot use this card for those accounts. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\n// The validator EmailInput itself uses, so the two never disagree.\nimport isEmail from 'validator/lib/isEmail';\nimport { Button } from '../../components/button';\nimport { Checkbox } from '../../components/checkbox';\nimport { Card } from '../../components/card';\nimport { EmailInput } from '../../components/email-input';\nimport { ErrorSummary } from '../../components/error-summary';\nimport { FormField } from '../../components/form-field';\nimport { PasswordInput } from '../../components/password-input';\nimport { isDevelopment } from '../../components/_shared/is-development';\nimport { isSafeHref } from '../../components/_shared/safe-href';\nimport { useStateBackedInput } from '../../components/_shared/use-state-backed-input';\nimport {\n AuthCardHeading,\n AuthFormMessage,\n AuthFormStatus,\n AuthTextLink,\n ExtraFields,\n useExtraFields,\n useFormAction,\n} from '../_shared/auth-form-parts';\nimport type { BrandMarkMotion } from '../_shared/brand-mark';\nimport {\n useErrorSummary,\n useFormMessageAnnounce,\n} from '../_shared/use-error-summary';\nimport { useRegistrationSubmit } from '../registration-form/use-registration-submit';\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** The fields of the form, in the order they appear. */\nexport const LOGIN_FORM_FIELDS = ['email', 'password'] as const;\n\nexport type LoginFormField = (typeof LOGIN_FORM_FIELDS)[number];\n\n/** What `onSubmit` receives once both checks have passed. */\nexport interface LoginFormValues {\n email: string;\n password: string;\n /** True when the \"Remember me\" box is ticked. Always false when the\n * box is not shown. */\n rememberMe: boolean;\n}\n\n/** Values to show when the form opens. There is no password here, on\n * purpose: a password is never sent back to the browser. */\nexport type LoginFormInitialValues = Partial<\n Pick<LoginFormValues, 'email' | 'rememberMe'>\n>;\n\n/** Messages from the server, already translated: one per field, plus\n * `form` for a message about the whole form, such as \"the email or\n * password is incorrect\". */\nexport type LoginFormErrors = Partial<Record<LoginFormField | 'form', string>>;\n\n/** The host's own form field names, for a native form post. `email` and\n * `password` are needed: a field without a name is not posted.\n * `rememberMe` is optional and also turns the \"Remember me\" box on. */\nexport type LoginFormFieldNames = Record<LoginFormField, string> & {\n rememberMe?: string;\n};\n\nexport interface LoginFormProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title' | 'onSubmit'\n> {\n /** Replaces the heading \"Sign in to Alfadocs\". Pass it translated. */\n title?: string;\n /** A line under the heading. Pass it translated. */\n description?: string;\n /**\n * The heading's level. Default 1: a sign-in page usually has no other\n * heading. Pass 2 on a page that has its own `h1`.\n */\n headingLevel?: 1 | 2 | 3;\n /**\n * Shows the Alfadocs mark above the heading, with the heading and its\n * line centred under it. Default true. With `false` the heading sits\n * at the start edge, for a host that shows its own logo.\n */\n showLogo?: boolean;\n /**\n * How the mark arrives when the card opens: its pieces come together\n * (`assemble`, the default), it turns once (`spin`), it beats\n * (`pulse`), or it is still (`none`). It plays once and rests, and\n * holds still under reduced motion and in the accessible themes.\n */\n logoMotion?: BrandMarkMotion;\n /**\n * Host content between the heading and the fields, such as a notice\n * (\"You have been signed out\"). It sits outside the form, so nothing in\n * it is posted. Keep any heading inside it below the card's own level.\n */\n children?: ReactNode;\n /** The email to show when the form opens, such as the one last used,\n * and whether \"Remember me\" starts ticked (default false). Read once.\n * There is never an initial password. */\n initialValues?: LoginFormInitialValues;\n /**\n * Messages from the server, already translated. A field's message\n * shows on that field until the user changes it; `form` shows above\n * the fields.\n *\n * When messages arrive, the password is emptied and focus moves: to\n * the error summary at the top of the form, which lists each field\n * with a message, or, when only `form` says something, to the\n * password, which is then described by that message. The same happens\n * for messages present when the form opens (a page the server rendered\n * after a failed post).\n *\n * Never say which of the two values was wrong: one message for both.\n * Set `submitting` while you send, so the form also notices an answer\n * that says the same as the last one.\n */\n errors?: LoginFormErrors;\n /**\n * Adds \"Forgot password?\" under the password. A path on the same site,\n * or an address written in full (`https://…`). Anything else shows no\n * link. The same rule holds for the two addresses below.\n */\n forgotPasswordHref?: string;\n /**\n * Adds a \"Remember me on this computer\" box under the password, unticked\n * by default. Off unless you set this or name the box in\n * `fieldNames.rememberMe`. What \"remember\" means is the server's: the\n * kit only reports the box (`rememberMe` in `onSubmit`, or the posted\n * field).\n */\n showRememberMe?: boolean;\n /** Adds \"Register as a doctor\" under the button. */\n registerDoctorHref?: string;\n /** Adds \"Register as a patient\" under the button. */\n registerPatientHref?: string;\n /** Replaces the button's \"Sign in\". Pass it translated. */\n submitLabel?: string;\n /**\n * True while the host sends the values: the button shows a spinner and\n * a second submit is ignored. Set it inside `onSubmit`, before anything\n * is awaited: until it is true, a second press sends a second sign-in.\n */\n submitting?: boolean;\n /** For React hosts: called with the values once both checks have\n * passed. Not called when `fieldNames` is set. */\n onSubmit?: (values: LoginFormValues) => void;\n /**\n * For a native form post: the host's own field names, both of them,\n * e.g. `{ email: 'email', password: 'password' }`. When set, the inputs\n * carry these names and the browser posts the form. Add `rememberMe`\n * (e.g. `'_remember_me'`) to show the \"Remember me\" box: ticked, it posts\n * `<name>=on`; unticked, it posts nothing.\n */\n fieldNames?: LoginFormFieldNames;\n /**\n * Where a native form post goes. Default: the current address. Only a\n * path, or an address on the page's own origin, is accepted: another\n * origin is never sent what the user typed, and the post then goes to\n * the current address. Does nothing without `fieldNames`.\n */\n action?: string;\n /**\n * Extra hidden inputs posted with a native form, by name: a CSRF token,\n * a return address. Not used with `onSubmit`. A name that is also one\n * of `fieldNames` is left out: the form's own field wins. The server\n * must check a return address itself: anyone can change a hidden input.\n */\n hiddenFields?: Readonly<Record<string, string>>;\n /**\n * A second card beside the sign-in, the same height: the development\n * quick sign-in (`LoginDevCard`). Pass it only when the server says\n * this is a development environment: the kit never decides that\n * itself. The two sit side by side where there is room and stack on a\n * phone.\n */\n devCard?: ReactNode;\n}\n\n/* -------------------------------------------------------------------- */\n/* Styles */\n/* -------------------------------------------------------------------- */\n\n// The card is 400px wide at most, written in px: a host whose root font\n// size is not 16px would stretch or squeeze a width in rem.\nconst loginFormVariants = cva(\n 'ds:flex ds:w-full ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-lg)] ds:text-start ds:text-[var(--foreground)] ds:lg:flex-row ds:lg:items-stretch',\n);\n\nconst columnVariants = cva('ds:w-full ds:max-w-[400px]');\n\n// The two ways to register, side by side where they fit. The row gap\n// keeps the links' 44px touch targets apart when they wrap.\nconst registerLinksVariants = cva(\n 'ds:flex ds:flex-wrap ds:justify-center ds:gap-x-[var(--spacing-lg)] ds:gap-y-[var(--spacing-lg)]',\n);\n\n/* -------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------- */\n\n/** An address a link may use, or nothing. */\nconst linkTo = (href: string | undefined): string | undefined =>\n href && isSafeHref(href) ? href : undefined;\n\nconst hasMessage = (errors: LoginFormErrors): boolean =>\n Object.values(errors).some(Boolean);\n\nconst hasFieldMessage = (errors: LoginFormErrors): boolean =>\n LOGIN_FORM_FIELDS.some((field) => Boolean(errors[field]));\n\n/**\n * Where to send the user for a set of server messages: the first field\n * that has one. A message about the whole form sends them to the\n * password, the field they will have to type again.\n */\nconst focusTargetFor = (\n messages: LoginFormErrors,\n): LoginFormField | undefined =>\n LOGIN_FORM_FIELDS.find((field) => messages[field]) ??\n (messages.form ? 'password' : undefined);\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\n/**\n * The sign-in card. Mount it on the login page, inside `SignedOutFrame`\n * or the host's own chrome.\n */\nexport const LoginForm = forwardRef<HTMLDivElement, LoginFormProps>(\n (\n {\n title,\n description,\n headingLevel = 1,\n showLogo = true,\n logoMotion = 'assemble',\n children,\n initialValues,\n errors,\n forgotPasswordHref,\n showRememberMe = false,\n registerDoctorHref,\n registerPatientHref,\n submitLabel,\n submitting = false,\n onSubmit,\n fieldNames,\n action,\n hiddenFields,\n devCard,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const titleId = useId();\n const formMessageId = useId();\n const fieldIdBase = useId();\n /** The id of a field's wrapper: where the summary's link leads. */\n const fieldId = (field: LoginFormField) => `${fieldIdBase}-${field}`;\n const native = fieldNames !== undefined;\n\n /* ------------------------------ State ----------------------------- */\n\n // Read once. The password always starts empty.\n const [email, setEmail] = useState(() => initialValues?.email ?? '');\n const [password, setPassword] = useState('');\n const [rememberMe, setRememberMe] = useState(\n () => initialValues?.rememberMe === true,\n );\n const rememberShown = showRememberMe || Boolean(fieldNames?.rememberMe);\n const rememberUnnamed = native && rememberShown && !fieldNames?.rememberMe;\n useEffect(() => {\n if (rememberUnnamed && isDevelopment()) {\n console.warn(\n 'LoginForm: the remember-me box is shown but `fieldNames.rememberMe` is not set, so the server will not read it.',\n );\n }\n }, [rememberUnnamed]);\n // A field the user has filled in and left. An email that arrives\n // filled in counts: a bad one is then flagged at once, with its\n // message. An empty field is not flagged for being passed through: a\n // keyboard user on the way to \"Forgot password?\" has made no mistake.\n // Its message waits for a submit.\n const [touched, setTouched] = useState<\n Partial<Record<LoginFormField, boolean>>\n >(() => ({ email: Boolean(initialValues?.email) }));\n const [submitted, setSubmitted] = useState(false);\n const [serverErrors, setServerErrors] = useState<LoginFormErrors>(\n () => errors ?? {},\n );\n\n const leave = (field: LoginFormField) =>\n setTouched((previous) =>\n previous[field] ? previous : { ...previous, [field]: true },\n );\n // The server's message was about the old value.\n const forget = (field: LoginFormField) =>\n setServerErrors((previous) =>\n previous[field] ? { ...previous, [field]: undefined } : previous,\n );\n\n const emailInput = useRef<HTMLInputElement>(null);\n const passwordInput = useRef<HTMLInputElement>(null);\n // The address stays out of the input's `value` attribute, where a\n // copied outerHTML or a session replay could read it.\n const emailField = useStateBackedInput(email, emailInput);\n\n const emptyPassword = () => {\n setPassword('');\n setTouched((previous) => ({ ...previous, password: false }));\n };\n /**\n * What the two inputs hold now. Read from the inputs, not from state:\n * a browser or a password manager can fill a field without telling\n * React, and the form must not refuse a field that is visibly filled.\n */\n const held = (): LoginFormValues => {\n const values: LoginFormValues = {\n email: emailInput.current?.value ?? email,\n password: passwordInput.current?.value ?? password,\n rememberMe: rememberShown && rememberMe,\n };\n if (values.email !== email) setEmail(values.email);\n if (values.password !== password) setPassword(values.password);\n return values;\n };\n\n /* ---------------------------- Validation -------------------------- */\n\n /** What stops a submit, whether or not the message shows yet. The\n * password only has to be there: its rules are for a new password. */\n const invalid: Record<LoginFormField, boolean> = {\n email: !isEmail(email),\n password: password === '',\n };\n // A message shows once the user has filled in and left the field, or\n // tried to submit.\n const due = (field: LoginFormField) => submitted || touched[field] === true;\n const ownErrors: Record<LoginFormField, string | undefined> = {\n email:\n due('email') && invalid.email\n ? email === ''\n ? t('loginForm.emailRequired')\n : t('inputs.email.invalid')\n : undefined,\n password:\n due('password') && invalid.password\n ? t('loginForm.passwordRequired')\n : undefined,\n };\n const errorFor = (field: LoginFormField) =>\n serverErrors[field] ?? ownErrors[field];\n\n /* ------------------------------ Focus ----------------------------- */\n\n // Every field with a message after a refused submit, or after a server\n // answer, is listed at the top of the form, and focus goes there. A\n // page the server rendered after a failed post opens that way too: it\n // announces nothing itself.\n const [openedWithFieldMessage] = useState(() =>\n hasFieldMessage(errors ?? {}),\n );\n const summary = useErrorSummary(\n LOGIN_FORM_FIELDS,\n errorFor,\n openedWithFieldMessage,\n );\n\n // Any other place focus goes: the password, when only the message\n // about the whole form says something. A new object for each request,\n // so asking twice for the same place moves focus twice. The effect runs\n // after the messages are drawn, so a screen reader lands on something\n // that already says what is wrong.\n const [focusRequest, setFocusRequest] = useState<{\n target: LoginFormField;\n } | null>(() => {\n const target = openedWithFieldMessage\n ? undefined\n : focusTargetFor(errors ?? {});\n return target ? { target } : null;\n });\n useEffect(() => {\n if (!focusRequest) return;\n (focusRequest.target === 'email'\n ? emailInput\n : passwordInput\n ).current?.focus();\n }, [focusRequest]);\n\n /* ------------------------------ Submit ---------------------------- */\n\n const submit = useRegistrationSubmit<LoginFormField>({\n errors,\n submitting,\n native,\n captcha: false,\n firstProblem: () => {\n const values = held();\n if (!isEmail(values.email)) return 'email';\n return values.password === '' ? 'password' : undefined;\n },\n onRefused: (field) => {\n // Both messages now show, listed in the summary, which takes focus.\n setSubmitted(true);\n summary.open(() => setFocusRequest({ target: field }));\n },\n // Only a React host gets here: a native post is the browser's own.\n deliver: () => onSubmit?.(held()),\n onAnswer: (answer) => {\n const next: LoginFormErrors = answer;\n setServerErrors(next);\n if (!hasMessage(next)) return;\n // Never keep a password the server did not accept.\n emptyPassword();\n setSubmitted(false);\n // The summary when a field has a message, else the password.\n summary.open(() => {\n const target = focusTargetFor(next);\n if (target) setFocusRequest({ target });\n });\n },\n // The page came back from the browser's cache as it was left: the\n // password must not come back with it.\n onRestore: emptyPassword,\n });\n const { busy } = submit;\n\n /* ------------------------------ Render ---------------------------- */\n\n const formAction = useFormAction('LoginForm', native, action);\n const forgotLink = linkTo(forgotPasswordHref);\n const doctorLink = linkTo(registerDoctorHref);\n const patientLink = linkTo(registerPatientHref);\n const extraFields = useExtraFields(\n 'LoginForm',\n native,\n fieldNames,\n hiddenFields,\n );\n const formError = serverErrors.form;\n // Quiet while the summary lists a field: the summary reads it then.\n const formMessageAnnounce = useFormMessageAnnounce(\n formError,\n summary.listed.length > 0,\n );\n\n return (\n <div\n ref={ref}\n {...rest}\n data-component=\"login-form\"\n className={loginFormVariants({ className })}\n >\n <div className={columnVariants()}>\n <Card variant=\"elevated\" className=\"ds:h-full\">\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]\">\n <AuthCardHeading\n id={titleId}\n title={title ?? t('loginForm.title')}\n description={description}\n level={headingLevel}\n showLogo={showLogo}\n logoMotion={logoMotion}\n />\n\n {children ? (\n <div\n data-slot=\"host-content\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {children}\n </div>\n ) : null}\n\n {/* Always POST, in both modes: should the script ever fail to\n run, the browser must not put a password in the address. */}\n <form\n noValidate\n method=\"post\"\n action={formAction}\n aria-labelledby={titleId}\n aria-busy={busy || undefined}\n onSubmit={submit.handleSubmit}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n <ErrorSummary\n ref={summary.ref}\n headingLevel={(headingLevel + 1) as 2 | 3 | 4}\n // The message about the whole form is read with it.\n aria-describedby={formError ? formMessageId : undefined}\n errors={summary.listed.map((field) => ({\n field,\n message: errorFor(field) ?? '',\n targetId: fieldId(field),\n }))}\n />\n\n {formError && (\n <AuthFormMessage\n id={formMessageId}\n announce={formMessageAnnounce}\n >\n {formError}\n </AuthFormMessage>\n )}\n\n <FormField\n id={fieldId('email')}\n label={t('loginForm.email')}\n required\n error={errorFor('email')}\n // Quiet while the summary lists it: the summary reads it.\n announceError={!summary.lists('email')}\n data-field=\"email\"\n >\n {/* One check, above, drives the message, the red mark and\n aria-invalid through FormField. EmailInput's own check\n is off so the two cannot disagree. `username` is the\n name browsers and password managers give the field\n that goes with `current-password`. */}\n <EmailInput\n ref={emailField.ref}\n name={native ? fieldNames.email : 'email'}\n autoComplete=\"username\"\n disableBuiltInValidation\n onChange={emailField.quiet((event) => {\n setEmail(event.target.value);\n forget('email');\n })}\n onBlur={(event) => {\n // Whatever a browser filled in without saying so.\n setEmail(event.target.value);\n if (event.target.value !== '') leave('email');\n }}\n />\n </FormField>\n\n <FormField\n id={fieldId('password')}\n label={t('loginForm.password')}\n required\n error={errorFor('password')}\n announceError={!summary.lists('password')}\n data-field=\"password\"\n >\n {/* Described by the message above the fields when there is\n one: focus lands here after a refused sign-in, and a\n screen reader then reads why. */}\n <PasswordInput\n ref={passwordInput}\n name={native ? fieldNames.password : 'password'}\n autoComplete=\"current-password\"\n aria-describedby={formError ? formMessageId : undefined}\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n forget('password');\n }}\n onBlur={(event) => {\n setPassword(event.target.value);\n if (event.target.value !== '') leave('password');\n }}\n />\n </FormField>\n\n {forgotLink && (\n <AuthTextLink\n href={forgotLink}\n action=\"forgot-password\"\n align=\"end\"\n >\n {t('loginForm.forgot')}\n </AuthTextLink>\n )}\n\n {rememberShown && (\n <div data-field=\"remember-me\">\n {/* No `value`: a ticked box posts `on`, which is what\n a server's remember-me reads. */}\n <Checkbox\n name={\n native\n ? fieldNames.rememberMe || 'rememberMe'\n : 'rememberMe'\n }\n checked={rememberMe}\n onCheckedChange={(next) => setRememberMe(next === true)}\n label={t('loginForm.rememberMe')}\n />\n </div>\n )}\n\n <ExtraFields fields={extraFields} />\n\n <Button\n type=\"submit\"\n intent=\"primary\"\n size=\"lg\"\n loading={busy}\n className=\"ds:w-full\"\n data-action=\"submit\"\n >\n {submitLabel ?? t('loginForm.submit')}\n </Button>\n </form>\n\n {/* Outside the form: they lead to other pages and post\n nothing. The header's own labels, already translated. */}\n {(doctorLink || patientLink) && (\n <div\n data-slot=\"register-links\"\n className={registerLinksVariants()}\n >\n {doctorLink && (\n <AuthTextLink href={doctorLink} action=\"register-doctor\">\n {t('signedOutHeader.registerDoctor')}\n </AuthTextLink>\n )}\n {patientLink && (\n <AuthTextLink href={patientLink} action=\"register-patient\">\n {t('signedOutHeader.registerPatient')}\n </AuthTextLink>\n )}\n </div>\n )}\n {/* Outside the form: a screen reader may hold back what\n changes inside a busy region. */}\n <AuthFormStatus busy={busy} />\n </Card.Body>\n </Card>\n </div>\n {devCard ? <div className={columnVariants()}>{devCard}</div> : null}\n </div>\n );\n },\n);\nLoginForm.displayName = 'LoginForm';\n","/* -------------------------------------------------------------------- */\n/* LoginDevCard — the development quick sign-in card. */\n/* */\n/* A second card beside the login, for developers: one link per test */\n/* account the host's server can sign in. The kit only draws it. The */\n/* host decides whether it is rendered, supplies every word on it, and */\n/* its server must refuse the routes outside development. */\n/* -------------------------------------------------------------------- */\n\nimport { forwardRef, useId, type HTMLAttributes, type ReactNode } from 'react';\nimport { cva } from 'class-variance-authority';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { MatrixRain } from '../../components/matrix-rain';\nimport { isSafeHref } from '../../components/_shared/safe-href';\nimport { ErrorPageIllustration } from '../error-page/error-page-illustration';\n\nexport interface LoginDevOption {\n /** The link's text, e.g. \"Sign in as admin\". The host supplies it, so\n * the kit ships no text for a card that users never see. */\n label: string;\n /** The development-only route that signs the test account in. A path\n * on the same site, or an address written in full. */\n href: string;\n /** A Lucide icon for the link, passed bare: `<ShieldUser />`. */\n icon?: ReactNode;\n}\n\nexport interface LoginDevCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /** The card's heading, e.g. \"Developer quick login\". */\n title: string;\n /** One link per test account. An option with an unsafe address is\n * left out. */\n options: readonly LoginDevOption[];\n /** The heading's level. Default 2, under the login's own heading. */\n headingLevel?: 2 | 3;\n}\n\n// As tall as the login beside it, so the two cards read as a pair.\nconst loginDevCardVariants = cva('ds:h-full ds:w-full');\n\n/**\n * The development quick sign-in card. Render it only when the server\n * says this is a development environment: it never checks the\n * environment itself. Pass it to `LoginForm` as `devCard`.\n */\nexport const LoginDevCard = forwardRef<HTMLDivElement, LoginDevCardProps>(\n ({ title, options, headingLevel = 2, className, ...rest }, ref) => {\n const titleId = useId();\n const Heading = `h${headingLevel}` as const;\n const links = options.filter((option) => isSafeHref(option.href));\n return (\n <div\n ref={ref}\n {...rest}\n data-component=\"login-dev-card\"\n className={loginDevCardVariants({ className })}\n >\n <Card\n variant=\"elevated\"\n aria-labelledby={titleId}\n className=\"ds:relative ds:isolate ds:flex ds:h-full ds:flex-col ds:overflow-hidden\"\n >\n {/* Code rain round the edges, clear in the middle so it never runs\n behind the links. MatrixRain holds still under reduced motion by\n itself; it does not know the accessible themes, so the rain is\n taken out there, like the kit's other decorative motion. */}\n <div className=\"ds:absolute ds:inset-0 ds:z-0 ds:[display:var(--accessible-off,block)]\">\n <MatrixRain\n glyphs=\"hex\"\n decay=\"fast\"\n mask=\"center\"\n maskRadius=\"xl\"\n className=\"ds:size-full\"\n />\n </div>\n <Card.Header className=\"ds:relative ds:z-[1]\">\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-center\">\n {/* The melting mark from the error pages, at half its size\n there. */}\n <div className=\"ds:[&>div]:w-24\">\n <ErrorPageIllustration mood=\"melt\" />\n </div>\n <Heading\n id={titleId}\n className=\"type-title-card ds:text-[var(--foreground)]\"\n >\n {title}\n </Heading>\n </div>\n </Card.Header>\n <Card.Body className=\"ds:relative ds:z-[1] ds:flex ds:flex-1 ds:flex-col ds:justify-center\">\n {/* The top margin keeps the heading clear of the links when the\n cards stack and this one is only as tall as its content. */}\n <div className=\"ds:mt-[var(--spacing-md)] ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n {links.map((option, index) => (\n <Button\n // Two options may share an address, so the place in the\n // list is part of the key.\n key={`${index}:${option.href}`}\n asChild\n intent=\"primary\"\n startIcon={option.icon}\n className=\"ds:min-h-[var(--min-target-size)] ds:w-full\"\n >\n <a href={option.href} data-action=\"dev-login\">\n {option.label}\n </a>\n </Button>\n ))}\n </div>\n </Card.Body>\n </Card>\n </div>\n );\n },\n);\nLoginDevCard.displayName = 'LoginDevCard';\n"],"names":["LOGIN_FORM_FIELDS","loginFormVariants","cva","columnVariants","registerLinksVariants","linkTo","href","isSafeHref","hasMessage","errors","hasFieldMessage","field","focusTargetFor","messages","LoginForm","forwardRef","title","description","headingLevel","showLogo","logoMotion","children","initialValues","forgotPasswordHref","showRememberMe","registerDoctorHref","registerPatientHref","submitLabel","submitting","onSubmit","fieldNames","action","hiddenFields","devCard","className","rest","ref","t","useTranslation","titleId","useId","formMessageId","fieldIdBase","fieldId","native","email","setEmail","useState","password","setPassword","rememberMe","setRememberMe","rememberShown","rememberUnnamed","useEffect","isDevelopment","touched","setTouched","submitted","setSubmitted","serverErrors","setServerErrors","leave","previous","forget","emailInput","useRef","passwordInput","emailField","useStateBackedInput","emptyPassword","held","values","_a","_b","invalid","isEmail","due","ownErrors","errorFor","openedWithFieldMessage","summary","useErrorSummary","focusRequest","setFocusRequest","target","submit","useRegistrationSubmit","answer","next","busy","formAction","useFormAction","forgotLink","doctorLink","patientLink","extraFields","useExtraFields","formError","formMessageAnnounce","useFormMessageAnnounce","jsxs","jsx","Card","AuthCardHeading","ErrorSummary","AuthFormMessage","FormField","EmailInput","event","PasswordInput","AuthTextLink","Checkbox","ExtraFields","Button","AuthFormStatus","loginDevCardVariants","LoginDevCard","options","Heading","links","option","MatrixRain","ErrorPageIllustration","index"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"multi-select-IOVnOGlP.js","sources":["../../src/components/multi-select/multi-select.agent.ts","../../src/components/multi-select/multi-select.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { MultiSelectHandle } from './multi-select';\n\nexport const multiSelectAgent: AgentAdapter<MultiSelectHandle> = {\n id: 'multi-select',\n // Persisted multi-choice (selection state + set_selection) → select_multiple,\n // plus type-to-filter and open/close of the option list.\n capabilities: ['select_multiple', 'filter', 'open', 'close'],\n state: {\n selection: {\n type: 'string[]',\n descriptionKey: 'ui.agent.multiSelect.state.selection',\n description: 'Values of currently-selected options.',\n read: (handle) => handle.getSelection(),\n },\n query: {\n type: 'string',\n descriptionKey: 'ui.agent.multiSelect.state.query',\n description: 'Current filter query.',\n read: (handle) => handle.getQuery(),\n },\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.multiSelect.state.isOpen',\n description: 'True when the option list is visible.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n set_selection: {\n // Persists the user's chosen options — reversible via the same UI.\n safety: 'write',\n argsType: '{ values: string[] }',\n argsSchema: {\n type: 'object',\n properties: {\n values: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'Option values to select (replaces the current selection).',\n },\n },\n required: ['values'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.setSelection',\n description:\n 'Replace the current selection with the given list of values.',\n examples: [\n {\n args: { values: ['a', 'b'] },\n note: 'Select exactly options \"a\" and \"b\".',\n },\n ],\n invoke: (handle, args: { values: string[] }) => {\n handle.setSelection(args.values);\n },\n },\n clear_selection: {\n // Discards the persisted selection — destructive (loses the choices).\n safety: 'destructive',\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.clearSelection',\n description: 'Clear the current selection.',\n invoke: (handle) => {\n handle.clearSelection();\n },\n },\n apply_filter: {\n // Pure ephemeral filter of the visible options — no persisted change.\n safety: 'read',\n argsType: '{ query: string }',\n argsSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Filter text for the list.' },\n },\n required: ['query'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.applyFilter',\n description: 'Set the filter query for the option list.',\n invoke: (handle, args: { query: string }) => {\n handle.setQuery(args.query);\n },\n },\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.open',\n description: 'Open the option list.',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.multiSelect.actions.close',\n description: 'Close the option list.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: { attr: 'data-component', value: 'multi-select' },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-option-id',\n description: 'Each option emits its value as data-option-id.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type Ref,\n} from 'react';\nimport * as Popover from '@radix-ui/react-popover';\nimport { Command } from 'cmdk';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Check, X } from 'lucide-react';\nimport {\n FormFieldContext,\n useFormField,\n useFormFieldControlRef,\n} from '../form-field/form-field-context';\nimport { Tooltip } from '../tooltip';\nimport type { OptionShape } from '../_shared/option';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useControllableState } from '../../hooks/use-controllable-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { groupOptions } from '../_shared/group-options';\nimport { MENU_ROW_HIGHLIGHT } from '../_shared/menu-row';\nimport {\n OPTION_BODY_CLASSES,\n OPTION_END_CLASSES,\n OPTION_LABEL_ROW_CLASSES,\n optionDescriptionVariants,\n optionLabelVariants,\n} from '../_shared/option-row';\nimport {\n INPUT_SURFACE_CHROME,\n INPUT_SURFACE_TEXT,\n} from '../_shared/input-surface';\nimport { useAgentRegistration } from '../../agent';\nimport { multiSelectAgent } from './multi-select.agent';\n\n// MultiSelect uses `min-h-*` (not `h-*`) because the wrapper grows vertically\n// as chips wrap to additional lines. The height floor per size mirrors the\n// other inputs' fixed heights in _shared/input-surface.ts.\nconst multiSelectVariants = cva(\n [\n 'ds:inline-flex ds:flex-wrap ds:items-center ds:gap-1 ds:w-full',\n INPUT_SURFACE_CHROME,\n 'ds:aria-[invalid=true]:border-destructive',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50',\n ],\n {\n variants: {\n size: {\n sm: `ds:min-h-8 ds:ps-2 ds:pe-2 ds:py-1 ${INPUT_SURFACE_TEXT.sm}`,\n md: `ds:min-h-[var(--min-target-size)] ds:ps-3 ds:pe-3 ds:py-1.5 ${INPUT_SURFACE_TEXT.md}`,\n lg: `ds:min-h-12 ds:ps-4 ds:pe-4 ds:py-2 ${INPUT_SURFACE_TEXT.lg}`,\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst chipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-1',\n 'ds:rounded-[var(--radius-sm)] ds:border ds:border-border ds:bg-muted',\n 'ds:text-foreground ds:select-none',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ],\n {\n variants: {\n size: {\n sm: 'ds:ps-2 ds:pe-1 ds:py-0.5 ds:text-[length:var(--font-size-xs)]',\n md: 'ds:ps-2 ds:pe-1 ds:py-0.5 ds:text-[length:var(--font-size-sm)]',\n lg: 'ds:ps-3 ds:pe-1.5 ds:py-1 ds:text-[length:var(--font-size-base)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst chipDismissClasses = [\n 'ds:inline-flex ds:items-center ds:justify-center ds:shrink-0',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-muted-foreground ds:hover:text-foreground',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:size-4',\n 'ds:relative ds:before:absolute ds:before:inset-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"]',\n].join(' ');\n\nconst popoverContentClasses = [\n 'ds:z-[var(--z-dropdown)] ds:overflow-hidden',\n // At least as wide as the field, at most as wide as the screen allows: a\n // long option wraps or ends in an ellipsis instead of running off the\n // edge. The floor gives way to the cap on a field wider than that.\n 'ds:min-w-[min(var(--radix-popover-trigger-width),var(--radix-popover-content-available-width))]',\n 'ds:max-w-[var(--radix-popover-content-available-width)]',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-border ds:bg-background ds:text-foreground',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:animate-in ds:fade-in ds:zoom-in-95',\n 'ds:data-[state=closed]:animate-out ds:data-[state=closed]:fade-out',\n 'ds:data-[state=closed]:zoom-out-95',\n 'ds:data-[side=bottom]:slide-in-from-top-2',\n 'ds:data-[side=top]:slide-in-from-bottom-2',\n 'ds:motion-reduce:animate-none',\n].join(' ');\n\nconst commandItemClasses = [\n 'ds:relative ds:flex ds:cursor-pointer ds:items-center',\n 'ds:rounded-[var(--radius-sm)] ds:ps-2 ds:pe-2 ds:py-1.5',\n 'ds:text-[var(--font-size-sm)] ds:text-foreground ds:outline-none ds:select-none',\n MENU_ROW_HIGHLIGHT.selected,\n 'ds:aria-[disabled=true]:pointer-events-none ds:aria-[disabled=true]:opacity-50',\n 'ds:data-[disabled=true]:pointer-events-none ds:data-[disabled=true]:opacity-50',\n].join(' ');\n\nconst actionItemClasses = [\n 'ds:relative ds:flex ds:cursor-pointer ds:items-center',\n 'ds:rounded-[var(--radius-sm)] ds:ps-2 ds:pe-2 ds:py-1.5',\n 'ds:text-[var(--font-size-sm)] ds:font-medium ds:text-primary ds:outline-none ds:select-none',\n MENU_ROW_HIGHLIGHT.selected,\n].join(' ');\n\nconst SELECT_ALL_VALUE = '__ui-multiselect-select-all__';\nconst CLEAR_ALL_VALUE = '__ui-multiselect-clear-all__';\n\ntype HTMLDivAttributes = HTMLAttributes<HTMLDivElement>;\n\n// Curated agent-readiness handle — see multi-select.agent.ts.\nexport interface MultiSelectHandle {\n getSelection: () => string[];\n getQuery: () => string;\n getIsOpen: () => boolean;\n setSelection: (values: string[]) => void;\n clearSelection: () => void;\n setQuery: (query: string) => void;\n open: () => void;\n close: () => void;\n}\n\nexport interface MultiSelectProps<T extends string = string>\n extends\n Omit<HTMLDivAttributes, 'onChange'>,\n VariantProps<typeof multiSelectVariants> {\n options: OptionShape<T>[];\n value?: T[];\n defaultValue?: T[];\n onChange?: (next: T[]) => void;\n onComplete?: (values: T[]) => void;\n placeholder?: string;\n maxSelections?: number;\n allowSelectAll?: boolean;\n allowClear?: boolean;\n filter?: (query: string, option: OptionShape<T>) => boolean;\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n /**\n * Let a long option label wrap onto a second line instead of ending in an\n * ellipsis. Longer still, it is clipped after two lines. Off by default.\n * An option's `description` always sits on its own line under the label.\n */\n wrapOptionLabels?: boolean;\n}\n\nconst MultiSelectImpl = forwardRef<HTMLDivElement, MultiSelectProps>(\n function MultiSelect(\n {\n options,\n value,\n defaultValue,\n onChange,\n onComplete,\n placeholder,\n maxSelections,\n allowSelectAll = false,\n allowClear = false,\n filter,\n size = 'md',\n disabled,\n wrapOptionLabels = false,\n className,\n id,\n // Pull `aria-label` out of the div spread so it names the combobox\n // INPUT (the interactive control) rather than the wrapper div. Lets a\n // consumer give the trigger a meaningful name when there's no visible\n // label or FormField (e.g. a data-table floating filter naming itself\n // after its column). Untouched callers fall back to the placeholder.\n // Inside a FormField the field's label names the input and this is\n // ignored, so it can never override the visible text (WCAG 2.5.3).\n 'aria-label': ariaLabel,\n ...divProps\n },\n ref,\n ) {\n const { t } = useTranslation('ui');\n const ctx = useFormField();\n const inFormField = useContext(FormFieldContext) !== null;\n\n const [currentValueRaw, setMultiSelectValue] = useControllableState<\n string[]\n >({\n value,\n defaultValue: defaultValue ?? [],\n onChange,\n });\n const currentValue = currentValueRaw ?? [];\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n\n const inputRef = useRef<HTMLInputElement>(null);\n const counterId = `${useId()}-count`;\n const chipRefs = useRef<Array<HTMLSpanElement | null>>([]);\n const triggerRef = useRef<HTMLDivElement>(null);\n const composedRef = composeRefs<HTMLDivElement>(ref, triggerRef);\n\n const effectiveDisabled =\n (inFormField && ctx.disabled) || Boolean(disabled);\n const effectiveRequired = inFormField && ctx.required;\n const effectiveInvalid = inFormField && ctx.invalid;\n const describedBy =\n inFormField && ctx.describedBy ? ctx.describedBy : undefined;\n const triggerId = id ?? (inFormField ? ctx.id : undefined);\n /* cmdk writes its own id on the input, so the field's label follows\n that one. */\n useFormFieldControlRef(ctx, inputRef);\n\n const labelByValue = useMemo(() => {\n const map = new Map<string, string>();\n for (const option of options) map.set(option.value, option.label);\n return map;\n }, [options]);\n const dirByValue = useMemo(() => {\n const map = new Map<string, OptionShape['dir']>();\n for (const option of options) map.set(option.value, option.dir);\n return map;\n }, [options]);\n\n const atCap =\n typeof maxSelections === 'number' && currentValue.length >= maxSelections;\n\n const commit = (next: string[]): void => {\n setMultiSelectValue(next);\n };\n\n const toggle = (val: string): void => {\n if (currentValue.includes(val)) {\n commit(currentValue.filter((v) => v !== val));\n return;\n }\n if (atCap) return;\n commit([...currentValue, val]);\n };\n\n const removeAt = (index: number): string[] => {\n const next = currentValue.filter((_, i) => i !== index);\n commit(next);\n return next;\n };\n\n const handleSelectAll = (): void => {\n const selectable = options.filter((o) => !o.disabled).map((o) => o.value);\n const cap =\n typeof maxSelections === 'number' ? maxSelections : selectable.length;\n commit(selectable.slice(0, cap));\n };\n\n const handleClearAll = (): void => {\n commit([]);\n };\n\n // Agent handle — refs for fresh reads from the memoized handle.\n const valueRef = useRef<string[]>(currentValue);\n useEffect(() => {\n valueRef.current = currentValue;\n }, [currentValue]);\n const queryRef = useRef<string>(query);\n useEffect(() => {\n queryRef.current = query;\n }, [query]);\n const openRef = useRef<boolean>(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const commitStable = useCallback(\n (next: string[]) => {\n setMultiSelectValue(next);\n },\n [setMultiSelectValue],\n );\n\n const agentHandle = useMemo<MultiSelectHandle>(\n () => ({\n getSelection: () => [...valueRef.current],\n getQuery: () => queryRef.current,\n getIsOpen: () => openRef.current,\n setSelection: (values) => commitStable(values),\n clearSelection: () => commitStable([]),\n setQuery: (next) => setQuery(next),\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [commitStable],\n );\n useAgentRegistration(multiSelectAgent, agentHandle, id);\n\n const resolvedPlaceholder =\n placeholder ?? t('inputs.multiSelect.placeholder', 'Select…');\n\n const filteredOptions = useMemo(() => {\n if (!query) return options;\n const needle = query.toLowerCase();\n return options.filter((option) => {\n if (filter) return filter(query, option);\n return option.label.toLowerCase().includes(needle);\n });\n }, [options, query, filter]);\n\n const groups = useMemo(\n () => groupOptions(filteredOptions),\n [filteredOptions],\n );\n\n const handleInputKeyDown = (e: KeyboardEvent<HTMLInputElement>): void => {\n const target = e.currentTarget;\n if (e.key === 'Backspace' && query === '' && currentValue.length > 0) {\n e.preventDefault();\n const removedIndex = currentValue.length - 1;\n const next = removeAt(removedIndex);\n const newLast = next.length - 1;\n if (newLast >= 0) {\n requestAnimationFrame(() => {\n chipRefs.current[newLast]?.focus();\n });\n }\n return;\n }\n const caretAtStart =\n target.selectionStart === 0 && target.selectionEnd === 0;\n if (\n (e.key === 'ArrowLeft' || e.key === 'ArrowRight') &&\n caretAtStart &&\n currentValue.length > 0\n ) {\n const isRTL = document.dir === 'rtl' || target.dir === 'rtl';\n const shouldNavigate =\n (isRTL && e.key === 'ArrowRight') ||\n (!isRTL && e.key === 'ArrowLeft');\n if (shouldNavigate) {\n e.preventDefault();\n const lastIdx = currentValue.length - 1;\n chipRefs.current[lastIdx]?.focus();\n }\n return;\n }\n if (e.key === 'Escape') {\n setOpen(false);\n return;\n }\n if (!open && (e.key === 'ArrowDown' || e.key === 'Enter')) {\n setOpen(true);\n }\n };\n\n const handleChipKeyDown =\n (index: number) =>\n (e: KeyboardEvent<HTMLSpanElement>): void => {\n if (\n e.key === 'Backspace' ||\n e.key === 'Delete' ||\n e.key === 'Enter' ||\n e.key === ' '\n ) {\n e.preventDefault();\n e.stopPropagation();\n const next = removeAt(index);\n if (next.length === 0) {\n requestAnimationFrame(() => inputRef.current?.focus());\n return;\n }\n const focusIdx = Math.min(index, next.length - 1);\n requestAnimationFrame(() => {\n chipRefs.current[focusIdx]?.focus();\n });\n return;\n }\n const isRTL = document.dir === 'rtl';\n const prevKey = isRTL ? 'ArrowRight' : 'ArrowLeft';\n const nextKey = isRTL ? 'ArrowLeft' : 'ArrowRight';\n if (e.key === prevKey) {\n e.preventDefault();\n const newIdx = Math.max(0, index - 1);\n chipRefs.current[newIdx]?.focus();\n return;\n }\n if (e.key === nextKey) {\n e.preventDefault();\n if (index < currentValue.length - 1) {\n chipRefs.current[index + 1]?.focus();\n } else {\n inputRef.current?.focus();\n }\n return;\n }\n if (e.key === 'Escape') {\n setOpen(false);\n inputRef.current?.focus();\n }\n };\n\n // ----- Chip overflow measurement -----\n // The measurement must read the FULL chip row, never the collapsed one.\n // Counting only the rendered (collapsed) chips is self-referential: hiding\n // the overflow behind \"+N more\" leaves a subset that trivially fits row 1,\n // the next measure concludes \"everything fits\", it expands, re-wraps, and\n // the ResizeObserver oscillates every frame (the visible flicker).\n //\n // Instead we run a two-pass cycle driven by `measureNonce`: a request first\n // renders every chip (visibleCount → ∞), then the layout effect measures\n // that complete row and sets the collapsed count. Both passes are layout\n // effects, so React flushes them before paint — the browser only ever shows\n // the settled, single-line result, with no full-row flash.\n const [visibleCount, setVisibleCount] = useState<number>(\n Number.POSITIVE_INFINITY,\n );\n const [measureNonce, setMeasureNonce] = useState<number>(0);\n const lastWidthRef = useRef<number>(-1);\n\n const requestMeasure = useCallback((): void => {\n setVisibleCount(Number.POSITIVE_INFINITY);\n setMeasureNonce((n) => n + 1);\n }, []);\n\n // Pass two: the \"show all\" render has committed — measure the true wrap\n // point off the complete chip row and collapse to it. Runs once per request\n // (keyed on measureNonce); collapsing does not bump the nonce, so it settles.\n useIsomorphicLayoutEffect(() => {\n const el = triggerRef.current;\n if (!el) return;\n const chipEls = Array.from(\n el.querySelectorAll<HTMLElement>('[data-ui-chip=\"true\"]'),\n );\n if (chipEls.length === 0) {\n setVisibleCount(Number.POSITIVE_INFINITY);\n return;\n }\n const firstTop = chipEls[0].offsetTop;\n let firstRowCount = 0;\n for (const chip of chipEls) {\n if (chip.offsetTop === firstTop) firstRowCount++;\n else break;\n }\n setVisibleCount(\n firstRowCount === chipEls.length\n ? Number.POSITIVE_INFINITY\n : Math.max(1, firstRowCount - 1),\n );\n }, [measureNonce]);\n\n // Re-measure whenever the selected set or the size variant changes.\n useIsomorphicLayoutEffect(() => {\n requestMeasure();\n }, [currentValue.length, size, requestMeasure]);\n\n // Re-measure on a real width change only. Collapsing shrinks the trigger's\n // height, not its width, so a width guard keeps that from re-triggering the\n // cycle — the ResizeObserver never chases its own output.\n useIsomorphicLayoutEffect(() => {\n const el = triggerRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n const width = Math.round(\n entries[0]?.contentRect.width ?? el.clientWidth,\n );\n if (width === lastWidthRef.current) return;\n lastWidthRef.current = width;\n requestMeasure();\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, [requestMeasure]);\n\n const chips = currentValue.map((val) => ({\n value: val,\n label: labelByValue.get(val) ?? val,\n }));\n\n const showAllChips =\n visibleCount === Number.POSITIVE_INFINITY || visibleCount >= chips.length;\n const visibleChips = showAllChips ? chips : chips.slice(0, visibleCount);\n const overflowChips = showAllChips ? [] : chips.slice(visibleCount);\n const overflowCount = overflowChips.length;\n\n const handleTriggerClick = (event: MouseEvent<HTMLDivElement>): void => {\n if (effectiveDisabled) return;\n // Ignore clicks on chips/buttons so they can manage their own focus.\n const target = event.target as HTMLElement;\n if (target.closest('[data-ui-chip=\"true\"]')) return;\n if (target.closest('[data-ui-chip-dismiss=\"true\"]')) return;\n setOpen(true);\n inputRef.current?.focus();\n };\n\n const handleOpenChange = (next: boolean): void => {\n if (effectiveDisabled) {\n setOpen(false);\n return;\n }\n setOpen(next);\n if (!next) {\n setQuery('');\n onComplete?.(currentValue);\n }\n };\n\n const hasActionRow = allowSelectAll || allowClear;\n\n const counterMessage = t('inputs.multiSelect.selected', {\n count: currentValue.length,\n defaultValue: `${currentValue.length} selected`,\n });\n\n /* cmdk writes `aria-labelledby` on the input after the props it is\n given, pointing at its own hidden `<label cmdk-label>` whose text is\n the Command root's `label`. So that label is the input's name: the\n host's `aria-label`, else the placeholder, so the input is never\n unnamed. The count of chosen options describes the input rather than\n naming it. */\n const accessibleName =\n (inFormField ? ctx.label || ariaLabel : ariaLabel) || resolvedPlaceholder;\n const inputDescribedBy = [counterId, describedBy].filter(Boolean).join(' ');\n\n /* Inside a FormField the name is the field's own `<label>`, read whole,\n as for every other control: its labelStart and labelEnd marks and\n \"(optional)\" join it, and the host's `aria-label` never overrides\n that visible text. cmdk's hidden label holds the label string only,\n so the input is pointed at the field's label instead. React leaves\n the attribute alone afterwards: cmdk's prop for it never changes. */\n const fieldLabelId = inFormField ? `${ctx.id}-label` : undefined;\n const cmdkLabelledBy = useRef<string | null>(null);\n useIsomorphicLayoutEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const current = input.getAttribute('aria-labelledby');\n if (fieldLabelId) {\n if (current === fieldLabelId) return;\n cmdkLabelledBy.current = current;\n input.setAttribute('aria-labelledby', fieldLabelId);\n } else if (cmdkLabelledBy.current !== null) {\n // Out of the field again: back to cmdk's own label.\n input.setAttribute('aria-labelledby', cmdkLabelledBy.current);\n cmdkLabelledBy.current = null;\n }\n });\n\n const { onClick: onClickProp, ...restDivProps } = divProps;\n\n return (\n <Command shouldFilter={false} label={accessibleName}>\n <Popover.Root open={open} onOpenChange={handleOpenChange}>\n <Popover.Anchor asChild>\n {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -- compound input shell; keyboard handling lives on the inner searchable input which is always rendered */}\n <div\n ref={composedRef}\n className={multiSelectVariants({ size, className })}\n aria-disabled={effectiveDisabled || undefined}\n aria-invalid={effectiveInvalid || undefined}\n data-component=\"multi-select\"\n data-component-id={id}\n onClick={(event) => {\n onClickProp?.(event);\n handleTriggerClick(event);\n }}\n {...restDivProps}\n >\n {visibleChips.map((chip, idx) => (\n // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- chip pill receives focus via roving tabindex; chip removal uses an inner button\n <span\n key={chip.value}\n ref={(el) => {\n chipRefs.current[idx] = el;\n }}\n tabIndex={effectiveDisabled ? -1 : 0}\n data-ui-chip=\"true\"\n className={chipVariants({ size })}\n onKeyDown={handleChipKeyDown(idx)}\n aria-label={chip.label}\n >\n <span dir={dirByValue.get(chip.value)}>{chip.label}</span>\n <button\n type=\"button\"\n tabIndex={-1}\n data-ui-chip-dismiss=\"true\"\n aria-label={t('inputs.multiSelect.remove', {\n label: chip.label,\n defaultValue: `Remove ${chip.label}`,\n })}\n disabled={effectiveDisabled}\n onClick={(event) => {\n event.stopPropagation();\n removeAt(idx);\n requestAnimationFrame(() => inputRef.current?.focus());\n }}\n className={chipDismissClasses}\n >\n <X aria-hidden=\"true\" className=\"ds:size-3.5\" />\n </button>\n </span>\n ))}\n {overflowCount > 0 ? (\n <Tooltip\n label={overflowChips.map((c) => c.label).join(', ')}\n delayDuration={200}\n >\n <span\n className={chipVariants({ size })}\n tabIndex={0}\n role=\"button\"\n aria-label={t('inputs.multiSelect.overflow', {\n count: overflowCount,\n defaultValue: `+${overflowCount} more`,\n })}\n >\n <span>\n {t('inputs.multiSelect.overflow', {\n count: overflowCount,\n defaultValue: `+${overflowCount} more`,\n })}\n </span>\n </span>\n </Tooltip>\n ) : null}\n <Command.Input\n ref={inputRef}\n value={query}\n onValueChange={setQuery}\n onKeyDown={handleInputKeyDown}\n onFocus={() => {\n if (!effectiveDisabled) setOpen(true);\n }}\n placeholder={\n currentValue.length === 0 ? resolvedPlaceholder : ''\n }\n id={triggerId}\n // The name comes from the Command root's `label` above, or\n // from the FormField's label: cmdk writes `aria-labelledby`\n // after these props, and a layout effect above re-points it.\n aria-describedby={inputDescribedBy}\n aria-invalid={effectiveInvalid || undefined}\n aria-required={effectiveRequired || undefined}\n disabled={effectiveDisabled}\n className={[\n 'ds:flex-1 ds:min-w-[6rem] ds:bg-transparent ds:outline-none',\n 'ds:placeholder:text-muted-foreground ds:text-start',\n 'ds:disabled:cursor-not-allowed',\n ].join(' ')}\n />\n {/* Hidden: read only as the input's description, not as stray\n text on the page. */}\n <span id={counterId} hidden>\n {counterMessage}\n </span>\n </div>\n </Popover.Anchor>\n <Popover.Portal>\n {/* Portalled to <body>, so the list carries its own bounding\n marker: the kit's cascade reset — and a host's shield against\n its own bare-element CSS — scope to [data-component]. */}\n <Popover.Content\n data-component=\"multi-select-list\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n onCloseAutoFocus={(e) => e.preventDefault()}\n align=\"start\"\n sideOffset={4}\n collisionPadding={8}\n className={popoverContentClasses}\n >\n <Command.List\n role=\"listbox\"\n aria-multiselectable=\"true\"\n // cmdk writes its own aria-label after ours, \"Suggestions\"\n // in English unless it gets `label`.\n label={accessibleName}\n className=\"ds:max-h-[20rem] ds:overflow-y-auto ds:p-1\"\n >\n {hasActionRow ? (\n <Command.Group>\n {allowSelectAll ? (\n <Command.Item\n value={SELECT_ALL_VALUE}\n onSelect={handleSelectAll}\n className={actionItemClasses}\n >\n {t('inputs.multiSelect.selectAll', 'Select all')}\n </Command.Item>\n ) : null}\n {allowClear ? (\n <Command.Item\n value={CLEAR_ALL_VALUE}\n onSelect={handleClearAll}\n className={actionItemClasses}\n >\n {t('inputs.multiSelect.clearAll', 'Clear all')}\n </Command.Item>\n ) : null}\n </Command.Group>\n ) : null}\n <Command.Empty className=\"ds:ps-2 ds:pe-2 ds:py-2 type-body-sm ds:text-muted-foreground\">\n {t('inputs.multiSelect.noOptions', 'No options found')}\n </Command.Empty>\n {groups.map(({ group, items }, gi) => {\n const body = items.map((option) => {\n const isSelected = currentValue.includes(option.value);\n const isCapped = !isSelected && atCap;\n const isDisabled = Boolean(option.disabled) || isCapped;\n const item = (\n <Command.Item\n key={option.value}\n value={option.value}\n // Agent DOM hook — see multi-select.agent.ts item.\n data-option-id={option.value}\n disabled={isDisabled}\n onSelect={() => {\n if (isDisabled) return;\n toggle(option.value);\n }}\n aria-selected={isSelected}\n aria-disabled={isDisabled || undefined}\n className={commandItemClasses}\n >\n <span\n // Off, the box is a state indicator, so its edge is\n // the 3:1 --control-border (WCAG 1.4.11), as on\n // Checkbox.\n className={[\n 'ds:inline-flex ds:items-center ds:justify-center ds:me-[var(--spacing-xs)] ds:shrink-0',\n 'ds:size-4 ds:rounded-[var(--radius-sm)] ds:border',\n isSelected\n ? 'ds:bg-primary ds:border-primary ds:text-primary-foreground'\n : 'ds:bg-background ds:border-[color:var(--control-border)]',\n ].join(' ')}\n aria-hidden=\"true\"\n >\n {isSelected ? (\n <Check className=\"ds:size-3.5\" />\n ) : null}\n </span>\n {option.startAdornment ? (\n // Decorative by contract — the accessible name comes\n // from the option label.\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:shrink-0 ds:me-[var(--spacing-xs)]\"\n >\n {option.startAdornment}\n </span>\n ) : null}\n {option.description || wrapOptionLabels ? (\n // Stacked, as in Combobox: the label and its end\n // content on one row, the description under them.\n // The option's name reads in that order.\n <span className={OPTION_BODY_CLASSES}>\n <span className={OPTION_LABEL_ROW_CLASSES}>\n <span\n dir={option.dir}\n className={optionLabelVariants({\n wrap: wrapOptionLabels,\n className: 'ds:flex-1 ds:text-start',\n })}\n >\n {option.label}\n </span>\n {option.endContent ? (\n // Announced, as below.\n <span className={OPTION_END_CLASSES}>\n {option.endContent}\n </span>\n ) : null}\n </span>\n {option.description ? (\n <span\n className={optionDescriptionVariants({\n tone: option.descriptionTone,\n className: 'ds:text-start',\n })}\n >\n {option.description}\n </span>\n ) : null}\n </span>\n ) : (\n <>\n {/* `min-w-0 truncate` matches Combobox and Select.\n Without it a long service name cannot be\n clipped, so it pushes the trailing content and\n overflows the row instead of the name\n ellipsing — the CJK and long-label case. */}\n <span\n dir={option.dir}\n className=\"ds:flex-1 ds:min-w-0 ds:truncate ds:text-start\"\n >\n {option.label}\n </span>\n {option.endContent ? (\n // Deliberately NOT aria-hidden — unlike\n // `startAdornment`, this slot carries meaning\n // (a price, a count) and must reach the\n // option's accessible name. `ms-auto` pins it\n // to the inline-end and flips under RTL.\n <span className=\"ds:inline-flex ds:items-center ds:ms-auto ds:shrink-0 ds:ps-[var(--spacing-xs)]\">\n {option.endContent}\n </span>\n ) : null}\n </>\n )}\n </Command.Item>\n );\n if (isCapped) {\n return (\n <Tooltip\n key={option.value}\n label={t('inputs.multiSelect.maxReached', {\n count: maxSelections,\n defaultValue: `Maximum ${maxSelections} selections`,\n })}\n delayDuration={200}\n >\n {item}\n </Tooltip>\n );\n }\n return item;\n });\n if (!group) {\n return (\n <Command.Group key={`group-${gi}`}>{body}</Command.Group>\n );\n }\n return (\n <Command.Group\n key={`group-${group}`}\n heading={group}\n className=\"ds:[&_[cmdk-group-heading]]:ps-2 ds:[&_[cmdk-group-heading]]:pe-2 ds:[&_[cmdk-group-heading]]:py-1 ds:[&_[cmdk-group-heading]]:type-eyebrow ds:[&_[cmdk-group-heading]]:text-muted-foreground\"\n >\n {body}\n </Command.Group>\n );\n })}\n </Command.List>\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n </Command>\n );\n },\n);\nMultiSelectImpl.displayName = 'MultiSelect';\n\ninterface MultiSelectComponent {\n <T extends string = string>(\n props: MultiSelectProps<T> & { ref?: Ref<HTMLDivElement> },\n ): ReactElement | null;\n displayName?: string;\n}\n\nexport const MultiSelect = MultiSelectImpl as unknown as MultiSelectComponent;\n\nexport { multiSelectVariants };\n"],"names":["multiSelectAgent","handle","args","multiSelectVariants","cva","INPUT_SURFACE_CHROME","INPUT_SURFACE_TEXT","chipVariants","chipDismissClasses","popoverContentClasses","commandItemClasses","MENU_ROW_HIGHLIGHT","actionItemClasses","SELECT_ALL_VALUE","CLEAR_ALL_VALUE","MultiSelectImpl","forwardRef","options","value","defaultValue","onChange","onComplete","placeholder","maxSelections","allowSelectAll","allowClear","filter","size","disabled","wrapOptionLabels","className","id","ariaLabel","divProps","ref","t","useTranslation","ctx","useFormField","inFormField","useContext","FormFieldContext","currentValueRaw","setMultiSelectValue","useControllableState","currentValue","open","setOpen","useState","query","setQuery","inputRef","useRef","counterId","useId","chipRefs","triggerRef","composedRef","composeRefs","effectiveDisabled","effectiveRequired","effectiveInvalid","describedBy","triggerId","useFormFieldControlRef","labelByValue","useMemo","map","option","dirByValue","atCap","commit","next","toggle","val","v","removeAt","index","_","i","handleSelectAll","selectable","o","cap","handleClearAll","valueRef","useEffect","queryRef","openRef","commitStable","useCallback","agentHandle","values","useAgentRegistration","resolvedPlaceholder","filteredOptions","needle","groups","groupOptions","handleInputKeyDown","target","removedIndex","newLast","_a","caretAtStart","isRTL","lastIdx","handleChipKeyDown","e","focusIdx","prevKey","nextKey","newIdx","_b","_c","_d","visibleCount","setVisibleCount","measureNonce","setMeasureNonce","lastWidthRef","requestMeasure","n","useIsomorphicLayoutEffect","el","chipEls","firstTop","firstRowCount","chip","ro","entries","width","chips","showAllChips","visibleChips","overflowChips","overflowCount","handleTriggerClick","event","handleOpenChange","hasActionRow","counterMessage","accessibleName","inputDescribedBy","fieldLabelId","cmdkLabelledBy","input","current","onClickProp","restDivProps","jsx","Command","jsxs","Popover","idx","X","Tooltip","c","group","items","gi","body","isSelected","isCapped","isDisabled","item","Check","OPTION_BODY_CLASSES","OPTION_LABEL_ROW_CLASSES","optionLabelVariants","OPTION_END_CLASSES","optionDescriptionVariants","Fragment","MultiSelect"],"mappings":"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"}