@alfadocs/ui-kit-debug 0.25.2 → 0.30.1

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 (147) hide show
  1. package/dist/_chunks/booking-Bw9eOU4k.js +2292 -0
  2. package/dist/_chunks/booking-Bw9eOU4k.js.map +1 -0
  3. package/dist/_chunks/{calendar-9eOXumpH.js → calendar-WWNx448i.js} +10 -9
  4. package/dist/_chunks/{calendar-9eOXumpH.js.map → calendar-WWNx448i.js.map} +1 -1
  5. package/dist/_chunks/checkbox-mwbrPZDY.js.map +1 -1
  6. package/dist/_chunks/{contact-card-CeEfEAxh.js → contact-card-DYbp--s-.js} +2 -2
  7. package/dist/_chunks/{contact-card-CeEfEAxh.js.map → contact-card-DYbp--s-.js.map} +1 -1
  8. package/dist/_chunks/{header-B8V_sNPy.js → header-CkMb1TZS.js} +23 -23
  9. package/dist/_chunks/header-CkMb1TZS.js.map +1 -0
  10. package/dist/_chunks/heart-pulse-CvuyFKHB.js +21 -0
  11. package/dist/_chunks/heart-pulse-CvuyFKHB.js.map +1 -0
  12. package/dist/_chunks/{link-DmM5IevO.js → link-DrD_cRUg.js} +50 -45
  13. package/dist/_chunks/link-DrD_cRUg.js.map +1 -0
  14. package/dist/_chunks/parseISO-Dk4xa7q6.js +120 -0
  15. package/dist/_chunks/parseISO-Dk4xa7q6.js.map +1 -0
  16. package/dist/_chunks/patient-search-DuSoGG2t.js +1113 -0
  17. package/dist/_chunks/patient-search-DuSoGG2t.js.map +1 -0
  18. package/dist/_chunks/{patient-shell-Bq8CjRYF.js → patient-shell-CAXYzbRw.js} +2 -2
  19. package/dist/_chunks/{patient-shell-Bq8CjRYF.js.map → patient-shell-CAXYzbRw.js.map} +1 -1
  20. package/dist/_chunks/public-footer.agent-DivkKdG4.js +537 -0
  21. package/dist/_chunks/public-footer.agent-DivkKdG4.js.map +1 -0
  22. package/dist/_chunks/reviews-panel-CFttsfuC.js +513 -0
  23. package/dist/_chunks/reviews-panel-CFttsfuC.js.map +1 -0
  24. package/dist/_chunks/slot-grid-B2zprPcv.js +387 -0
  25. package/dist/_chunks/slot-grid-B2zprPcv.js.map +1 -0
  26. package/dist/_chunks/stethoscope-DT5qCW8Y.js +18 -0
  27. package/dist/_chunks/stethoscope-DT5qCW8Y.js.map +1 -0
  28. package/dist/agent-catalog.json +117 -22
  29. package/dist/components/booking/booking-types.d.ts +167 -0
  30. package/dist/components/booking/booking-types.d.ts.map +1 -0
  31. package/dist/components/booking/booking.agent.d.ts +1 -1
  32. package/dist/components/booking/booking.agent.d.ts.map +1 -1
  33. package/dist/components/booking/booking.d.ts +4 -89
  34. package/dist/components/booking/booking.d.ts.map +1 -1
  35. package/dist/components/booking/cascade.d.ts +96 -0
  36. package/dist/components/booking/cascade.d.ts.map +1 -0
  37. package/dist/components/booking/details-form.d.ts +39 -0
  38. package/dist/components/booking/details-form.d.ts.map +1 -0
  39. package/dist/components/booking/index.d.ts +2 -1
  40. package/dist/components/booking/index.d.ts.map +1 -1
  41. package/dist/components/booking/index.js +5 -3
  42. package/dist/components/calendar/index.js +1 -1
  43. package/dist/components/checkbox/checkbox.d.ts +6 -2
  44. package/dist/components/checkbox/checkbox.d.ts.map +1 -1
  45. package/dist/components/contact-card/index.js +1 -1
  46. package/dist/components/header/index.js +1 -1
  47. package/dist/components/index.d.ts +3 -0
  48. package/dist/components/index.d.ts.map +1 -1
  49. package/dist/components/link/index.js +1 -1
  50. package/dist/components/link/link.d.ts +7 -0
  51. package/dist/components/link/link.d.ts.map +1 -1
  52. package/dist/components/patient-search/index.d.ts +4 -0
  53. package/dist/components/patient-search/index.d.ts.map +1 -0
  54. package/dist/components/patient-search/index.js +6 -0
  55. package/dist/components/patient-search/index.js.map +1 -0
  56. package/dist/components/patient-search/patient-search.agent.d.ts +4 -0
  57. package/dist/components/patient-search/patient-search.agent.d.ts.map +1 -0
  58. package/dist/components/patient-search/patient-search.d.ts +112 -0
  59. package/dist/components/patient-search/patient-search.d.ts.map +1 -0
  60. package/dist/components/public-footer/index.d.ts +6 -0
  61. package/dist/components/public-footer/index.d.ts.map +1 -0
  62. package/dist/components/public-footer/index.js +10 -0
  63. package/dist/components/public-footer/index.js.map +1 -0
  64. package/dist/components/public-footer/legal-urls.d.ts +18 -0
  65. package/dist/components/public-footer/legal-urls.d.ts.map +1 -0
  66. package/dist/components/public-footer/public-footer.agent.d.ts +4 -0
  67. package/dist/components/public-footer/public-footer.agent.d.ts.map +1 -0
  68. package/dist/components/public-footer/public-footer.d.ts +58 -0
  69. package/dist/components/public-footer/public-footer.d.ts.map +1 -0
  70. package/dist/components/public-footer/socials.d.ts +9 -0
  71. package/dist/components/public-footer/socials.d.ts.map +1 -0
  72. package/dist/components/reviews-panel/index.d.ts +4 -0
  73. package/dist/components/reviews-panel/index.d.ts.map +1 -0
  74. package/dist/components/reviews-panel/index.js +6 -0
  75. package/dist/components/reviews-panel/index.js.map +1 -0
  76. package/dist/components/reviews-panel/reviews-panel.agent.d.ts +4 -0
  77. package/dist/components/reviews-panel/reviews-panel.agent.d.ts.map +1 -0
  78. package/dist/components/reviews-panel/reviews-panel.d.ts +76 -0
  79. package/dist/components/reviews-panel/reviews-panel.d.ts.map +1 -0
  80. package/dist/components/slot-grid/index.js +1 -1
  81. package/dist/i18n/config.js +3994 -38
  82. package/dist/i18n/config.js.map +1 -1
  83. package/dist/i18n/locales/ar.d.ts +221 -0
  84. package/dist/i18n/locales/ar.d.ts.map +1 -1
  85. package/dist/i18n/locales/de.d.ts +221 -0
  86. package/dist/i18n/locales/de.d.ts.map +1 -1
  87. package/dist/i18n/locales/el.d.ts +221 -0
  88. package/dist/i18n/locales/el.d.ts.map +1 -1
  89. package/dist/i18n/locales/es.d.ts +221 -0
  90. package/dist/i18n/locales/es.d.ts.map +1 -1
  91. package/dist/i18n/locales/fr.d.ts +221 -0
  92. package/dist/i18n/locales/fr.d.ts.map +1 -1
  93. package/dist/i18n/locales/hi.d.ts +221 -0
  94. package/dist/i18n/locales/hi.d.ts.map +1 -1
  95. package/dist/i18n/locales/ja.d.ts +221 -0
  96. package/dist/i18n/locales/ja.d.ts.map +1 -1
  97. package/dist/i18n/locales/nl.d.ts +221 -0
  98. package/dist/i18n/locales/nl.d.ts.map +1 -1
  99. package/dist/i18n/locales/pl.d.ts +221 -0
  100. package/dist/i18n/locales/pl.d.ts.map +1 -1
  101. package/dist/i18n/locales/pt.d.ts +221 -0
  102. package/dist/i18n/locales/pt.d.ts.map +1 -1
  103. package/dist/i18n/locales/ro.d.ts +221 -0
  104. package/dist/i18n/locales/ro.d.ts.map +1 -1
  105. package/dist/i18n/locales/ru.d.ts +221 -0
  106. package/dist/i18n/locales/ru.d.ts.map +1 -1
  107. package/dist/i18n/locales/sq.d.ts +221 -0
  108. package/dist/i18n/locales/sq.d.ts.map +1 -1
  109. package/dist/i18n/locales/sv.d.ts +221 -0
  110. package/dist/i18n/locales/sv.d.ts.map +1 -1
  111. package/dist/i18n/locales/tr.d.ts +221 -0
  112. package/dist/i18n/locales/tr.d.ts.map +1 -1
  113. package/dist/i18n/locales/zh.d.ts +221 -0
  114. package/dist/i18n/locales/zh.d.ts.map +1 -1
  115. package/dist/i18n/resources.d.ts +442 -0
  116. package/dist/i18n/resources.d.ts.map +1 -1
  117. package/dist/index.js +351 -336
  118. package/dist/index.js.map +1 -1
  119. package/dist/locales/ar.json +222 -1
  120. package/dist/locales/de.json +222 -1
  121. package/dist/locales/el.json +222 -1
  122. package/dist/locales/en.json +222 -1
  123. package/dist/locales/es.json +222 -1
  124. package/dist/locales/fr.json +222 -1
  125. package/dist/locales/hi.json +222 -1
  126. package/dist/locales/it.json +222 -1
  127. package/dist/locales/ja.json +222 -1
  128. package/dist/locales/nl.json +222 -1
  129. package/dist/locales/pl.json +222 -1
  130. package/dist/locales/pt.json +222 -1
  131. package/dist/locales/ro.json +222 -1
  132. package/dist/locales/ru.json +222 -1
  133. package/dist/locales/sq.json +222 -1
  134. package/dist/locales/sv.json +222 -1
  135. package/dist/locales/tr.json +222 -1
  136. package/dist/locales/zh.json +222 -1
  137. package/dist/patterns/patient-shell/index.js +1 -1
  138. package/dist/tokens.css +1 -1
  139. package/package.json +17 -1
  140. package/dist/_chunks/booking-CXngC-1u.js +0 -1743
  141. package/dist/_chunks/booking-CXngC-1u.js.map +0 -1
  142. package/dist/_chunks/header-B8V_sNPy.js.map +0 -1
  143. package/dist/_chunks/link-DmM5IevO.js.map +0 -1
  144. package/dist/_chunks/slot-grid-DoodeQGZ.js +0 -502
  145. package/dist/_chunks/slot-grid-DoodeQGZ.js.map +0 -1
  146. package/dist/_chunks/stethoscope-B8kpbtjh.js +0 -35
  147. package/dist/_chunks/stethoscope-B8kpbtjh.js.map +0 -1
@@ -0,0 +1,387 @@
1
+ import { jsx as t, jsxs as x } from "react/jsx-runtime";
2
+ import { forwardRef as os, useId as ls, useState as cs, useCallback as L } from "react";
3
+ import { c as f } from "./index-D2ZczOXr.js";
4
+ import { useTranslation as ms } from "react-i18next";
5
+ import { B as $ } from "./button-DD_0Xdmr.js";
6
+ import { I as A } from "./icon-button-BRHSSFmZ.js";
7
+ import { E as us } from "./empty-state-BLy7tigq.js";
8
+ import { S as B } from "./skeleton-CZbwyJAA.js";
9
+ import { i as fs } from "./isSameDay-DHG8Xade.js";
10
+ import { p as gs } from "./parseISO-Dk4xa7q6.js";
11
+ const ps = f(
12
+ [
13
+ "ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]",
14
+ "ds:text-[var(--foreground)]",
15
+ "ds:w-full"
16
+ ].join(" "),
17
+ {
18
+ variants: {
19
+ size: {
20
+ sm: "ds:text-[length:var(--font-size-sm)]",
21
+ md: "ds:text-[length:var(--font-size-base)]",
22
+ lg: "ds:text-[length:var(--font-size-lg)]"
23
+ }
24
+ },
25
+ defaultVariants: { size: "md" }
26
+ }
27
+ ), vs = f(
28
+ "ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:w-full"
29
+ ), hs = 12, bs = f(
30
+ "ds:grid ds:gap-[var(--spacing-sm)] ds:w-full ds:auto-rows-min ds:items-start",
31
+ {
32
+ variants: {
33
+ cols: {
34
+ 1: "ds:grid-cols-1",
35
+ 2: "ds:grid-cols-2",
36
+ 3: "ds:grid-cols-3",
37
+ 4: "ds:grid-cols-4",
38
+ 5: "ds:grid-cols-5",
39
+ 6: "ds:grid-cols-6",
40
+ 7: "ds:grid-cols-7",
41
+ 8: "ds:grid-cols-8",
42
+ 9: "ds:grid-cols-9",
43
+ 10: "ds:grid-cols-10",
44
+ 11: "ds:grid-cols-11",
45
+ 12: "ds:grid-cols-12"
46
+ }
47
+ },
48
+ defaultVariants: { cols: 1 }
49
+ }
50
+ );
51
+ function xs(s) {
52
+ return Math.max(1, Math.min(s, hs));
53
+ }
54
+ const R = f(
55
+ [
56
+ "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]",
57
+ "ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]",
58
+ "ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]",
59
+ "ds:rounded-[var(--radius-md)]",
60
+ "ds:bg-[var(--card)]",
61
+ "ds:min-w-0"
62
+ ].join(" ")
63
+ ), ys = f(
64
+ [
65
+ "ds:font-[var(--font-weight-semibold)]",
66
+ "ds:text-[var(--foreground)]",
67
+ "ds:text-start",
68
+ "ds:truncate"
69
+ ].join(" "),
70
+ {
71
+ variants: {
72
+ size: {
73
+ sm: "ds:text-[length:var(--font-size-xs)]",
74
+ md: "ds:text-[length:var(--font-size-sm)]",
75
+ lg: "ds:text-[length:var(--font-size-base)]"
76
+ }
77
+ },
78
+ defaultVariants: { size: "md" }
79
+ }
80
+ ), T = f(
81
+ "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:w-full ds:m-0 ds:p-0 ds:list-none"
82
+ ), ws = f(
83
+ [
84
+ "ds:inline-flex ds:items-center ds:justify-center",
85
+ "ds:w-full",
86
+ "ds:rounded-[var(--radius-sm)]",
87
+ "ds:font-[var(--font-weight-medium)]",
88
+ "ds:bg-[var(--secondary)]",
89
+ "ds:shadow-[var(--shadow-sm)]",
90
+ "ds:text-[var(--foreground)]",
91
+ "ds:transition-[background-color,color,box-shadow]",
92
+ "ds:duration-[var(--animation-duration)]",
93
+ "ds:motion-reduce:transition-none",
94
+ "ds:focus-visible:outline-[var(--focus-ring-width)]",
95
+ "ds:focus-visible:outline-solid",
96
+ "ds:focus-visible:outline-[var(--ring)]",
97
+ "ds:focus-visible:outline-offset-[var(--focus-ring-offset)]",
98
+ "ds:min-h-[var(--min-target-size)]",
99
+ "ds:disabled:opacity-50 ds:disabled:cursor-not-allowed ds:disabled:shadow-none",
100
+ "ds:aria-disabled:opacity-50 ds:aria-disabled:cursor-not-allowed ds:aria-disabled:shadow-none",
101
+ "ds:hover:enabled:shadow-[var(--shadow-md)]",
102
+ "ds:aria-pressed:bg-[var(--primary)] ds:aria-pressed:text-[var(--primary-foreground)]"
103
+ ].join(" "),
104
+ {
105
+ variants: {
106
+ size: {
107
+ sm: "ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:text-[length:var(--font-size-xs)] ds:h-8",
108
+ md: "ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-sm)] ds:h-10",
109
+ lg: "ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-base)] ds:h-12"
110
+ }
111
+ },
112
+ defaultVariants: { size: "md" }
113
+ }
114
+ );
115
+ function u(s) {
116
+ return s instanceof Date ? s : gs(s);
117
+ }
118
+ function Rs(s, r) {
119
+ return fs(u(s), u(r));
120
+ }
121
+ function Ts(s) {
122
+ for (const r of s) {
123
+ const e = r.slots.find((n) => n.available !== !1);
124
+ if (e) return { day: r, slot: e };
125
+ }
126
+ }
127
+ function F(s, r, e) {
128
+ try {
129
+ return new Intl.DateTimeFormat(r, {
130
+ weekday: "short",
131
+ month: "short",
132
+ day: "numeric",
133
+ timeZone: e
134
+ }).format(s);
135
+ } catch {
136
+ return new Intl.DateTimeFormat("en", {
137
+ weekday: "short",
138
+ month: "short",
139
+ day: "numeric"
140
+ }).format(s);
141
+ }
142
+ }
143
+ function O(s, r, e) {
144
+ if (s.label !== void 0) return s.label;
145
+ const n = u(s.start);
146
+ try {
147
+ const d = new Intl.DateTimeFormat(r, {
148
+ hour: "numeric",
149
+ minute: "2-digit",
150
+ timeZone: e
151
+ });
152
+ if (s.end) {
153
+ const g = u(s.end);
154
+ if (typeof d.formatRange == "function")
155
+ try {
156
+ return d.formatRange(n, g);
157
+ } catch {
158
+ }
159
+ return `${d.format(n)} – ${d.format(g)}`;
160
+ }
161
+ return d.format(n);
162
+ } catch {
163
+ return n.toISOString();
164
+ }
165
+ }
166
+ function ks(s, r, e, n, d) {
167
+ if (s.ariaLabel !== void 0) return s.ariaLabel;
168
+ const g = O(s, e, n), p = r.label !== void 0 ? r.label : F(u(r.date), e, n);
169
+ return d({ time: g, day: p });
170
+ }
171
+ function Cs() {
172
+ return /* @__PURE__ */ t(
173
+ "svg",
174
+ {
175
+ "aria-hidden": "true",
176
+ viewBox: "0 0 24 24",
177
+ fill: "none",
178
+ stroke: "currentColor",
179
+ strokeWidth: "2",
180
+ strokeLinecap: "round",
181
+ strokeLinejoin: "round",
182
+ className: "ds:size-4",
183
+ children: /* @__PURE__ */ t("path", { d: "M15 18l-6-6 6-6" })
184
+ }
185
+ );
186
+ }
187
+ function Ls() {
188
+ return /* @__PURE__ */ t(
189
+ "svg",
190
+ {
191
+ "aria-hidden": "true",
192
+ viewBox: "0 0 24 24",
193
+ fill: "none",
194
+ stroke: "currentColor",
195
+ strokeWidth: "2",
196
+ strokeLinecap: "round",
197
+ strokeLinejoin: "round",
198
+ className: "ds:size-4",
199
+ children: /* @__PURE__ */ t("path", { d: "M9 6l6 6-6 6" })
200
+ }
201
+ );
202
+ }
203
+ const Ds = os(
204
+ ({
205
+ days: s,
206
+ state: r = "default",
207
+ size: e = "md",
208
+ selectedSlotId: n,
209
+ maxInitialSlotsPerDay: d = 6,
210
+ locale: g,
211
+ timeZone: p,
212
+ hasPrevious: K = !1,
213
+ hasNext: M = !1,
214
+ showNextAvailable: _ = !1,
215
+ ariaLabel: H,
216
+ onSlotSelect: v,
217
+ onPreviousDays: W,
218
+ onNextDays: X,
219
+ onShowMore: h,
220
+ onJumpToNextAvailable: q,
221
+ className: J,
222
+ ...Q
223
+ }, U) => {
224
+ const { t: o, i18n: Y } = ms(), y = g ?? Y.language ?? "en", P = ls(), [Z, ss] = cs({}), D = r === "loading", z = r === "disabled", m = D || z, as = r === "empty" || s.length === 0 || s.every((a) => a.slots.length === 0), ts = H ?? o("slotGrid.ariaLabel"), w = L(
225
+ (a, i) => {
226
+ m || a.available !== !1 && (v == null || v(a, i));
227
+ },
228
+ [m, v]
229
+ ), es = L(
230
+ (a, i) => {
231
+ ss((l) => ({ ...l, [i]: !0 })), h == null || h(a);
232
+ },
233
+ [h]
234
+ ), rs = L(
235
+ (a, i, l) => {
236
+ (a.key === "Enter" || a.key === " ") && (a.preventDefault(), w(i, l));
237
+ },
238
+ [w]
239
+ ), I = xs(s.length || 1), N = bs({ cols: I });
240
+ let b;
241
+ return D ? b = /* @__PURE__ */ t(
242
+ "div",
243
+ {
244
+ className: N,
245
+ "data-state": "loading",
246
+ role: "status",
247
+ "aria-live": "polite",
248
+ "aria-label": o("common.loading"),
249
+ children: Array.from({ length: I }, (a, i) => /* @__PURE__ */ x("div", { className: R(), children: [
250
+ /* @__PURE__ */ t(B, { variant: "text", size: e, width: "60%" }),
251
+ /* @__PURE__ */ t("div", { className: T(), children: Array.from(
252
+ { length: Math.min(d, 4) },
253
+ (l, k) => /* @__PURE__ */ t(
254
+ B,
255
+ {
256
+ variant: "rounded",
257
+ size: e,
258
+ height: "40px"
259
+ },
260
+ `loading-slot-${i}-${k}`
261
+ )
262
+ ) })
263
+ ] }, `loading-col-${i}`))
264
+ }
265
+ ) : as ? b = /* @__PURE__ */ t("div", { "data-state": "empty", children: /* @__PURE__ */ t(us, { variant: "no-results", title: o("slotGrid.noSlots") }) }) : b = /* @__PURE__ */ t(
266
+ "div",
267
+ {
268
+ className: N,
269
+ "data-state": z ? "disabled" : "default",
270
+ children: s.map((a, i) => {
271
+ const l = `${u(a.date).toISOString()}-${i}`, k = a.label ?? F(u(a.date), y, p), S = `${P}-day-${i}-header`, G = Z[l] ?? !1 ? a.slots : a.slots.slice(0, d), V = a.slots.length - G.length, j = a.slots.length === 0;
272
+ return (
273
+ // Use a plain <div role="group"> rather than <section> — a
274
+ // <section> with aria-labelledby is a landmark, and nesting many
275
+ // landmarks inside the outer slot-grid landmark fails axe's
276
+ // landmark-unique rule.
277
+ /* @__PURE__ */ x(
278
+ "div",
279
+ {
280
+ role: "group",
281
+ className: R(),
282
+ "aria-labelledby": S,
283
+ "data-empty": j || void 0,
284
+ children: [
285
+ /* @__PURE__ */ t("h3", { id: S, className: ys({ size: e }), children: k }),
286
+ j ? /* @__PURE__ */ t("p", { className: "type-body-sm ds:text-[var(--muted-foreground)] ds:m-0", children: o("slotGrid.noSlots") }) : null,
287
+ /* @__PURE__ */ t("ul", { className: T(), children: G.map((c) => {
288
+ const ns = ks(
289
+ c,
290
+ a,
291
+ y,
292
+ p,
293
+ ({ time: C, day: ds }) => o("slotGrid.slotLabel", { time: C, day: ds })
294
+ ), is = n === c.id, E = c.available === !1 || m;
295
+ return /* @__PURE__ */ t("li", { children: /* @__PURE__ */ t(
296
+ "button",
297
+ {
298
+ type: "button",
299
+ className: ws({ size: e }),
300
+ "aria-label": ns,
301
+ "aria-pressed": is,
302
+ disabled: E,
303
+ "aria-disabled": E || void 0,
304
+ "data-slot-id": c.id,
305
+ onClick: () => w(c, a),
306
+ onKeyDown: (C) => rs(C, c, a),
307
+ children: O(c, y, p)
308
+ }
309
+ ) }, c.id);
310
+ }) }),
311
+ V > 0 ? /* @__PURE__ */ t(
312
+ $,
313
+ {
314
+ intent: "ghost",
315
+ size: e === "lg" ? "md" : "sm",
316
+ onClick: () => es(a, l),
317
+ disabled: m,
318
+ children: o("slotGrid.showMore", { count: V })
319
+ }
320
+ ) : null
321
+ ]
322
+ },
323
+ l
324
+ )
325
+ );
326
+ })
327
+ }
328
+ ), /* @__PURE__ */ x(
329
+ "div",
330
+ {
331
+ ref: U,
332
+ role: "region",
333
+ "aria-label": ts,
334
+ className: ps({ size: e, className: J }),
335
+ "data-component": "slot-grid",
336
+ "data-state": r,
337
+ ...Q,
338
+ children: [
339
+ /* @__PURE__ */ x("div", { className: vs(), children: [
340
+ /* @__PURE__ */ t(
341
+ A,
342
+ {
343
+ icon: /* @__PURE__ */ t(Cs, {}),
344
+ "aria-label": o("slotGrid.previousDays"),
345
+ size: e === "lg" ? "md" : "sm",
346
+ intent: "ghost",
347
+ flipIconInRtl: !0,
348
+ disabled: !K || m,
349
+ onClick: W
350
+ }
351
+ ),
352
+ _ ? /* @__PURE__ */ t(
353
+ $,
354
+ {
355
+ intent: "secondary",
356
+ size: e === "lg" ? "md" : "sm",
357
+ disabled: m,
358
+ onClick: q,
359
+ children: o("slotGrid.nextAvailable")
360
+ }
361
+ ) : /* @__PURE__ */ t("span", { "aria-hidden": "true" }),
362
+ /* @__PURE__ */ t(
363
+ A,
364
+ {
365
+ icon: /* @__PURE__ */ t(Ls, {}),
366
+ "aria-label": o("slotGrid.nextDays"),
367
+ size: e === "lg" ? "md" : "sm",
368
+ intent: "ghost",
369
+ flipIconInRtl: !0,
370
+ disabled: !M || m,
371
+ onClick: X
372
+ }
373
+ )
374
+ ] }),
375
+ b
376
+ ]
377
+ }
378
+ );
379
+ }
380
+ );
381
+ Ds.displayName = "SlotGrid";
382
+ export {
383
+ Ds as S,
384
+ Ts as f,
385
+ Rs as i
386
+ };
387
+ //# sourceMappingURL=slot-grid-B2zprPcv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-grid-B2zprPcv.js","sources":["../../src/components/slot-grid/slot-grid.tsx"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* SlotGrid — multi-day time-slot picker for patient booking. */\n/* */\n/* Renders N day columns side-by-side. Each column shows a day header */\n/* (formatted via `Intl.DateTimeFormat(locale)`) plus a vertical list */\n/* of slot buttons. Long days collapse to `maxInitialSlotsPerDay` and */\n/* reveal the rest via a \"Show more\" button (progressive disclosure). */\n/* */\n/* Navigation arrows (`onPreviousDays` / `onNextDays`) let the consumer */\n/* page the window of days; the optional \"Next available\" CTA jumps to */\n/* the first day with an open slot. */\n/* */\n/* Purely presentational — no business logic, no data fetching. Date */\n/* comparisons use `date-fns` (never moment.js) and the rendered labels */\n/* come exclusively from `Intl.DateTimeFormat` or the `ui.slotGrid` */\n/* namespace via `useTranslation()`. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useCallback,\n useId,\n useState,\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { isSameDay, parseISO } from 'date-fns';\nimport { Button } from '../button/button';\nimport { IconButton } from '../button/icon-button';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Skeleton } from '../skeleton/skeleton';\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport type SlotGridState = 'default' | 'loading' | 'disabled' | 'empty';\n\nexport type SlotGridSize = 'sm' | 'md' | 'lg';\n\nexport interface SlotGridSlot {\n /** Stable identity — used by consumers to resolve selection. */\n id: string;\n /** Slot start — ISO string or `Date`. Rendered via `Intl.DateTimeFormat`. */\n start: string | Date;\n /** Optional slot end — if omitted only the start time is announced. */\n end?: string | Date;\n /** Defaults to `true`. Unavailable slots render disabled and are not focusable. */\n available?: boolean;\n /** Override the default `Intl`-formatted time label. */\n label?: string;\n /** Override the accessible name of the slot button. */\n ariaLabel?: string;\n}\n\nexport interface SlotGridDay {\n /** The calendar day the column represents. */\n date: string | Date;\n /** Slots for this day, in chronological order. Empty array ⇒ empty day. */\n slots: SlotGridSlot[];\n /** Override the default `Intl`-formatted day header. */\n label?: string;\n}\n\nexport interface SlotGridProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'aria-label' | 'onSelect'>,\n VariantProps<typeof slotGridVariants> {\n /** Days to render, one column per entry. */\n days: SlotGridDay[];\n /** Visual / interactive state. Defaults to `'default'`. */\n state?: SlotGridState;\n /** Density of the slot buttons and day headers. Defaults to `'md'`. */\n size?: SlotGridSize;\n /** Id of the currently selected slot (controlled). */\n selectedSlotId?: string;\n /**\n * Initial number of slots to render per day before the \"Show more\"\n * progressive-disclosure control collapses the rest. Defaults to `6`.\n */\n maxInitialSlotsPerDay?: number;\n /**\n * BCP-47 locale tag for `Intl.DateTimeFormat`. Defaults to the active\n * i18next language.\n */\n locale?: string;\n /** IANA time zone for `Intl.DateTimeFormat`. Optional. */\n timeZone?: string;\n /** Whether the \"previous days\" navigation arrow should be enabled. */\n hasPrevious?: boolean;\n /** Whether the \"next days\" navigation arrow should be enabled. */\n hasNext?: boolean;\n /**\n * When `true`, renders the \"Next available\" CTA at the end of the\n * toolbar. Only emits a callback — the consumer owns the navigation.\n */\n showNextAvailable?: boolean;\n /** Accessible label for the outer grid region. */\n ariaLabel?: string;\n /** Fires when the user selects an available slot. */\n onSlotSelect?: (slot: SlotGridSlot, day: SlotGridDay) => void;\n /** Fires when the user clicks the \"previous days\" arrow. */\n onPreviousDays?: () => void;\n /** Fires when the user clicks the \"next days\" arrow. */\n onNextDays?: () => void;\n /** Fires when the user clicks a day's \"Show more\" button. */\n onShowMore?: (day: SlotGridDay) => void;\n /** Fires when the user clicks the \"Next available\" CTA. */\n onJumpToNextAvailable?: () => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst slotGridVariants = cva(\n [\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n 'ds:text-[var(--foreground)]',\n 'ds:w-full',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:text-[length:var(--font-size-sm)]',\n md: 'ds:text-[length:var(--font-size-base)]',\n lg: 'ds:text-[length:var(--font-size-lg)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst toolbarVariants = cva(\n 'ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:w-full',\n);\n\n/**\n * Column-count is dynamic (1–12), so it is declared as a full CVA variant —\n * this keeps every `grid-cols-N` string statically visible to Tailwind's\n * JIT and keeps the variant table inside CVA rather than hand-rolled.\n */\nconst COLS_MAX = 12;\n\nconst columnsVariants = cva(\n 'ds:grid ds:gap-[var(--spacing-sm)] ds:w-full ds:auto-rows-min ds:items-start',\n {\n variants: {\n cols: {\n 1: 'ds:grid-cols-1',\n 2: 'ds:grid-cols-2',\n 3: 'ds:grid-cols-3',\n 4: 'ds:grid-cols-4',\n 5: 'ds:grid-cols-5',\n 6: 'ds:grid-cols-6',\n 7: 'ds:grid-cols-7',\n 8: 'ds:grid-cols-8',\n 9: 'ds:grid-cols-9',\n 10: 'ds:grid-cols-10',\n 11: 'ds:grid-cols-11',\n 12: 'ds:grid-cols-12',\n },\n },\n defaultVariants: { cols: 1 },\n },\n);\n\ntype ColumnsCount = NonNullable<VariantProps<typeof columnsVariants>['cols']>;\n\nfunction clampCols(count: number): ColumnsCount {\n return Math.max(1, Math.min(count, COLS_MAX)) as ColumnsCount;\n}\n\nconst columnVariants = cva(\n [\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:bg-[var(--card)]',\n 'ds:min-w-0',\n ].join(' '),\n);\n\nconst dayHeaderVariants = cva(\n [\n 'ds:font-[var(--font-weight-semibold)]',\n 'ds:text-[var(--foreground)]',\n 'ds:text-start',\n 'ds:truncate',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:text-[length:var(--font-size-xs)]',\n md: 'ds:text-[length:var(--font-size-sm)]',\n lg: 'ds:text-[length:var(--font-size-base)]',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\nconst slotListVariants = cva(\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-xs)] ds:w-full ds:m-0 ds:p-0 ds:list-none',\n);\n\nconst slotButtonVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:w-full',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:font-[var(--font-weight-medium)]',\n 'ds:bg-[var(--secondary)]',\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:text-[var(--foreground)]',\n 'ds:transition-[background-color,color,box-shadow]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[var(--focus-ring-offset)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:disabled:opacity-50 ds:disabled:cursor-not-allowed ds:disabled:shadow-none',\n 'ds:aria-disabled:opacity-50 ds:aria-disabled:cursor-not-allowed ds:aria-disabled:shadow-none',\n 'ds:hover:enabled:shadow-[var(--shadow-md)]',\n 'ds:aria-pressed:bg-[var(--primary)] ds:aria-pressed:text-[var(--primary-foreground)]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:text-[length:var(--font-size-xs)] ds:h-8',\n md: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-sm)] ds:h-10',\n lg: 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:text-[length:var(--font-size-base)] ds:h-12',\n },\n },\n defaultVariants: { size: 'md' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Helpers */\n/* ------------------------------------------------------------------ */\n\nfunction toDate(value: string | Date): Date {\n return value instanceof Date ? value : parseISO(value);\n}\n\n/** Is `a` the same calendar day as `b`? Uses `date-fns`, locale-agnostic. */\nexport function isSameDate(a: string | Date, b: string | Date): boolean {\n return isSameDay(toDate(a), toDate(b));\n}\n\n/** Find the first day in a list that has at least one available slot. */\nexport function findFirstAvailable(\n days: SlotGridDay[],\n): { day: SlotGridDay; slot: SlotGridSlot } | undefined {\n for (const day of days) {\n const slot = day.slots.find((s) => s.available !== false);\n if (slot) return { day, slot };\n }\n return undefined;\n}\n\nfunction formatDayHeader(\n date: Date,\n locale: string,\n timeZone?: string,\n): string {\n try {\n return new Intl.DateTimeFormat(locale, {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n timeZone,\n }).format(date);\n } catch {\n return new Intl.DateTimeFormat('en', {\n weekday: 'short',\n month: 'short',\n day: 'numeric',\n }).format(date);\n }\n}\n\nfunction formatSlotTime(\n slot: SlotGridSlot,\n locale: string,\n timeZone?: string,\n): string {\n if (slot.label !== undefined) return slot.label;\n const start = toDate(slot.start);\n try {\n const fmt = new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: '2-digit',\n timeZone,\n });\n if (slot.end) {\n const end = toDate(slot.end);\n if (typeof fmt.formatRange === 'function') {\n try {\n return fmt.formatRange(start, end);\n } catch {\n /* fall through */\n }\n }\n return `${fmt.format(start)} – ${fmt.format(end)}`;\n }\n return fmt.format(start);\n } catch {\n return start.toISOString();\n }\n}\n\nfunction formatSlotAriaLabel(\n slot: SlotGridSlot,\n day: SlotGridDay,\n locale: string,\n timeZone: string | undefined,\n template: (opts: { time: string; day: string }) => string,\n): string {\n if (slot.ariaLabel !== undefined) return slot.ariaLabel;\n const time = formatSlotTime(slot, locale, timeZone);\n const dayLabel =\n day.label !== undefined\n ? day.label\n : formatDayHeader(toDate(day.date), locale, timeZone);\n return template({ time, day: dayLabel });\n}\n\n/* ------------------------------------------------------------------ */\n/* Glyphs — logical-direction arrows */\n/* ------------------------------------------------------------------ */\n\nfunction ChevronStartIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"ds:size-4\"\n >\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n );\n}\n\nfunction ChevronEndIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"ds:size-4\"\n >\n <path d=\"M9 6l6 6-6 6\" />\n </svg>\n );\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const SlotGrid = forwardRef<HTMLDivElement, SlotGridProps>(\n (\n {\n days,\n state = 'default',\n size = 'md',\n selectedSlotId,\n maxInitialSlotsPerDay = 6,\n locale: localeProp,\n timeZone,\n hasPrevious = false,\n hasNext = false,\n showNextAvailable = false,\n ariaLabel,\n onSlotSelect,\n onPreviousDays,\n onNextDays,\n onShowMore,\n onJumpToNextAvailable,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const locale = localeProp ?? i18n.language ?? 'en';\n const idBase = useId();\n\n const [expanded, setExpanded] = useState<Record<string, boolean>>({});\n\n const isLoading = state === 'loading';\n const isDisabled = state === 'disabled';\n const isInteractionSuppressed = isLoading || isDisabled;\n const isEmpty =\n state === 'empty' ||\n days.length === 0 ||\n days.every((day) => day.slots.length === 0);\n\n const resolvedAriaLabel = ariaLabel ?? t('slotGrid.ariaLabel');\n\n const handleSlotClick = useCallback(\n (slot: SlotGridSlot, day: SlotGridDay) => {\n if (isInteractionSuppressed) return;\n if (slot.available === false) return;\n onSlotSelect?.(slot, day);\n },\n [isInteractionSuppressed, onSlotSelect],\n );\n\n const handleShowMore = useCallback(\n (day: SlotGridDay, key: string) => {\n setExpanded((prev) => ({ ...prev, [key]: true }));\n onShowMore?.(day);\n },\n [onShowMore],\n );\n\n const handleSlotKeyDown = useCallback(\n (\n event: KeyboardEvent<HTMLButtonElement>,\n slot: SlotGridSlot,\n day: SlotGridDay,\n ) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleSlotClick(slot, day);\n }\n },\n [handleSlotClick],\n );\n\n const columnCount = clampCols(days.length || 1);\n const columnsClass = columnsVariants({ cols: columnCount });\n\n /* ---- Rendered content ------------------------------------------ */\n\n let body: ReactNode;\n if (isLoading) {\n body = (\n <div\n className={columnsClass}\n data-state=\"loading\"\n role=\"status\"\n aria-live=\"polite\"\n aria-label={t('common.loading')}\n >\n {Array.from({ length: columnCount }, (_, colIdx) => (\n <div key={`loading-col-${colIdx}`} className={columnVariants()}>\n <Skeleton variant=\"text\" size={size} width=\"60%\" />\n <div className={slotListVariants()}>\n {Array.from(\n { length: Math.min(maxInitialSlotsPerDay, 4) },\n (_, rowIdx) => (\n <Skeleton\n key={`loading-slot-${colIdx}-${rowIdx}`}\n variant=\"rounded\"\n size={size}\n height=\"40px\"\n />\n ),\n )}\n </div>\n </div>\n ))}\n </div>\n );\n } else if (isEmpty) {\n body = (\n <div data-state=\"empty\">\n <EmptyState variant=\"no-results\" title={t('slotGrid.noSlots')} />\n </div>\n );\n } else {\n body = (\n <div\n className={columnsClass}\n data-state={isDisabled ? 'disabled' : 'default'}\n >\n {days.map((day, dayIdx) => {\n const dayKey = `${toDate(day.date).toISOString()}-${dayIdx}`;\n const headerLabel =\n day.label ?? formatDayHeader(toDate(day.date), locale, timeZone);\n const headerId = `${idBase}-day-${dayIdx}-header`;\n const isExpanded = expanded[dayKey] ?? false;\n const visibleSlots = isExpanded\n ? day.slots\n : day.slots.slice(0, maxInitialSlotsPerDay);\n const hiddenCount = day.slots.length - visibleSlots.length;\n\n const isDayEmpty = day.slots.length === 0;\n\n return (\n // Use a plain <div role=\"group\"> rather than <section> — a\n // <section> with aria-labelledby is a landmark, and nesting many\n // landmarks inside the outer slot-grid landmark fails axe's\n // landmark-unique rule.\n <div\n key={dayKey}\n role=\"group\"\n className={columnVariants()}\n aria-labelledby={headerId}\n data-empty={isDayEmpty || undefined}\n >\n <h3 id={headerId} className={dayHeaderVariants({ size })}>\n {headerLabel}\n </h3>\n {isDayEmpty ? (\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)] ds:m-0\">\n {t('slotGrid.noSlots')}\n </p>\n ) : null}\n <ul className={slotListVariants()}>\n {visibleSlots.map((slot) => {\n const ariaLabelSlot = formatSlotAriaLabel(\n slot,\n day,\n locale,\n timeZone,\n ({ time, day: dayLabel }) =>\n t('slotGrid.slotLabel', { time, day: dayLabel }),\n );\n const isSelected = selectedSlotId === slot.id;\n const isSlotDisabled =\n slot.available === false || isInteractionSuppressed;\n return (\n <li key={slot.id}>\n <button\n type=\"button\"\n className={slotButtonVariants({ size })}\n aria-label={ariaLabelSlot}\n aria-pressed={isSelected}\n disabled={isSlotDisabled}\n aria-disabled={isSlotDisabled || undefined}\n data-slot-id={slot.id}\n onClick={() => handleSlotClick(slot, day)}\n onKeyDown={(event) =>\n handleSlotKeyDown(event, slot, day)\n }\n >\n {formatSlotTime(slot, locale, timeZone)}\n </button>\n </li>\n );\n })}\n </ul>\n {hiddenCount > 0 ? (\n <Button\n intent=\"ghost\"\n size={size === 'lg' ? 'md' : 'sm'}\n onClick={() => handleShowMore(day, dayKey)}\n disabled={isInteractionSuppressed}\n >\n {t('slotGrid.showMore', { count: hiddenCount })}\n </Button>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={resolvedAriaLabel}\n className={slotGridVariants({ size, className })}\n data-component=\"slot-grid\"\n data-state={state}\n {...rest}\n >\n <div className={toolbarVariants()}>\n <IconButton\n icon={<ChevronStartIcon />}\n aria-label={t('slotGrid.previousDays')}\n size={size === 'lg' ? 'md' : 'sm'}\n intent=\"ghost\"\n flipIconInRtl\n disabled={!hasPrevious || isInteractionSuppressed}\n onClick={onPreviousDays}\n />\n {showNextAvailable ? (\n <Button\n intent=\"secondary\"\n size={size === 'lg' ? 'md' : 'sm'}\n disabled={isInteractionSuppressed}\n onClick={onJumpToNextAvailable}\n >\n {t('slotGrid.nextAvailable')}\n </Button>\n ) : (\n <span aria-hidden=\"true\" />\n )}\n <IconButton\n icon={<ChevronEndIcon />}\n aria-label={t('slotGrid.nextDays')}\n size={size === 'lg' ? 'md' : 'sm'}\n intent=\"ghost\"\n flipIconInRtl\n disabled={!hasNext || isInteractionSuppressed}\n onClick={onNextDays}\n />\n </div>\n\n {body}\n </div>\n );\n },\n);\n\nSlotGrid.displayName = 'SlotGrid';\n"],"names":["slotGridVariants","cva","toolbarVariants","COLS_MAX","columnsVariants","clampCols","count","columnVariants","dayHeaderVariants","slotListVariants","slotButtonVariants","toDate","value","parseISO","isSameDate","a","b","isSameDay","findFirstAvailable","days","day","slot","s","formatDayHeader","date","locale","timeZone","formatSlotTime","start","fmt","end","formatSlotAriaLabel","template","time","dayLabel","ChevronStartIcon","jsx","ChevronEndIcon","SlotGrid","forwardRef","state","size","selectedSlotId","maxInitialSlotsPerDay","localeProp","hasPrevious","hasNext","showNextAvailable","ariaLabel","onSlotSelect","onPreviousDays","onNextDays","onShowMore","onJumpToNextAvailable","className","rest","ref","t","i18n","useTranslation","idBase","useId","expanded","setExpanded","useState","isLoading","isDisabled","isInteractionSuppressed","isEmpty","resolvedAriaLabel","handleSlotClick","useCallback","handleShowMore","key","prev","handleSlotKeyDown","event","columnCount","columnsClass","body","_","colIdx","jsxs","Skeleton","rowIdx","EmptyState","dayIdx","dayKey","headerLabel","headerId","visibleSlots","hiddenCount","isDayEmpty","ariaLabelSlot","isSelected","isSlotDisabled","Button","IconButton"],"mappings":";;;;;;;;;;AAsHA,MAAMA,KAAmBC;AAAA,EACvB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB,EAAE,MAAM,KAAA;AAAA,EAAK;AAElC,GAEMC,KAAkBD;AAAA,EACtB;AACF,GAOME,KAAW,IAEXC,KAAkBH;AAAA,EACtB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB,EAAE,MAAM,EAAA;AAAA,EAAE;AAE/B;AAIA,SAASI,GAAUC,GAA6B;AAC9C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAIA,GAAOH,EAAQ,CAAC;AAC9C;AAEA,MAAMI,IAAiBN;AAAA,EACrB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AACZ,GAEMO,KAAoBP;AAAA,EACxB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB,EAAE,MAAM,KAAA;AAAA,EAAK;AAElC,GAEMQ,IAAmBR;AAAA,EACvB;AACF,GAEMS,KAAqBT;AAAA,EACzB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MAAA;AAAA,IACN;AAAA,IAEF,iBAAiB,EAAE,MAAM,KAAA;AAAA,EAAK;AAElC;AAMA,SAASU,EAAOC,GAA4B;AAC1C,SAAOA,aAAiB,OAAOA,IAAQC,GAASD,CAAK;AACvD;AAGO,SAASE,GAAWC,GAAkBC,GAA2B;AACtE,SAAOC,GAAUN,EAAOI,CAAC,GAAGJ,EAAOK,CAAC,CAAC;AACvC;AAGO,SAASE,GACdC,GACsD;AACtD,aAAWC,KAAOD,GAAM;AACtB,UAAME,IAAOD,EAAI,MAAM,KAAK,CAACE,MAAMA,EAAE,cAAc,EAAK;AACxD,QAAID,EAAM,QAAO,EAAE,KAAAD,GAAK,MAAAC,EAAA;AAAA,EAC1B;AAEF;AAEA,SAASE,EACPC,GACAC,GACAC,GACQ;AACR,MAAI;AACF,WAAO,IAAI,KAAK,eAAeD,GAAQ;AAAA,MACrC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,KAAK;AAAA,MACL,UAAAC;AAAA,IAAA,CACD,EAAE,OAAOF,CAAI;AAAA,EAChB,QAAQ;AACN,WAAO,IAAI,KAAK,eAAe,MAAM;AAAA,MACnC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,KAAK;AAAA,IAAA,CACN,EAAE,OAAOA,CAAI;AAAA,EAChB;AACF;AAEA,SAASG,EACPN,GACAI,GACAC,GACQ;AACR,MAAIL,EAAK,UAAU,OAAW,QAAOA,EAAK;AAC1C,QAAMO,IAAQjB,EAAOU,EAAK,KAAK;AAC/B,MAAI;AACF,UAAMQ,IAAM,IAAI,KAAK,eAAeJ,GAAQ;AAAA,MAC1C,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,UAAAC;AAAA,IAAA,CACD;AACD,QAAIL,EAAK,KAAK;AACZ,YAAMS,IAAMnB,EAAOU,EAAK,GAAG;AAC3B,UAAI,OAAOQ,EAAI,eAAgB;AAC7B,YAAI;AACF,iBAAOA,EAAI,YAAYD,GAAOE,CAAG;AAAA,QACnC,QAAQ;AAAA,QAER;AAEF,aAAO,GAAGD,EAAI,OAAOD,CAAK,CAAC,MAAMC,EAAI,OAAOC,CAAG,CAAC;AAAA,IAClD;AACA,WAAOD,EAAI,OAAOD,CAAK;AAAA,EACzB,QAAQ;AACN,WAAOA,EAAM,YAAA;AAAA,EACf;AACF;AAEA,SAASG,GACPV,GACAD,GACAK,GACAC,GACAM,GACQ;AACR,MAAIX,EAAK,cAAc,OAAW,QAAOA,EAAK;AAC9C,QAAMY,IAAON,EAAeN,GAAMI,GAAQC,CAAQ,GAC5CQ,IACJd,EAAI,UAAU,SACVA,EAAI,QACJG,EAAgBZ,EAAOS,EAAI,IAAI,GAAGK,GAAQC,CAAQ;AACxD,SAAOM,EAAS,EAAE,MAAAC,GAAM,KAAKC,GAAU;AACzC;AAMA,SAASC,KAAmB;AAC1B,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,eAAY;AAAA,MACZ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,WAAU;AAAA,MAEV,UAAA,gBAAAA,EAAC,QAAA,EAAK,GAAE,kBAAA,CAAkB;AAAA,IAAA;AAAA,EAAA;AAGhC;AAEA,SAASC,KAAiB;AACxB,SACE,gBAAAD;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,eAAY;AAAA,MACZ,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,WAAU;AAAA,MAEV,UAAA,gBAAAA,EAAC,QAAA,EAAK,GAAE,eAAA,CAAe;AAAA,IAAA;AAAA,EAAA;AAG7B;AAMO,MAAME,KAAWC;AAAA,EACtB,CACE;AAAA,IACE,MAAApB;AAAA,IACA,OAAAqB,IAAQ;AAAA,IACR,MAAAC,IAAO;AAAA,IACP,gBAAAC;AAAA,IACA,uBAAAC,IAAwB;AAAA,IACxB,QAAQC;AAAA,IACR,UAAAlB;AAAA,IACA,aAAAmB,IAAc;AAAA,IACd,SAAAC,IAAU;AAAA,IACV,mBAAAC,IAAoB;AAAA,IACpB,WAAAC;AAAA,IACA,cAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,YAAAC;AAAA,IACA,YAAAC;AAAA,IACA,uBAAAC;AAAA,IACA,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAM,EAAE,GAAAC,GAAG,MAAAC,EAAA,IAASC,GAAA,GACdlC,IAASmB,KAAcc,EAAK,YAAY,MACxCE,IAASC,GAAA,GAET,CAACC,GAAUC,EAAW,IAAIC,GAAkC,CAAA,CAAE,GAE9DC,IAAYzB,MAAU,WACtB0B,IAAa1B,MAAU,YACvB2B,IAA0BF,KAAaC,GACvCE,KACJ5B,MAAU,WACVrB,EAAK,WAAW,KAChBA,EAAK,MAAM,CAACC,MAAQA,EAAI,MAAM,WAAW,CAAC,GAEtCiD,KAAoBrB,KAAaS,EAAE,oBAAoB,GAEvDa,IAAkBC;AAAA,MACtB,CAAClD,GAAoBD,MAAqB;AACxC,QAAI+C,KACA9C,EAAK,cAAc,OACvB4B,KAAA,QAAAA,EAAe5B,GAAMD;AAAA,MACvB;AAAA,MACA,CAAC+C,GAAyBlB,CAAY;AAAA,IAAA,GAGlCuB,KAAiBD;AAAA,MACrB,CAACnD,GAAkBqD,MAAgB;AACjC,QAAAV,GAAY,CAACW,OAAU,EAAE,GAAGA,GAAM,CAACD,CAAG,GAAG,GAAA,EAAO,GAChDrB,KAAA,QAAAA,EAAahC;AAAA,MACf;AAAA,MACA,CAACgC,CAAU;AAAA,IAAA,GAGPuB,KAAoBJ;AAAA,MACxB,CACEK,GACAvD,GACAD,MACG;AACH,SAAIwD,EAAM,QAAQ,WAAWA,EAAM,QAAQ,SACzCA,EAAM,eAAA,GACNN,EAAgBjD,GAAMD,CAAG;AAAA,MAE7B;AAAA,MACA,CAACkD,CAAe;AAAA,IAAA,GAGZO,IAAcxE,GAAUc,EAAK,UAAU,CAAC,GACxC2D,IAAe1E,GAAgB,EAAE,MAAMyE,GAAa;AAI1D,QAAIE;AACJ,WAAId,IACFc,IACE,gBAAA3C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW0C;AAAA,QACX,cAAW;AAAA,QACX,MAAK;AAAA,QACL,aAAU;AAAA,QACV,cAAYrB,EAAE,gBAAgB;AAAA,QAE7B,UAAA,MAAM,KAAK,EAAE,QAAQoB,EAAA,GAAe,CAACG,GAAGC,MACvC,gBAAAC,EAAC,OAAA,EAAkC,WAAW3E,KAC5C,UAAA;AAAA,UAAA,gBAAA6B,EAAC+C,GAAA,EAAS,SAAQ,QAAO,MAAA1C,GAAY,OAAM,OAAM;AAAA,UACjD,gBAAAL,EAAC,OAAA,EAAI,WAAW3B,EAAA,GACb,UAAA,MAAM;AAAA,YACL,EAAE,QAAQ,KAAK,IAAIkC,GAAuB,CAAC,EAAA;AAAA,YAC3C,CAACqC,GAAGI,MACF,gBAAAhD;AAAA,cAAC+C;AAAA,cAAA;AAAA,gBAEC,SAAQ;AAAA,gBACR,MAAA1C;AAAA,gBACA,QAAO;AAAA,cAAA;AAAA,cAHF,gBAAgBwC,CAAM,IAAIG,CAAM;AAAA,YAAA;AAAA,UAIvC,EAEJ,CACF;AAAA,QAAA,EAAA,GAdQ,eAAeH,CAAM,EAe/B,CACD;AAAA,MAAA;AAAA,IAAA,IAGIb,KACTW,IACE,gBAAA3C,EAAC,OAAA,EAAI,cAAW,SACd,UAAA,gBAAAA,EAACiD,IAAA,EAAW,SAAQ,cAAa,OAAO5B,EAAE,kBAAkB,EAAA,CAAG,GACjE,IAGFsB,IACE,gBAAA3C;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW0C;AAAA,QACX,cAAYZ,IAAa,aAAa;AAAA,QAErC,UAAA/C,EAAK,IAAI,CAACC,GAAKkE,MAAW;AACzB,gBAAMC,IAAS,GAAG5E,EAAOS,EAAI,IAAI,EAAE,YAAA,CAAa,IAAIkE,CAAM,IACpDE,IACJpE,EAAI,SAASG,EAAgBZ,EAAOS,EAAI,IAAI,GAAGK,GAAQC,CAAQ,GAC3D+D,IAAW,GAAG7B,CAAM,QAAQ0B,CAAM,WAElCI,IADa5B,EAASyB,CAAM,KAAK,KAEnCnE,EAAI,QACJA,EAAI,MAAM,MAAM,GAAGuB,CAAqB,GACtCgD,IAAcvE,EAAI,MAAM,SAASsE,EAAa,QAE9CE,IAAaxE,EAAI,MAAM,WAAW;AAExC;AAAA;AAAA;AAAA;AAAA;AAAA,YAKE,gBAAA8D;AAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,MAAK;AAAA,gBACL,WAAW3E,EAAA;AAAA,gBACX,mBAAiBkF;AAAA,gBACjB,cAAYG,KAAc;AAAA,gBAE1B,UAAA;AAAA,kBAAA,gBAAAxD,EAAC,MAAA,EAAG,IAAIqD,GAAU,WAAWjF,GAAkB,EAAE,MAAAiC,EAAA,CAAM,GACpD,UAAA+C,EAAA,CACH;AAAA,kBACCI,sBACE,KAAA,EAAE,WAAU,yDACV,UAAAnC,EAAE,kBAAkB,GACvB,IACE;AAAA,kBACJ,gBAAArB,EAAC,QAAG,WAAW3B,EAAA,GACZ,UAAAiF,EAAa,IAAI,CAACrE,MAAS;AAC1B,0BAAMwE,KAAgB9D;AAAA,sBACpBV;AAAA,sBACAD;AAAA,sBACAK;AAAA,sBACAC;AAAA,sBACA,CAAC,EAAE,MAAAO,GAAM,KAAKC,GAAA,MACZuB,EAAE,sBAAsB,EAAE,MAAAxB,GAAM,KAAKC,GAAA,CAAU;AAAA,oBAAA,GAE7C4D,KAAapD,MAAmBrB,EAAK,IACrC0E,IACJ1E,EAAK,cAAc,MAAS8C;AAC9B,6CACG,MAAA,EACC,UAAA,gBAAA/B;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,MAAK;AAAA,wBACL,WAAW1B,GAAmB,EAAE,MAAA+B,GAAM;AAAA,wBACtC,cAAYoD;AAAA,wBACZ,gBAAcC;AAAA,wBACd,UAAUC;AAAA,wBACV,iBAAeA,KAAkB;AAAA,wBACjC,gBAAc1E,EAAK;AAAA,wBACnB,SAAS,MAAMiD,EAAgBjD,GAAMD,CAAG;AAAA,wBACxC,WAAW,CAACwD,MACVD,GAAkBC,GAAOvD,GAAMD,CAAG;AAAA,wBAGnC,UAAAO,EAAeN,GAAMI,GAAQC,CAAQ;AAAA,sBAAA;AAAA,oBAAA,EACxC,GAfOL,EAAK,EAgBd;AAAA,kBAEJ,CAAC,EAAA,CACH;AAAA,kBACCsE,IAAc,IACb,gBAAAvD;AAAA,oBAAC4D;AAAA,oBAAA;AAAA,sBACC,QAAO;AAAA,sBACP,MAAMvD,MAAS,OAAO,OAAO;AAAA,sBAC7B,SAAS,MAAM+B,GAAepD,GAAKmE,CAAM;AAAA,sBACzC,UAAUpB;AAAA,sBAET,UAAAV,EAAE,qBAAqB,EAAE,OAAOkC,GAAa;AAAA,oBAAA;AAAA,kBAAA,IAE9C;AAAA,gBAAA;AAAA,cAAA;AAAA,cAzDCJ;AAAA,YAAA;AAAA;AAAA,QA4DX,CAAC;AAAA,MAAA;AAAA,IAAA,GAML,gBAAAL;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAA1B;AAAA,QACA,MAAK;AAAA,QACL,cAAYa;AAAA,QACZ,WAAWrE,GAAiB,EAAE,MAAAyC,GAAM,WAAAa,GAAW;AAAA,QAC/C,kBAAe;AAAA,QACf,cAAYd;AAAA,QACX,GAAGe;AAAA,QAEJ,UAAA;AAAA,UAAA,gBAAA2B,EAAC,OAAA,EAAI,WAAWhF,GAAA,GACd,UAAA;AAAA,YAAA,gBAAAkC;AAAA,cAAC6D;AAAA,cAAA;AAAA,gBACC,wBAAO9D,IAAA,EAAiB;AAAA,gBACxB,cAAYsB,EAAE,uBAAuB;AAAA,gBACrC,MAAMhB,MAAS,OAAO,OAAO;AAAA,gBAC7B,QAAO;AAAA,gBACP,eAAa;AAAA,gBACb,UAAU,CAACI,KAAesB;AAAA,gBAC1B,SAASjB;AAAA,cAAA;AAAA,YAAA;AAAA,YAEVH,IACC,gBAAAX;AAAA,cAAC4D;AAAA,cAAA;AAAA,gBACC,QAAO;AAAA,gBACP,MAAMvD,MAAS,OAAO,OAAO;AAAA,gBAC7B,UAAU0B;AAAA,gBACV,SAASd;AAAA,gBAER,YAAE,wBAAwB;AAAA,cAAA;AAAA,YAAA,IAG7B,gBAAAjB,EAAC,QAAA,EAAK,eAAY,OAAA,CAAO;AAAA,YAE3B,gBAAAA;AAAA,cAAC6D;AAAA,cAAA;AAAA,gBACC,wBAAO5D,IAAA,EAAe;AAAA,gBACtB,cAAYoB,EAAE,mBAAmB;AAAA,gBACjC,MAAMhB,MAAS,OAAO,OAAO;AAAA,gBAC7B,QAAO;AAAA,gBACP,eAAa;AAAA,gBACb,UAAU,CAACK,KAAWqB;AAAA,gBACtB,SAAShB;AAAA,cAAA;AAAA,YAAA;AAAA,UACX,GACF;AAAA,UAEC4B;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEAzC,GAAS,cAAc;"}
@@ -0,0 +1,18 @@
1
+ import { c as e } from "./createLucideIcon-CrFbzy84.js";
2
+ /**
3
+ * @license lucide-react v1.8.0 - ISC
4
+ *
5
+ * This source code is licensed under the ISC license.
6
+ * See the LICENSE file in the root directory of this source tree.
7
+ */
8
+ const t = [
9
+ ["path", { d: "M11 2v2", key: "1539x4" }],
10
+ ["path", { d: "M5 2v2", key: "1yf1q8" }],
11
+ ["path", { d: "M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1", key: "rb5t3r" }],
12
+ ["path", { d: "M8 15a6 6 0 0 0 12 0v-3", key: "x18d4x" }],
13
+ ["circle", { cx: "20", cy: "10", r: "2", key: "ts1r5v" }]
14
+ ], o = e("stethoscope", t);
15
+ export {
16
+ o as S
17
+ };
18
+ //# sourceMappingURL=stethoscope-DT5qCW8Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stethoscope-DT5qCW8Y.js","sources":["../../node_modules/lucide-react/dist/esm/icons/stethoscope.js"],"sourcesContent":["/**\n * @license lucide-react v1.8.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M11 2v2\", key: \"1539x4\" }],\n [\"path\", { d: \"M5 2v2\", key: \"1yf1q8\" }],\n [\"path\", { d: \"M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1\", key: \"rb5t3r\" }],\n [\"path\", { d: \"M8 15a6 6 0 0 0 12 0v-3\", key: \"x18d4x\" }],\n [\"circle\", { cx: \"20\", cy: \"10\", r: \"2\", key: \"ts1r5v\" }]\n];\nconst Stethoscope = createLucideIcon(\"stethoscope\", __iconNode);\n\nexport { __iconNode, Stethoscope as default };\n//# sourceMappingURL=stethoscope.js.map\n"],"names":["__iconNode","Stethoscope","createLucideIcon"],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,IAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAAA,EACxC,CAAC,QAAQ,EAAE,GAAG,UAAU,KAAK,SAAQ,CAAE;AAAA,EACvC,CAAC,QAAQ,EAAE,GAAG,4DAA4D,KAAK,SAAQ,CAAE;AAAA,EACzF,CAAC,QAAQ,EAAE,GAAG,2BAA2B,KAAK,SAAQ,CAAE;AAAA,EACxD,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,SAAQ,CAAE;AAC1D,GACMC,IAAcC,EAAiB,eAAeF,CAAU;","x_google_ignoreList":[0]}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "packageVersion": "0.25.2",
3
+ "packageVersion": "0.30.1",
4
4
  "components": [
5
5
  {
6
6
  "kind": "component",
@@ -409,16 +409,6 @@
409
409
  "view_change"
410
410
  ],
411
411
  "state": [
412
- {
413
- "name": "currentStep",
414
- "type": "number",
415
- "description": "Zero-indexed active step within the active variant. Variants with no step machine report 0."
416
- },
417
- {
418
- "name": "totalSteps",
419
- "type": "number",
420
- "description": "Total number of steps in the active variant. Single-screen variants report 1."
421
- },
422
412
  {
423
413
  "name": "variant",
424
414
  "type": "string",
@@ -427,20 +417,15 @@
427
417
  ],
428
418
  "actions": [
429
419
  {
430
- "name": "goto_step",
431
- "safety": "read",
432
- "argsType": "{ step: number }",
433
- "description": "Jump to the given step within the active variant. Steps beyond first-incomplete are gated internally."
434
- },
435
- {
436
- "name": "next",
437
- "safety": "read",
438
- "description": "Advance to the next step when the current step has a valid value."
420
+ "name": "reset",
421
+ "safety": "write",
422
+ "description": "Clear the booking value back to an empty state. Use to abandon an in-progress flow."
439
423
  },
440
424
  {
441
- "name": "previous",
425
+ "name": "goto_step",
442
426
  "safety": "read",
443
- "description": "Return to the previous step."
427
+ "argsType": "{ step: 1 | 2 | 3 | 4 | 5 | 6 | 7 }",
428
+ "description": "Jump to the given step. Implementations may clamp to the first incomplete step if the requested one is not reachable yet."
444
429
  }
445
430
  ],
446
431
  "domHooks": {
@@ -2449,6 +2434,45 @@
2449
2434
  }
2450
2435
  }
2451
2436
  },
2437
+ {
2438
+ "kind": "component",
2439
+ "id": "patient-search",
2440
+ "capabilities": [
2441
+ "navigate",
2442
+ "view_change"
2443
+ ],
2444
+ "state": [
2445
+ {
2446
+ "name": "variant",
2447
+ "type": "string",
2448
+ "description": "Active variant — one of `who-where`, `who-where-when`, `faceted`, `discovery`."
2449
+ }
2450
+ ],
2451
+ "actions": [
2452
+ {
2453
+ "name": "reset",
2454
+ "safety": "write",
2455
+ "description": "Clear the current selection (WHO, WHERE, WHEN, facets, geo) via the consumer-owned onChange."
2456
+ },
2457
+ {
2458
+ "name": "focus_primary",
2459
+ "safety": "read",
2460
+ "description": "Move keyboard focus to the most-relevant field for the current variant."
2461
+ }
2462
+ ],
2463
+ "domHooks": {
2464
+ "root": {
2465
+ "attr": "data-component",
2466
+ "value": "patient-search",
2467
+ "description": "Marks the PatientSearch root region."
2468
+ },
2469
+ "instanceId": {
2470
+ "attr": "data-component-id",
2471
+ "sourceProp": "id",
2472
+ "description": "Sourced from the id prop."
2473
+ }
2474
+ }
2475
+ },
2452
2476
  {
2453
2477
  "kind": "component",
2454
2478
  "id": "payment-form",
@@ -2677,6 +2701,38 @@
2677
2701
  }
2678
2702
  }
2679
2703
  },
2704
+ {
2705
+ "kind": "component",
2706
+ "id": "public-footer",
2707
+ "capabilities": [
2708
+ "navigate"
2709
+ ],
2710
+ "state": [
2711
+ {
2712
+ "name": "variant",
2713
+ "type": "string",
2714
+ "description": "Active variant — one of `minimal`, `compact`, `full`."
2715
+ },
2716
+ {
2717
+ "name": "legalUrls",
2718
+ "type": "object",
2719
+ "description": "Resolved legal URLs for the active locale + marketingBaseUrl + overrides: `{ privacy, terms, contacts }`."
2720
+ }
2721
+ ],
2722
+ "actions": [],
2723
+ "domHooks": {
2724
+ "root": {
2725
+ "attr": "data-component",
2726
+ "value": "public-footer",
2727
+ "description": "Marks the PublicFooter root region. The root also carries `data-variant=\"minimal|compact|full\"` for CSS + agent selectors."
2728
+ },
2729
+ "instanceId": {
2730
+ "attr": "id",
2731
+ "sourceProp": "id",
2732
+ "description": "Sourced from the `id` prop when provided."
2733
+ }
2734
+ }
2735
+ },
2680
2736
  {
2681
2737
  "kind": "component",
2682
2738
  "id": "public-header",
@@ -2856,6 +2912,45 @@
2856
2912
  }
2857
2913
  }
2858
2914
  },
2915
+ {
2916
+ "kind": "component",
2917
+ "id": "reviews-panel",
2918
+ "capabilities": [
2919
+ "filter"
2920
+ ],
2921
+ "state": [
2922
+ {
2923
+ "name": "filter",
2924
+ "type": "string",
2925
+ "description": "Active star-bucket filter — `\"all\"` or an integer 1..5. Reads the controlled `filter` prop."
2926
+ },
2927
+ {
2928
+ "name": "visibleCount",
2929
+ "type": "number",
2930
+ "description": "Number of reviews currently rendered after the filter is applied."
2931
+ }
2932
+ ],
2933
+ "actions": [
2934
+ {
2935
+ "name": "set_filter",
2936
+ "safety": "read",
2937
+ "argsType": "{ filter: \"all\" | 1 | 2 | 3 | 4 | 5 }",
2938
+ "description": "Narrow the visible review list to a star bucket, or `\"all\"` to clear the filter."
2939
+ }
2940
+ ],
2941
+ "domHooks": {
2942
+ "root": {
2943
+ "attr": "data-component",
2944
+ "value": "reviews-panel",
2945
+ "description": "Marks the ReviewsPanel root region."
2946
+ },
2947
+ "instanceId": {
2948
+ "attr": "data-component-id",
2949
+ "sourceProp": "id",
2950
+ "description": "Sourced from the id prop."
2951
+ }
2952
+ }
2953
+ },
2859
2954
  {
2860
2955
  "kind": "component",
2861
2956
  "id": "rich-text-editor",