@med-o/ui 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10,18 +10,337 @@ import { Label, ProgressBar as AriaProgressBar } from "react-aria-components";
10
10
  // src/utils/cx.ts
11
11
  var cx = (...classes) => classes.filter(Boolean).join(" ");
12
12
 
13
+ // src/i18n/I18n.tsx
14
+ import { createContext, useContext } from "react";
15
+ import { useLocale } from "react-aria-components";
16
+
17
+ // src/i18n/de.ts
18
+ var embed = (title, subject, load, remember) => ({
19
+ title,
20
+ body: (provider, to) => `${subject.nominative} von ${provider ?? "einem Drittanbieter"} bereitgestellt. Beim Laden werden Daten wie Ihre IP-Adresse an ${to ?? "den Anbieter"} \xFCbertragen.`,
21
+ bodyCompact: (provider, company, to) => `Beim Laden ${subject.dativeArticle} werden Daten an ${provider && company && provider !== company ? `${provider} (${company})` : to ?? "einen Drittanbieter"} \xFCbertragen.`,
22
+ load,
23
+ remember
24
+ });
25
+ var de = {
26
+ common: {
27
+ close: "Schlie\xDFen",
28
+ cancel: "Abbrechen",
29
+ back: "Zur\xFCck",
30
+ more: "Mehr",
31
+ done: "Fertig",
32
+ search: "Suche",
33
+ showResults: "Ergebnisse anzeigen",
34
+ loading: "Wird geladen",
35
+ clear: "Eingabe l\xF6schen",
36
+ clearAll: "Alle entfernen",
37
+ noResults: "Keine Ergebnisse",
38
+ noResultsFor: (q) => `Keine Ergebnisse f\xFCr \u201E${q}\u201C`,
39
+ selected: (name) => `${name}: ausgew\xE4hlt`,
40
+ removed: (labels) => `${labels.join(", ")} entfernt`,
41
+ add: (text) => `\u201E${text}\u201C hinzuf\xFCgen`,
42
+ create: "Erstellen",
43
+ reset: "Zur\xFCcksetzen",
44
+ countSelected: (n) => `${n} ausgew\xE4hlt`,
45
+ selectedValues: "Ausgew\xE4hlt"
46
+ },
47
+ keys: { control: "Strg" },
48
+ accordion: { expandAll: "Alle aufklappen", collapseAll: "Alle zuklappen" },
49
+ alert: { dismiss: "Ausblenden" },
50
+ avatar: {
51
+ status: { online: "online", away: "abwesend", busy: "besch\xE4ftigt", offline: "offline" },
52
+ unknownPerson: "Unbekannte Person",
53
+ unknownOrganization: "Unbekannte Organisation",
54
+ more: (n) => `${n} weitere`
55
+ },
56
+ breadcrumbs: { label: "Pfadnavigation", more: (n) => n === 1 ? "1 weitere Ebene anzeigen" : `${n} weitere Ebenen anzeigen` },
57
+ bulkActionBar: { label: "Sammelaktionen", count: (n) => `${n} ausgew\xE4hlt`, clear: "Auswahl aufheben", more: "Weitere Aktionen" },
58
+ calendar: {
59
+ previousMonth: "Vorheriger Monat",
60
+ nextMonth: "N\xE4chster Monat",
61
+ previousYear: "Vorheriges Jahr",
62
+ nextYear: "N\xE4chstes Jahr",
63
+ previousYears: "Vorherige Jahre",
64
+ nextYears: "N\xE4chste Jahre",
65
+ chooseMonth: (title) => `${title} \u2013 Monat und Jahr w\xE4hlen`,
66
+ chooseYear: (year) => `${year} \u2013 Jahr w\xE4hlen`,
67
+ weekNumber: "KW"
68
+ },
69
+ datePicker: {
70
+ openCalendar: "Kalender \xF6ffnen",
71
+ time: "Uhrzeit",
72
+ presets: "Zeitr\xE4ume",
73
+ beforeMin: (date) => `Bitte ein Datum ab dem ${date} w\xE4hlen.`,
74
+ afterMax: (date) => `Bitte ein Datum bis zum ${date} w\xE4hlen.`,
75
+ unavailable: "Dieser Tag ist nicht verf\xFCgbar. Bitte einen anderen Tag w\xE4hlen.",
76
+ reversed: "Das Enddatum muss nach dem Startdatum liegen.",
77
+ today: "Heute",
78
+ yesterday: "Gestern",
79
+ last7Days: "Letzte 7 Tage",
80
+ last14Days: "Letzte 14 Tage",
81
+ last30Days: "Letzte 30 Tage",
82
+ thisMonth: "Dieser Monat",
83
+ lastMonth: "Letzter Monat",
84
+ availableTimes: "Verf\xFCgbare Uhrzeiten"
85
+ },
86
+ dialog: {
87
+ discardTitle: "\xC4nderungen verwerfen?",
88
+ discardDescription: "Die \xC4nderungen gehen verloren.",
89
+ discardAction: "Verwerfen",
90
+ discardCancel: "Weiter bearbeiten"
91
+ },
92
+ embed: {
93
+ video: embed(
94
+ "Externes Video laden",
95
+ { nominative: "Dieses Video wird", dativeArticle: "dieses Videos" },
96
+ "Video laden",
97
+ (p) => p ? `${p}-Videos immer laden` : "Videos dieses Anbieters immer laden"
98
+ ),
99
+ map: embed(
100
+ "Karte laden",
101
+ { nominative: "Diese Karte wird", dativeArticle: "dieser Karte" },
102
+ "Karte laden",
103
+ (p) => p ? `${p} immer laden` : "Karten dieses Anbieters immer laden"
104
+ ),
105
+ generic: embed(
106
+ "Externe Inhalte laden",
107
+ { nominative: "Diese Inhalte werden", dativeArticle: "dieser Inhalte" },
108
+ "Inhalte laden",
109
+ (p) => p ? `Inhalte von ${p} immer laden` : "Inhalte dieses Anbieters immer laden"
110
+ ),
111
+ privacy: "Datenschutzerkl\xE4rung"
112
+ },
113
+ list: { notIncluded: "Nicht enthalten:" },
114
+ listView: { unread: "Ungelesen" },
115
+ navigation: {
116
+ skipToContent: "Zum Inhalt springen",
117
+ main: "Hauptnavigation",
118
+ app: "App",
119
+ menu: "Men\xFC",
120
+ collapse: "Navigation einklappen",
121
+ expand: "Navigation ausklappen"
122
+ },
123
+ pagination: {
124
+ label: "Seitennavigation",
125
+ summary: (from, to, total) => `${from}\u2013${to} von ${total}`,
126
+ pageSize: "Zeilen pro Seite",
127
+ previous: "Vorherige Seite",
128
+ next: "N\xE4chste Seite",
129
+ page: (p) => `Seite ${p}`,
130
+ pageOf: (p, total) => `Seite ${p} von ${total}`
131
+ },
132
+ quickSearch: {
133
+ placeholder: "Seiten, Dateien, Personen suchen \u2026",
134
+ suggestions: "Vorschl\xE4ge",
135
+ allResults: (q) => `Alle Ergebnisse f\xFCr \u201E${q}\u201C`,
136
+ noResults: (q) => `Keine Ergebnisse f\xFCr \u201E${q}\u201C. Bitte die Schreibweise pr\xFCfen oder andere Begriffe versuchen.`,
137
+ searchAll: (q) => `Alle Inhalte nach \u201E${q}\u201C durchsuchen`,
138
+ navigate: "Navigieren",
139
+ open: "\xD6ffnen"
140
+ },
141
+ searchField: { clear: "Suche l\xF6schen" },
142
+ select: { placeholder: "Ausw\xE4hlen\u2026", clearSelection: "Auswahl entfernen" },
143
+ combobox: { placeholder: "Suchen\u2026" },
144
+ slider: { minimum: (label) => label ? `${label}, Minimum` : "Minimum", maximum: (label) => label ? `${label}, Maximum` : "Maximum" },
145
+ table: { columns: "Spalten", showColumns: "Spalten anzeigen", scrollRegion: "Tabelle" },
146
+ textField: {
147
+ counter: (count, limit) => `${count} / ${limit}`,
148
+ tooMany: (over) => `${over} zu viel`,
149
+ charactersLeft: (left) => `Noch ${left} Zeichen`,
150
+ charactersTooMany: (over) => `${over} Zeichen zu viel`
151
+ },
152
+ upload: {
153
+ title: "Dateien hierher ziehen",
154
+ dropTitle: "Dateien zum Hochladen ablegen",
155
+ chooseFiles: "Dateien ausw\xE4hlen",
156
+ chooseFile: "Datei ausw\xE4hlen",
157
+ listLabel: "Hochgeladene Dateien",
158
+ cancel: (name) => `Hochladen von ${name} abbrechen`,
159
+ remove: (name) => `${name} entfernen`,
160
+ retry: (name) => `${name} erneut hochladen`,
161
+ retryShort: "Wiederholen",
162
+ uploading: (name) => `${name} wird hochgeladen`,
163
+ progress: (loaded, total, percent) => `${loaded} von ${total} \xB7 ${percent} %`,
164
+ typeNotAllowed: (names, types) => `${names} ${names.includes(",") ? "sind" : "ist"} nicht erlaubt.${types ? ` Erlaubt: ${types}.` : ""}`,
165
+ tooLarge: (size, max) => `Datei ist ${size} gro\xDF \u2013 max. ${max} erlaubt`,
166
+ tooMany: (max) => `H\xF6chstens ${max} Dateien. Zum Hinzuf\xFCgen bitte erst eine entfernen.`,
167
+ uploaded: (name) => `${name} hochgeladen`,
168
+ failed: (name, error) => `${name}: ${error}`
169
+ }
170
+ };
171
+
172
+ // src/i18n/en.ts
173
+ var s = (n, one, other) => n === 1 ? one : other;
174
+ var embed2 = (noun, title, load, remember) => ({
175
+ title,
176
+ body: (provider, to) => `This ${noun} is provided by ${provider ?? "a third party"}. Loading it sends data such as your IP address to ${to ?? "the provider"}.`,
177
+ bodyCompact: (provider, company, to) => noun === "video" ? `Loading this video sends data to ${provider && company && provider !== company ? `${provider} (${company})` : to ?? "a third party"}.` : `Loading this ${noun} sends data to ${to ?? "a third party"}.`,
178
+ load,
179
+ remember
180
+ });
181
+ var en = {
182
+ common: {
183
+ close: "Close",
184
+ cancel: "Cancel",
185
+ back: "Back",
186
+ more: "More",
187
+ done: "Done",
188
+ search: "Search",
189
+ showResults: "Show results",
190
+ loading: "Loading",
191
+ clear: "Clear",
192
+ clearAll: "Clear all",
193
+ noResults: "No results",
194
+ noResultsFor: (q) => `No results for \u201C${q}\u201D`,
195
+ selected: (name) => `${name}: selected`,
196
+ removed: (labels) => `${labels.join(", ")} removed`,
197
+ add: (text) => `Add \u201C${text}\u201D`,
198
+ create: "Create",
199
+ reset: "Reset",
200
+ countSelected: (n) => `${n} selected`,
201
+ selectedValues: "Selected"
202
+ },
203
+ keys: { control: "Ctrl" },
204
+ accordion: { expandAll: "Expand all", collapseAll: "Collapse all" },
205
+ alert: { dismiss: "Dismiss" },
206
+ avatar: {
207
+ status: { online: "online", away: "away", busy: "busy", offline: "offline" },
208
+ unknownPerson: "Unknown person",
209
+ unknownOrganization: "Unknown organization",
210
+ more: (n) => `${n} more`
211
+ },
212
+ breadcrumbs: { label: "Breadcrumb", more: (n) => `Show ${n} more ${s(n, "level", "levels")}` },
213
+ bulkActionBar: { label: "Bulk actions", count: (n) => `${n} selected`, clear: "Clear selection", more: "More actions" },
214
+ calendar: {
215
+ previousMonth: "Previous month",
216
+ nextMonth: "Next month",
217
+ previousYear: "Previous year",
218
+ nextYear: "Next year",
219
+ previousYears: "Previous years",
220
+ nextYears: "Next years",
221
+ chooseMonth: (title) => `${title} \u2013 choose month and year`,
222
+ chooseYear: (year) => `${year} \u2013 choose year`,
223
+ weekNumber: "Wk"
224
+ },
225
+ datePicker: {
226
+ openCalendar: "Open calendar",
227
+ time: "Time",
228
+ presets: "Periods",
229
+ beforeMin: (date) => `Choose a date from ${date} on.`,
230
+ afterMax: (date) => `Choose a date until ${date}.`,
231
+ unavailable: "This day is not available. Choose another day.",
232
+ reversed: "The end date must be after the start date.",
233
+ today: "Today",
234
+ yesterday: "Yesterday",
235
+ last7Days: "Last 7 days",
236
+ last14Days: "Last 14 days",
237
+ last30Days: "Last 30 days",
238
+ thisMonth: "This month",
239
+ lastMonth: "Last month",
240
+ availableTimes: "Available times"
241
+ },
242
+ dialog: {
243
+ discardTitle: "Discard changes?",
244
+ discardDescription: "Your changes will be lost.",
245
+ discardAction: "Discard",
246
+ discardCancel: "Keep editing"
247
+ },
248
+ embed: {
249
+ video: embed2("video", "Load external video", "Load video", (p) => p ? `Always load ${p} videos` : "Always load videos from this provider"),
250
+ map: embed2("map", "Load map", "Load map", (p) => p ? `Always load ${p}` : "Always load maps from this provider"),
251
+ generic: embed2(
252
+ "content",
253
+ "Load external content",
254
+ "Load content",
255
+ (p) => p ? `Always load content from ${p}` : "Always load content from this provider"
256
+ ),
257
+ privacy: "Privacy policy"
258
+ },
259
+ list: { notIncluded: "Not included:" },
260
+ listView: { unread: "Unread" },
261
+ navigation: {
262
+ skipToContent: "Skip to content",
263
+ main: "Main",
264
+ app: "App",
265
+ menu: "Menu",
266
+ collapse: "Collapse navigation",
267
+ expand: "Expand navigation"
268
+ },
269
+ pagination: {
270
+ label: "Pagination",
271
+ summary: (from, to, total) => `${from}\u2013${to} of ${total}`,
272
+ pageSize: "Rows per page",
273
+ previous: "Previous page",
274
+ next: "Next page",
275
+ page: (p) => `Page ${p}`,
276
+ pageOf: (p, total) => `Page ${p} of ${total}`
277
+ },
278
+ quickSearch: {
279
+ placeholder: "Search pages, files, people \u2026",
280
+ suggestions: "Suggestions",
281
+ allResults: (q) => `All results for \u201C${q}\u201D`,
282
+ noResults: (q) => `No results for \u201C${q}\u201D. Check the spelling or try other words.`,
283
+ searchAll: (q) => `Search all content for \u201C${q}\u201D`,
284
+ navigate: "Navigate",
285
+ open: "Open"
286
+ },
287
+ searchField: { clear: "Clear search" },
288
+ select: { placeholder: "Select\u2026", clearSelection: "Clear selection" },
289
+ combobox: { placeholder: "Search\u2026" },
290
+ slider: { minimum: (label) => `Minimum ${label}`.trim(), maximum: (label) => `Maximum ${label}`.trim() },
291
+ table: { columns: "Columns", showColumns: "Show columns", scrollRegion: "Table" },
292
+ textField: {
293
+ counter: (count, limit) => `${count} / ${limit}`,
294
+ tooMany: (over) => `${over} too many`,
295
+ charactersLeft: (left) => `${left} ${s(left, "character", "characters")} left`,
296
+ charactersTooMany: (over) => `${over} ${s(over, "character", "characters")} too many`
297
+ },
298
+ upload: {
299
+ title: "Drag and drop files here",
300
+ dropTitle: "Drop files to upload",
301
+ chooseFiles: "Choose files",
302
+ chooseFile: "Choose file",
303
+ listLabel: "Uploaded files",
304
+ cancel: (name) => `Cancel upload of ${name}`,
305
+ remove: (name) => `Remove ${name}`,
306
+ retry: (name) => `Retry ${name}`,
307
+ retryShort: "Retry",
308
+ uploading: (name) => `Uploading ${name}`,
309
+ progress: (loaded, total, percent) => `${loaded} of ${total} \xB7 ${percent} %`,
310
+ typeNotAllowed: (names, types) => `${names} ${names.includes(",") ? "are" : "is"} not allowed.${types ? ` Use ${types}.` : ""}`,
311
+ tooLarge: (size, max) => `File is ${size} \u2013 max. ${max} allowed`,
312
+ tooMany: (max) => `You can add up to ${max} files. Remove one to add another.`,
313
+ uploaded: (name) => `${name} uploaded`,
314
+ failed: (name, error) => `${name}: ${error}`
315
+ }
316
+ };
317
+
318
+ // src/i18n/I18n.tsx
319
+ import { jsx } from "react/jsx-runtime";
320
+ var builtIn = { en, de };
321
+ var MessagesContext = createContext(null);
322
+ function MessagesProvider({ messages, children }) {
323
+ return /* @__PURE__ */ jsx(MessagesContext.Provider, { value: messages, children });
324
+ }
325
+ function useMessages() {
326
+ const custom = useContext(MessagesContext);
327
+ const { locale } = useLocale();
328
+ return custom ?? builtIn[locale.split("-")[0].toLowerCase()] ?? en;
329
+ }
330
+
13
331
  // src/progress/Progress.tsx
14
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
332
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
15
333
  var SpinnerGraphic = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: [
16
- /* @__PURE__ */ jsx("circle", { className: "medo-spinner__track", cx: "12", cy: "12", r: "10" }),
17
- /* @__PURE__ */ jsx("circle", { className: "medo-spinner__arc", cx: "12", cy: "12", r: "10", pathLength: 100 })
334
+ /* @__PURE__ */ jsx2("circle", { className: "medo-spinner__track", cx: "12", cy: "12", r: "10" }),
335
+ /* @__PURE__ */ jsx2("circle", { className: "medo-spinner__arc", cx: "12", cy: "12", r: "10", pathLength: 100 })
18
336
  ] });
19
337
  function Spinner({ size = "md", tone = "current", decorative, className, style, ...props }) {
338
+ const m = useMessages();
20
339
  const classes = cx("medo-spinner", `medo-spinner--${size}`, tone !== "current" && `medo-spinner--${tone}`, className);
21
340
  if (decorative) {
22
- return /* @__PURE__ */ jsx("span", { className: classes, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx(SpinnerGraphic, {}) });
341
+ return /* @__PURE__ */ jsx2("span", { className: classes, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx2(SpinnerGraphic, {}) });
23
342
  }
24
- return /* @__PURE__ */ jsx(AriaProgressBar, { isIndeterminate: true, "aria-label": props["aria-label"] ?? "Loading", className: classes, style, children: /* @__PURE__ */ jsx(SpinnerGraphic, {}) });
343
+ return /* @__PURE__ */ jsx2(AriaProgressBar, { isIndeterminate: true, "aria-label": props["aria-label"] ?? m.common.loading, className: classes, style, children: /* @__PURE__ */ jsx2(SpinnerGraphic, {}) });
25
344
  }
26
345
  function ProgressBar({
27
346
  label,
@@ -34,7 +353,7 @@ function ProgressBar({
34
353
  ...props
35
354
  }) {
36
355
  const descriptionId = useId();
37
- return /* @__PURE__ */ jsx(
356
+ return /* @__PURE__ */ jsx2(
38
357
  AriaProgressBar,
39
358
  {
40
359
  ...props,
@@ -49,31 +368,31 @@ function ProgressBar({
49
368
  style,
50
369
  children: ({ percentage, valueText, isIndeterminate }) => /* @__PURE__ */ jsxs(Fragment, { children: [
51
370
  (label || showValue && !isIndeterminate) && /* @__PURE__ */ jsxs("div", { className: "medo-progress__header", children: [
52
- label && /* @__PURE__ */ jsx(Label, { className: "medo-progress__label", children: label }),
53
- showValue && !isIndeterminate && /* @__PURE__ */ jsx("span", { className: "medo-progress__value", children: valueText })
371
+ label && /* @__PURE__ */ jsx2(Label, { className: "medo-progress__label", children: label }),
372
+ showValue && !isIndeterminate && /* @__PURE__ */ jsx2("span", { className: "medo-progress__value", children: valueText })
54
373
  ] }),
55
- /* @__PURE__ */ jsx("div", { className: "medo-progress__track", children: /* @__PURE__ */ jsx("div", { className: "medo-progress__fill", style: isIndeterminate ? void 0 : { inlineSize: `${percentage}%` } }) }),
56
- description && // Live only for the final state, so regular updates („12 s left“) do not chatter.
57
- /* @__PURE__ */ jsx("span", { id: descriptionId, className: "medo-progress__description", "aria-live": status === "default" ? void 0 : "polite", children: description })
374
+ /* @__PURE__ */ jsx2("div", { className: "medo-progress__track", children: /* @__PURE__ */ jsx2("div", { className: "medo-progress__fill", style: isIndeterminate ? void 0 : { inlineSize: `${percentage}%` } }) }),
375
+ description && // Live only for the final state, so regular updates (“12 s left”) do not chatter.
376
+ /* @__PURE__ */ jsx2("span", { id: descriptionId, className: "medo-progress__description", "aria-live": status === "default" ? void 0 : "polite", children: description })
58
377
  ] })
59
378
  }
60
379
  );
61
380
  }
62
381
  function Skeleton({ shape = "text", lines = 1, width, height, className }) {
63
382
  const style = { inlineSize: width, blockSize: height };
64
- const one = (key) => /* @__PURE__ */ jsx("span", { className: cx("medo-skeleton", `medo-skeleton--${shape}`, className), style, "aria-hidden": "true" }, key);
383
+ const one = (key) => /* @__PURE__ */ jsx2("span", { className: cx("medo-skeleton", `medo-skeleton--${shape}`, className), style, "aria-hidden": "true" }, key);
65
384
  if (shape !== "text" || lines <= 1) return one();
66
- return /* @__PURE__ */ jsx("span", { className: "medo-skeleton-lines", "aria-hidden": "true", children: Array.from({ length: lines }, (_, i) => one(i)) });
385
+ return /* @__PURE__ */ jsx2("span", { className: "medo-skeleton-lines", "aria-hidden": "true", children: Array.from({ length: lines }, (_, i) => one(i)) });
67
386
  }
68
387
 
69
388
  // src/button/Button.tsx
70
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
389
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
71
390
  function Button({ variant = "primary", size = "md", startIcon, endIcon, className, children, ...props }) {
72
- const icon = props.isPending ? /* @__PURE__ */ jsx2(Spinner, { decorative: true }) : startIcon;
391
+ const icon = props.isPending ? /* @__PURE__ */ jsx3(Spinner, { decorative: true }) : startIcon;
73
392
  return /* @__PURE__ */ jsxs2(AriaButton, { ...props, className: cx("medo-button", `medo-button--${variant}`, `medo-button--${size}`, className), children: [
74
- icon && /* @__PURE__ */ jsx2("span", { className: "medo-button__icon", "aria-hidden": "true", children: icon }),
75
- /* @__PURE__ */ jsx2("span", { className: "medo-button__label", children }),
76
- endIcon && /* @__PURE__ */ jsx2("span", { className: "medo-button__icon", "aria-hidden": "true", children: endIcon })
393
+ icon && /* @__PURE__ */ jsx3("span", { className: "medo-button__icon", "aria-hidden": "true", children: icon }),
394
+ /* @__PURE__ */ jsx3("span", { className: "medo-button__label", children }),
395
+ endIcon && /* @__PURE__ */ jsx3("span", { className: "medo-button__icon", "aria-hidden": "true", children: endIcon })
77
396
  ] });
78
397
  }
79
398
  function ButtonGroup({ context = "footer", children, destructive, className, ...props }) {
@@ -84,7 +403,7 @@ function ButtonGroup({ context = "footer", children, destructive, className, ...
84
403
  "aria-label": props["aria-label"],
85
404
  className: cx("medo-button-group", `medo-button-group--${context}`, className),
86
405
  children: [
87
- destructive && context === "footer" && /* @__PURE__ */ jsx2("div", { className: "medo-button-group__destructive", children: destructive }),
406
+ destructive && context === "footer" && /* @__PURE__ */ jsx3("div", { className: "medo-button-group__destructive", children: destructive }),
88
407
  children
89
408
  ]
90
409
  }
@@ -95,48 +414,49 @@ function ButtonGroup({ context = "footer", children, destructive, className, ...
95
414
  import { Button as AriaButton2 } from "react-aria-components";
96
415
 
97
416
  // src/tooltip/Tooltip.tsx
98
- import { useContext } from "react";
417
+ import { useContext as useContext2 } from "react";
99
418
  import {
100
419
  Link as AriaLink,
101
420
  Tooltip as AriaTooltip,
102
421
  TooltipTrigger as AriaTooltipTrigger,
103
422
  TooltipTriggerStateContext
104
423
  } from "react-aria-components";
105
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
424
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
106
425
  function TooltipTrigger({ delay = 500, closeDelay = 100, ...props }) {
107
- return /* @__PURE__ */ jsx3(AriaTooltipTrigger, { delay, closeDelay, ...props });
426
+ return /* @__PURE__ */ jsx4(AriaTooltipTrigger, { delay, closeDelay, ...props });
108
427
  }
109
- var KEY_LABELS = { Control: "Ctrl", Meta: "\u2318", Shift: "\u21E7", Alt: "Alt" };
428
+ var KEY_LABELS = { Meta: "\u2318", Shift: "\u21E7", Alt: "Alt" };
110
429
  var isApple = () => typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent);
111
430
  var resolveShortcut = (keys) => keys.replace(/\bMod\b/g, isApple() ? "Meta" : "Control");
112
- var formatShortcut = (keys) => resolveShortcut(keys).split("+").map((k) => KEY_LABELS[k] ?? k).join(" ");
431
+ var formatShortcut = (keys, control = "Ctrl") => resolveShortcut(keys).split("+").map((k) => k === "Control" ? control : KEY_LABELS[k] ?? k).join(" ");
113
432
  function Tooltip({ children, shortcut, placement = "top", offset = 8, className, ...props }) {
114
433
  return /* @__PURE__ */ jsxs3(AriaTooltip, { ...props, placement, offset, className: cx("medo-tooltip", className), children: [
115
- /* @__PURE__ */ jsx3("span", { children }),
116
- shortcut && /* @__PURE__ */ jsx3("kbd", { className: "medo-tooltip__shortcut", children: shortcut })
434
+ /* @__PURE__ */ jsx4("span", { children }),
435
+ shortcut && /* @__PURE__ */ jsx4("kbd", { className: "medo-tooltip__shortcut", children: shortcut })
117
436
  ] });
118
437
  }
119
438
  function TooltipLink(props) {
120
- const tooltip = useContext(TooltipTriggerStateContext);
121
- return /* @__PURE__ */ jsx3(AriaLink, { ...props, onHoverStart: () => tooltip?.open(), onHoverEnd: () => tooltip?.close() });
439
+ const tooltip = useContext2(TooltipTriggerStateContext);
440
+ return /* @__PURE__ */ jsx4(AriaLink, { ...props, onHoverStart: () => tooltip?.open(), onHoverEnd: () => tooltip?.close() });
122
441
  }
123
442
 
124
443
  // src/icon-button/IconButton.tsx
125
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
444
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
126
445
  function IconButton({ icon, variant = "ghost", size = "md", tooltip, shortcut, shortcutLabel, className, ...props }) {
127
- const button = /* @__PURE__ */ jsx4(
446
+ const m = useMessages();
447
+ const button = /* @__PURE__ */ jsx5(
128
448
  AriaButton2,
129
449
  {
130
450
  ...props,
131
451
  "aria-keyshortcuts": shortcut && resolveShortcut(shortcut),
132
452
  className: cx("medo-button", "medo-button--icon-only", `medo-button--${variant}`, `medo-button--${size}`, className),
133
- children: /* @__PURE__ */ jsx4("span", { className: "medo-button__icon", "aria-hidden": "true", children: props.isPending ? /* @__PURE__ */ jsx4(Spinner, { decorative: true }) : icon })
453
+ children: /* @__PURE__ */ jsx5("span", { className: "medo-button__icon", "aria-hidden": "true", children: props.isPending ? /* @__PURE__ */ jsx5(Spinner, { decorative: true }) : icon })
134
454
  }
135
455
  );
136
456
  if (tooltip === false) return button;
137
457
  return /* @__PURE__ */ jsxs4(TooltipTrigger, { children: [
138
458
  button,
139
- /* @__PURE__ */ jsx4(Tooltip, { shortcut: shortcutLabel ?? (shortcut && formatShortcut(shortcut)), children: tooltip ?? props["aria-label"] })
459
+ /* @__PURE__ */ jsx5(Tooltip, { shortcut: shortcutLabel ?? (shortcut && formatShortcut(shortcut, m.keys.control)), children: tooltip ?? props["aria-label"] })
140
460
  ] });
141
461
  }
142
462
 
@@ -152,11 +472,11 @@ import {
152
472
  // src/field/Field.tsx
153
473
  import { FieldError, Label as Label2, Text } from "react-aria-components";
154
474
  import { CircleAlert } from "lucide-react";
155
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
475
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
156
476
  function FieldLabel({ children, isRequired }) {
157
477
  return /* @__PURE__ */ jsxs5(Label2, { className: "medo-field__label", children: [
158
478
  children,
159
- isRequired && /* @__PURE__ */ jsx5("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
479
+ isRequired && /* @__PURE__ */ jsx6("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
160
480
  ] });
161
481
  }
162
482
  function FieldFooter({
@@ -165,17 +485,17 @@ function FieldFooter({
165
485
  children
166
486
  }) {
167
487
  return /* @__PURE__ */ jsxs5("div", { className: "medo-field__footer", children: [
168
- description && /* @__PURE__ */ jsx5(Text, { slot: "description", className: "medo-field__description", children: description }),
169
- /* @__PURE__ */ jsx5(FieldError, { className: "medo-field__error", children: (validation) => /* @__PURE__ */ jsxs5(Fragment2, { children: [
170
- /* @__PURE__ */ jsx5(CircleAlert, { "aria-hidden": "true" }),
171
- /* @__PURE__ */ jsx5("span", { children: (typeof errorMessage === "function" ? errorMessage(validation) : errorMessage) || validation.validationErrors.join(" ") })
488
+ description && /* @__PURE__ */ jsx6(Text, { slot: "description", className: "medo-field__description", children: description }),
489
+ /* @__PURE__ */ jsx6(FieldError, { className: "medo-field__error", children: (validation) => /* @__PURE__ */ jsxs5(Fragment2, { children: [
490
+ /* @__PURE__ */ jsx6(CircleAlert, { "aria-hidden": "true" }),
491
+ /* @__PURE__ */ jsx6("span", { children: (typeof errorMessage === "function" ? errorMessage(validation) : errorMessage) || validation.validationErrors.join(" ") })
172
492
  ] }) }),
173
493
  children
174
494
  ] });
175
495
  }
176
496
 
177
497
  // src/text-field/TextField.tsx
178
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
498
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
179
499
  function TextField({
180
500
  label,
181
501
  description,
@@ -202,13 +522,13 @@ function TextField({
202
522
  onChange?.(value);
203
523
  },
204
524
  children: [
205
- /* @__PURE__ */ jsx6(FieldLabel, { isRequired: props.isRequired, children: label }),
206
- multiline ? /* @__PURE__ */ jsx6(AriaTextArea, { className: cx("medo-textarea", `medo-textarea--${size === "lg" ? "lg" : "md"}`), placeholder, onInput: clearErrorWhenValid }) : /* @__PURE__ */ jsxs6("div", { className: cx("medo-input", `medo-input--${size}`), children: [
207
- leadingIcon && /* @__PURE__ */ jsx6("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
208
- /* @__PURE__ */ jsx6(AriaInput, { className: "medo-input__control", placeholder, onInput: clearErrorWhenValid }),
525
+ label && /* @__PURE__ */ jsx7(FieldLabel, { isRequired: props.isRequired, children: label }),
526
+ multiline ? /* @__PURE__ */ jsx7(AriaTextArea, { className: cx("medo-textarea", `medo-textarea--${size === "lg" ? "lg" : "md"}`), placeholder, onInput: clearErrorWhenValid }) : /* @__PURE__ */ jsxs6("div", { className: cx("medo-input", `medo-input--${size}`), children: [
527
+ leadingIcon && /* @__PURE__ */ jsx7("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
528
+ /* @__PURE__ */ jsx7(AriaInput, { className: "medo-input__control", placeholder, onInput: clearErrorWhenValid }),
209
529
  trailing
210
530
  ] }),
211
- /* @__PURE__ */ jsx6(FieldFooter, { description, errorMessage, children: characterLimit !== void 0 && /* @__PURE__ */ jsx6(CharacterCount, { count, limit: characterLimit }) })
531
+ /* @__PURE__ */ jsx7(FieldFooter, { description, errorMessage, children: characterLimit !== void 0 && /* @__PURE__ */ jsx7(CharacterCount, { count, limit: characterLimit }) })
212
532
  ]
213
533
  }
214
534
  );
@@ -220,27 +540,28 @@ function clearErrorWhenValid(e) {
220
540
  });
221
541
  }
222
542
  function CharacterCount({ count, limit }) {
543
+ const m = useMessages();
223
544
  const over = count - limit;
224
- const text = over > 0 ? `${over} too many` : `${count} / ${limit}`;
545
+ const text = over > 0 ? m.textField.tooMany(over) : m.textField.counter(count, limit);
225
546
  const [announcement, setAnnouncement] = useState("");
226
547
  useEffect(() => {
227
548
  const id = setTimeout(
228
- () => setAnnouncement(over > 0 ? `${over} characters too many` : `${limit - count} characters left`),
549
+ () => setAnnouncement(over > 0 ? m.textField.charactersTooMany(over) : m.textField.charactersLeft(limit - count)),
229
550
  1e3
230
551
  );
231
552
  return () => clearTimeout(id);
232
- }, [count, limit, over]);
553
+ }, [count, limit, over, m]);
233
554
  return /* @__PURE__ */ jsxs6(Fragment3, { children: [
234
- /* @__PURE__ */ jsx6("span", { className: "medo-field__counter", "data-over": over > 0 || void 0, "aria-hidden": "true", children: text }),
235
- /* @__PURE__ */ jsx6("span", { className: "medo-visually-hidden", "aria-live": "polite", children: announcement })
555
+ /* @__PURE__ */ jsx7("span", { className: "medo-field__counter", "data-over": over > 0 || void 0, "aria-hidden": "true", children: text }),
556
+ /* @__PURE__ */ jsx7("span", { className: "medo-visually-hidden", "aria-live": "polite", children: announcement })
236
557
  ] });
237
558
  }
238
559
  function InputAction({ icon, ...props }) {
239
- return /* @__PURE__ */ jsx6(AriaButton3, { ...props, className: "medo-input__action", children: icon });
560
+ return /* @__PURE__ */ jsx7(AriaButton3, { ...props, className: "medo-input__action", children: icon });
240
561
  }
241
562
 
242
563
  // src/checkbox/Checkbox.tsx
243
- import { createContext, useContext as useContext2 } from "react";
564
+ import { createContext as createContext2, useContext as useContext3 } from "react";
244
565
  import {
245
566
  CheckboxButton,
246
567
  CheckboxField,
@@ -248,52 +569,52 @@ import {
248
569
  Text as Text2
249
570
  } from "react-aria-components";
250
571
  import { Check, Minus } from "lucide-react";
251
- import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
252
- var ChoiceSizeContext = createContext("md");
572
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
573
+ var ChoiceSizeContext = createContext2("md");
253
574
  function Checkbox({ children, description, size, className, ...props }) {
254
- const groupSize = useContext2(ChoiceSizeContext);
575
+ const groupSize = useContext3(ChoiceSizeContext);
255
576
  return /* @__PURE__ */ jsxs7(CheckboxField, { ...props, className: cx("medo-choice", "medo-checkbox", `medo-choice--${size ?? groupSize}`, className), children: [
256
- /* @__PURE__ */ jsx7(CheckboxButton, { className: "medo-choice__button", children: ({ isSelected, isIndeterminate }) => /* @__PURE__ */ jsxs7(Fragment4, { children: [
257
- /* @__PURE__ */ jsx7("span", { className: "medo-choice__control", "aria-hidden": "true", children: isIndeterminate ? /* @__PURE__ */ jsx7(Minus, {}) : isSelected ? /* @__PURE__ */ jsx7(Check, {}) : null }),
258
- children && /* @__PURE__ */ jsx7("span", { className: "medo-choice__label", children })
577
+ /* @__PURE__ */ jsx8(CheckboxButton, { className: "medo-choice__button", children: ({ isSelected, isIndeterminate }) => /* @__PURE__ */ jsxs7(Fragment4, { children: [
578
+ /* @__PURE__ */ jsx8("span", { className: "medo-choice__control", "aria-hidden": "true", children: isIndeterminate ? /* @__PURE__ */ jsx8(Minus, {}) : isSelected ? /* @__PURE__ */ jsx8(Check, {}) : null }),
579
+ children && /* @__PURE__ */ jsx8("span", { className: "medo-choice__label", children })
259
580
  ] }) }),
260
- description && /* @__PURE__ */ jsx7(Text2, { slot: "description", className: "medo-choice__description", children: description })
581
+ description && /* @__PURE__ */ jsx8(Text2, { slot: "description", className: "medo-choice__description", children: description })
261
582
  ] });
262
583
  }
263
584
  function CheckboxGroup({ label, description, errorMessage, size = "md", orientation = "vertical", children, className, ...props }) {
264
585
  return /* @__PURE__ */ jsxs7(AriaCheckboxGroup, { ...props, className: cx("medo-field", "medo-field--group", className), "data-orientation": orientation, children: [
265
- label && /* @__PURE__ */ jsx7(FieldLabel, { isRequired: props.isRequired, children: label }),
266
- /* @__PURE__ */ jsx7(ChoiceSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx7("div", { className: "medo-field__options", children }) }),
267
- /* @__PURE__ */ jsx7(FieldFooter, { description, errorMessage })
586
+ label && /* @__PURE__ */ jsx8(FieldLabel, { isRequired: props.isRequired, children: label }),
587
+ /* @__PURE__ */ jsx8(ChoiceSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx8("div", { className: "medo-field__options", children }) }),
588
+ /* @__PURE__ */ jsx8(FieldFooter, { description, errorMessage })
268
589
  ] });
269
590
  }
270
591
 
271
592
  // src/radio/Radio.tsx
272
- import { useContext as useContext3 } from "react";
593
+ import { useContext as useContext4 } from "react";
273
594
  import { RadioButton, RadioField, RadioGroup as AriaRadioGroup, Text as Text3 } from "react-aria-components";
274
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
595
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
275
596
  function Radio({ children, description, size, className, ...props }) {
276
- const groupSize = useContext3(ChoiceSizeContext);
597
+ const groupSize = useContext4(ChoiceSizeContext);
277
598
  return /* @__PURE__ */ jsxs8(RadioField, { ...props, className: cx("medo-choice", "medo-radio", `medo-choice--${size ?? groupSize}`, className), children: [
278
599
  /* @__PURE__ */ jsxs8(RadioButton, { className: "medo-choice__button", children: [
279
- /* @__PURE__ */ jsx8("span", { className: "medo-choice__control", "aria-hidden": "true" }),
280
- children && /* @__PURE__ */ jsx8("span", { className: "medo-choice__label", children })
600
+ /* @__PURE__ */ jsx9("span", { className: "medo-choice__control", "aria-hidden": "true" }),
601
+ children && /* @__PURE__ */ jsx9("span", { className: "medo-choice__label", children })
281
602
  ] }),
282
- description && /* @__PURE__ */ jsx8(Text3, { slot: "description", className: "medo-choice__description", children: description })
603
+ description && /* @__PURE__ */ jsx9(Text3, { slot: "description", className: "medo-choice__description", children: description })
283
604
  ] });
284
605
  }
285
606
  function RadioGroup({ label, description, errorMessage, size = "md", children, className, ...props }) {
286
607
  return /* @__PURE__ */ jsxs8(AriaRadioGroup, { ...props, className: cx("medo-field", "medo-field--group", className), children: [
287
- label && /* @__PURE__ */ jsx8(FieldLabel, { isRequired: props.isRequired, children: label }),
288
- /* @__PURE__ */ jsx8(ChoiceSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx8("div", { className: "medo-field__options", children }) }),
289
- /* @__PURE__ */ jsx8(FieldFooter, { description, errorMessage })
608
+ label && /* @__PURE__ */ jsx9(FieldLabel, { isRequired: props.isRequired, children: label }),
609
+ /* @__PURE__ */ jsx9(ChoiceSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx9("div", { className: "medo-field__options", children }) }),
610
+ /* @__PURE__ */ jsx9(FieldFooter, { description, errorMessage })
290
611
  ] });
291
612
  }
292
613
 
293
614
  // src/switch/Switch.tsx
294
615
  import { SwitchButton, SwitchField, Text as Text4 } from "react-aria-components";
295
616
  import { Check as Check2, LoaderCircle, X } from "lucide-react";
296
- import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
617
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
297
618
  function Switch({
298
619
  children,
299
620
  description,
@@ -312,21 +633,21 @@ function Switch({
312
633
  "aria-busy": isLoading || void 0,
313
634
  className: cx("medo-switch", `medo-switch--${size}`, `medo-switch--label-${labelPosition}`, className),
314
635
  children: [
315
- /* @__PURE__ */ jsx9(SwitchButton, { className: "medo-switch__button", children: ({ isSelected }) => /* @__PURE__ */ jsxs9(Fragment5, { children: [
316
- /* @__PURE__ */ jsx9("span", { className: "medo-switch__track", "aria-hidden": "true", children: /* @__PURE__ */ jsx9("span", { className: "medo-switch__thumb", children: isLoading ? /* @__PURE__ */ jsx9(LoaderCircle, { className: "medo-switch__spinner" }) : isSelected ? /* @__PURE__ */ jsx9(Check2, {}) : /* @__PURE__ */ jsx9(X, {}) }) }),
317
- /* @__PURE__ */ jsx9("span", { className: "medo-switch__label", children })
636
+ /* @__PURE__ */ jsx10(SwitchButton, { className: "medo-switch__button", children: ({ isSelected }) => /* @__PURE__ */ jsxs9(Fragment5, { children: [
637
+ /* @__PURE__ */ jsx10("span", { className: "medo-switch__track", "aria-hidden": "true", children: /* @__PURE__ */ jsx10("span", { className: "medo-switch__thumb", children: isLoading ? /* @__PURE__ */ jsx10(LoaderCircle, { className: "medo-switch__spinner" }) : isSelected ? /* @__PURE__ */ jsx10(Check2, {}) : /* @__PURE__ */ jsx10(X, {}) }) }),
638
+ /* @__PURE__ */ jsx10("span", { className: "medo-switch__label", children })
318
639
  ] }) }),
319
- description && /* @__PURE__ */ jsx9(Text4, { slot: "description", className: "medo-switch__description", children: description })
640
+ description && /* @__PURE__ */ jsx10(Text4, { slot: "description", className: "medo-switch__description", children: description })
320
641
  ]
321
642
  }
322
643
  );
323
644
  }
324
645
 
325
646
  // src/badge/Badge.tsx
326
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
647
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
327
648
  function Badge({ tone = "neutral", size = "md", dot, icon, className, children, ...props }) {
328
649
  return /* @__PURE__ */ jsxs10("span", { ...props, className: cx("medo-badge", `medo-badge--${tone}`, `medo-badge--${size}`, className), children: [
329
- dot ? /* @__PURE__ */ jsx10("span", { className: "medo-badge__dot", "aria-hidden": "true" }) : icon && /* @__PURE__ */ jsx10("span", { className: "medo-badge__icon", "aria-hidden": "true", children: icon }),
650
+ dot ? /* @__PURE__ */ jsx11("span", { className: "medo-badge__dot", "aria-hidden": "true" }) : icon && /* @__PURE__ */ jsx11("span", { className: "medo-badge__icon", "aria-hidden": "true", children: icon }),
330
651
  children
331
652
  ] });
332
653
  }
@@ -340,14 +661,14 @@ function BadgeCount({ count, max = 99, tone = "danger", size = "md", label, clas
340
661
  "aria-hidden": label ? void 0 : true,
341
662
  className: cx("medo-badge-count", `medo-badge-count--${tone}`, `medo-badge-count--${size}`, className),
342
663
  children: [
343
- /* @__PURE__ */ jsx10("span", { "aria-hidden": label ? true : void 0, children: text }),
344
- label && /* @__PURE__ */ jsx10("span", { className: "medo-visually-hidden", children: label })
664
+ /* @__PURE__ */ jsx11("span", { "aria-hidden": label ? true : void 0, children: text }),
665
+ label && /* @__PURE__ */ jsx11("span", { className: "medo-visually-hidden", children: label })
345
666
  ]
346
667
  }
347
668
  );
348
669
  }
349
670
  function BadgeDot({ tone = "neutral", label, className, ...props }) {
350
- return /* @__PURE__ */ jsx10(
671
+ return /* @__PURE__ */ jsx11(
351
672
  "span",
352
673
  {
353
674
  ...props,
@@ -360,7 +681,7 @@ function BadgeDot({ tone = "neutral", label, className, ...props }) {
360
681
  }
361
682
 
362
683
  // src/tag/Tag.tsx
363
- import { createContext as createContext2, useContext as useContext4, useRef, useState as useState2 } from "react";
684
+ import { createContext as createContext3, useContext as useContext5, useRef, useState as useState2 } from "react";
364
685
  import {
365
686
  Button as AriaButton4,
366
687
  Tag as AriaTag,
@@ -369,8 +690,8 @@ import {
369
690
  Text as Text5
370
691
  } from "react-aria-components";
371
692
  import { Check as Check3, X as X2 } from "lucide-react";
372
- import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
373
- var TagSizeContext = createContext2("md");
693
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
694
+ var TagSizeContext = createContext3("md");
374
695
  function TagGroup({
375
696
  label,
376
697
  description,
@@ -379,10 +700,12 @@ function TagGroup({
379
700
  items,
380
701
  renderEmptyState,
381
702
  onRemove,
382
- removedMessage = (labels) => `${labels.join(", ")} removed`,
703
+ removedMessage: removedMessageProp,
383
704
  className,
384
705
  ...props
385
706
  }) {
707
+ const m = useMessages();
708
+ const removedMessage = removedMessageProp ?? m.common.removed;
386
709
  const ref = useRef(null);
387
710
  const [announcement, setAnnouncement] = useState2("");
388
711
  const handleRemove = onRemove && ((keys) => {
@@ -393,24 +716,24 @@ function TagGroup({
393
716
  setAnnouncement(removedMessage(labels));
394
717
  });
395
718
  return /* @__PURE__ */ jsxs11(AriaTagGroup, { ...props, ref, onRemove: handleRemove, className: cx("medo-field", "medo-field--group", className), children: [
396
- label && /* @__PURE__ */ jsx11(FieldLabel, { children: label }),
397
- /* @__PURE__ */ jsx11(TagSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx11(TagList, { items, renderEmptyState, className: "medo-tag-list", children }) }),
398
- description && /* @__PURE__ */ jsx11("div", { className: "medo-field__footer", children: /* @__PURE__ */ jsx11(Text5, { slot: "description", className: "medo-field__description", children: description }) }),
399
- /* @__PURE__ */ jsx11("span", { className: "medo-visually-hidden", "aria-live": "polite", children: announcement })
719
+ label && /* @__PURE__ */ jsx12(FieldLabel, { children: label }),
720
+ /* @__PURE__ */ jsx12(TagSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx12(TagList, { items, renderEmptyState, className: "medo-tag-list", children }) }),
721
+ description && /* @__PURE__ */ jsx12("div", { className: "medo-field__footer", children: /* @__PURE__ */ jsx12(Text5, { slot: "description", className: "medo-field__description", children: description }) }),
722
+ /* @__PURE__ */ jsx12("span", { className: "medo-visually-hidden", "aria-live": "polite", children: announcement })
400
723
  ] });
401
724
  }
402
725
  function Tag({ children, icon, textValue, className, ...props }) {
403
- const size = useContext4(TagSizeContext);
404
- return /* @__PURE__ */ jsx11(
726
+ const size = useContext5(TagSizeContext);
727
+ return /* @__PURE__ */ jsx12(
405
728
  AriaTag,
406
729
  {
407
730
  ...props,
408
731
  textValue: textValue ?? (typeof children === "string" ? children : void 0),
409
732
  className: ({ selectionMode }) => cx("medo-tag", `medo-tag--${size}`, selectionMode !== "none" && "medo-tag--selectable", className),
410
733
  children: ({ allowsRemoving, isSelected, selectionMode }) => /* @__PURE__ */ jsxs11(Fragment6, { children: [
411
- selectionMode !== "none" && isSelected ? /* @__PURE__ */ jsx11("span", { className: "medo-tag__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx11(Check3, {}) }) : icon && /* @__PURE__ */ jsx11("span", { className: "medo-tag__icon", "aria-hidden": "true", children: icon }),
412
- /* @__PURE__ */ jsx11("span", { className: "medo-tag__label", children }),
413
- allowsRemoving && /* @__PURE__ */ jsx11(AriaButton4, { slot: "remove", className: "medo-tag__remove", children: /* @__PURE__ */ jsx11(X2, { "aria-hidden": "true" }) })
734
+ selectionMode !== "none" && isSelected ? /* @__PURE__ */ jsx12("span", { className: "medo-tag__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx12(Check3, {}) }) : icon && /* @__PURE__ */ jsx12("span", { className: "medo-tag__icon", "aria-hidden": "true", children: icon }),
735
+ /* @__PURE__ */ jsx12("span", { className: "medo-tag__label", children }),
736
+ allowsRemoving && /* @__PURE__ */ jsx12(AriaButton4, { slot: "remove", className: "medo-tag__remove", children: /* @__PURE__ */ jsx12(X2, { "aria-hidden": "true" }) })
414
737
  ] })
415
738
  }
416
739
  );
@@ -420,17 +743,17 @@ function Tag({ children, icon, textValue, className, ...props }) {
420
743
  import {
421
744
  Children,
422
745
  cloneElement,
423
- createContext as createContext3,
746
+ createContext as createContext4,
424
747
  isValidElement,
425
- useContext as useContext5,
748
+ useContext as useContext6,
426
749
  useEffect as useEffect2,
427
750
  useState as useState3
428
751
  } from "react";
429
752
  import { Button as AriaButton5 } from "react-aria-components";
430
753
  import { Building2, User } from "lucide-react";
431
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
754
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
432
755
  var TONES = ["blue", "violet", "pink", "amber", "green", "teal"];
433
- var AvatarSizeContext = createContext3(void 0);
756
+ var AvatarSizeContext = createContext4(void 0);
434
757
  function toneFor(key) {
435
758
  let hash = 0;
436
759
  for (const char of key) hash = hash * 31 + char.codePointAt(0) | 0;
@@ -442,7 +765,6 @@ function initialsOf(name) {
442
765
  if (words.length === 1) return Array.from(words[0]).slice(0, 2).join("").toUpperCase();
443
766
  return (Array.from(words[0])[0] + Array.from(words[words.length - 1])[0]).toUpperCase();
444
767
  }
445
- var STATUS_TEXT = { online: "online", away: "away", busy: "busy", offline: "offline" };
446
768
  function Avatar({
447
769
  name,
448
770
  src,
@@ -456,15 +778,16 @@ function Avatar({
456
778
  className,
457
779
  style
458
780
  }) {
459
- const groupSize = useContext5(AvatarSizeContext);
781
+ const m = useMessages();
782
+ const groupSize = useContext6(AvatarSizeContext);
460
783
  const finalSize = size ?? groupSize ?? "md";
461
784
  const [failed, setFailed] = useState3(false);
462
785
  useEffect2(() => setFailed(false), [src]);
463
786
  const initials = name ? initialsOf(name) : "";
464
787
  const showImage = Boolean(src) && !failed;
465
788
  const tone = initials ? toneFor(colorKey ?? name) : "neutral";
466
- const statusText = status ? statusLabels?.[status] ?? STATUS_TEXT[status] : void 0;
467
- const fallbackName = unknownLabel ?? (shape === "square" ? "Unknown organization" : "Unknown person");
789
+ const statusText = status ? statusLabels?.[status] ?? m.avatar.status[status] : void 0;
790
+ const fallbackName = unknownLabel ?? (shape === "square" ? m.avatar.unknownOrganization : m.avatar.unknownPerson);
468
791
  const label = [name || fallbackName, statusText].filter(Boolean).join(", ");
469
792
  return /* @__PURE__ */ jsxs12(
470
793
  "span",
@@ -482,9 +805,9 @@ function Avatar({
482
805
  ),
483
806
  style,
484
807
  children: [
485
- initials ? /* @__PURE__ */ jsx12("span", { className: "medo-avatar__initials", "aria-hidden": "true", children: initials }) : /* @__PURE__ */ jsx12("span", { className: "medo-avatar__icon", "aria-hidden": "true", children: shape === "square" ? /* @__PURE__ */ jsx12(Building2, {}) : /* @__PURE__ */ jsx12(User, {}) }),
486
- showImage && /* @__PURE__ */ jsx12("img", { className: "medo-avatar__image", src, alt: "", onError: () => setFailed(true) }),
487
- status && /* @__PURE__ */ jsx12("span", { className: cx("medo-avatar__status", `medo-avatar__status--${status}`), "aria-hidden": "true" })
808
+ initials ? /* @__PURE__ */ jsx13("span", { className: "medo-avatar__initials", "aria-hidden": "true", children: initials }) : /* @__PURE__ */ jsx13("span", { className: "medo-avatar__icon", "aria-hidden": "true", children: shape === "square" ? /* @__PURE__ */ jsx13(Building2, {}) : /* @__PURE__ */ jsx13(User, {}) }),
809
+ showImage && /* @__PURE__ */ jsx13("img", { className: "medo-avatar__image", src, alt: "", onError: () => setFailed(true) }),
810
+ status && /* @__PURE__ */ jsx13("span", { className: cx("medo-avatar__status", `medo-avatar__status--${status}`), "aria-hidden": "true" })
488
811
  ]
489
812
  }
490
813
  );
@@ -494,16 +817,18 @@ function AvatarGroup({
494
817
  max = 4,
495
818
  size = "md",
496
819
  onMorePress,
497
- moreLabel = (n) => `${n} more`,
820
+ moreLabel: moreLabelProp,
498
821
  className,
499
822
  ...props
500
823
  }) {
824
+ const m = useMessages();
825
+ const moreLabel = moreLabelProp ?? m.avatar.more;
501
826
  const items = Children.toArray(children);
502
827
  const visible = items.slice(0, max);
503
828
  const hidden = items.length - visible.length;
504
829
  const moreClass = cx("medo-avatar", `medo-avatar--${size}`, "medo-avatar--circle", "medo-avatar--neutral", "medo-avatar--more");
505
830
  return /* @__PURE__ */ jsxs12("div", { role: "group", "aria-label": props["aria-label"], className: cx("medo-avatar-group", `medo-avatar-group--${size}`, className), children: [
506
- /* @__PURE__ */ jsx12(AvatarSizeContext.Provider, { value: size, children: visible.map(
831
+ /* @__PURE__ */ jsx13(AvatarSizeContext.Provider, { value: size, children: visible.map(
507
832
  (child, i) => (
508
833
  // The first avatar sits on top.
509
834
  isValidElement(child) ? cloneElement(child, { style: { ...child.props.style, zIndex: visible.length - i } }) : child
@@ -520,7 +845,7 @@ function AvatarGroup({
520
845
  }
521
846
 
522
847
  // src/toggle-button/ToggleButton.tsx
523
- import { createContext as createContext4, useContext as useContext6, useEffect as useEffect3, useRef as useRef2 } from "react";
848
+ import { createContext as createContext5, useContext as useContext7, useEffect as useEffect3, useRef as useRef2 } from "react";
524
849
  import {
525
850
  SelectionIndicator,
526
851
  Separator,
@@ -528,23 +853,24 @@ import {
528
853
  ToggleButtonGroup as AriaToggleButtonGroup,
529
854
  Toolbar as AriaToolbar
530
855
  } from "react-aria-components";
531
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
532
- var ToggleSizeContext = createContext4(null);
533
- var SegmentedContext = createContext4(false);
856
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
857
+ var ToggleSizeContext = createContext5(null);
858
+ var SegmentedContext = createContext5(false);
534
859
  function ToggleButton({ children, icon, size, tooltip, shortcut, className, ...props }) {
535
- const groupSize = useContext6(ToggleSizeContext);
536
- const segmented = useContext6(SegmentedContext);
537
- const s = groupSize ?? size ?? "md";
860
+ const m = useMessages();
861
+ const groupSize = useContext7(ToggleSizeContext);
862
+ const segmented = useContext7(SegmentedContext);
863
+ const s2 = groupSize ?? size ?? "md";
538
864
  const iconOnly = !children;
539
865
  const button = /* @__PURE__ */ jsxs13(
540
866
  AriaToggleButton,
541
867
  {
542
868
  ...props,
543
869
  "aria-keyshortcuts": shortcut && resolveShortcut(shortcut),
544
- className: cx("medo-button", `medo-button--${s}`, iconOnly && "medo-button--icon-only", "medo-toggle", className),
870
+ className: cx("medo-button", `medo-button--${s2}`, iconOnly && "medo-button--icon-only", "medo-toggle", className),
545
871
  children: [
546
- segmented && /* @__PURE__ */ jsx13(SelectionIndicator, { className: "medo-toggle__indicator" }),
547
- icon && /* @__PURE__ */ jsx13("span", { className: "medo-button__icon", "aria-hidden": "true", children: icon }),
872
+ segmented && /* @__PURE__ */ jsx14(SelectionIndicator, { className: "medo-toggle__indicator" }),
873
+ icon && /* @__PURE__ */ jsx14("span", { className: "medo-button__icon", "aria-hidden": "true", children: icon }),
548
874
  children
549
875
  ]
550
876
  }
@@ -552,7 +878,7 @@ function ToggleButton({ children, icon, size, tooltip, shortcut, className, ...p
552
878
  if (!iconOnly || tooltip === false) return button;
553
879
  return /* @__PURE__ */ jsxs13(TooltipTrigger, { children: [
554
880
  button,
555
- /* @__PURE__ */ jsx13(Tooltip, { shortcut: shortcut && formatShortcut(shortcut), children: tooltip ?? props["aria-label"] })
881
+ /* @__PURE__ */ jsx14(Tooltip, { shortcut: shortcut && formatShortcut(shortcut, m.keys.control), children: tooltip ?? props["aria-label"] })
556
882
  ] });
557
883
  }
558
884
  function ToggleButtonGroup({
@@ -579,7 +905,7 @@ function ToggleButtonGroup({
579
905
  return () => observer.disconnect();
580
906
  }, []);
581
907
  const itemSize = segmented ? size === "lg" ? "md" : "sm" : size;
582
- return /* @__PURE__ */ jsx13(
908
+ return /* @__PURE__ */ jsx14(
583
909
  AriaToggleButtonGroup,
584
910
  {
585
911
  ...props,
@@ -587,19 +913,19 @@ function ToggleButtonGroup({
587
913
  selectionMode: segmented ? "single" : selectionMode ?? "multiple",
588
914
  disallowEmptySelection: segmented || disallowEmptySelection,
589
915
  className: cx("medo-toggle-group", `medo-toggle-group--${variant}`, `medo-toggle-group--${size}`, segmented && fullWidth && "medo-toggle-group--full", className),
590
- children: /* @__PURE__ */ jsx13(SegmentedContext.Provider, { value: segmented, children: /* @__PURE__ */ jsx13(ToggleSizeContext.Provider, { value: itemSize, children }) })
916
+ children: /* @__PURE__ */ jsx14(SegmentedContext.Provider, { value: segmented, children: /* @__PURE__ */ jsx14(ToggleSizeContext.Provider, { value: itemSize, children }) })
591
917
  }
592
918
  );
593
919
  }
594
920
  function Toolbar({ className, ...props }) {
595
- return /* @__PURE__ */ jsx13(AriaToolbar, { ...props, className: cx("medo-toolbar", className) });
921
+ return /* @__PURE__ */ jsx14(AriaToolbar, { ...props, className: cx("medo-toolbar", className) });
596
922
  }
597
923
  function ToolbarSeparator() {
598
- return /* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "medo-toolbar__separator" });
924
+ return /* @__PURE__ */ jsx14(Separator, { orientation: "vertical", className: "medo-toolbar__separator" });
599
925
  }
600
926
 
601
927
  // src/listbox/ListBox.tsx
602
- import { createContext as createContext5, useContext as useContext7 } from "react";
928
+ import { createContext as createContext6, useContext as useContext8 } from "react";
603
929
  import {
604
930
  Collection,
605
931
  ComboBoxStateContext,
@@ -612,7 +938,7 @@ import {
612
938
  import { Check as Check4 } from "lucide-react";
613
939
 
614
940
  // src/utils/highlight.tsx
615
- import { jsx as jsx14 } from "react/jsx-runtime";
941
+ import { jsx as jsx15 } from "react/jsx-runtime";
616
942
  var plain = (text) => text.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLocaleLowerCase();
617
943
  function matchParts(text, query, all = false) {
618
944
  const q = plain(query.trim());
@@ -651,57 +977,57 @@ function Highlight({
651
977
  }) {
652
978
  if (!query?.trim()) return text;
653
979
  return matchParts(text, query, all).map(
654
- (part, i) => part.match ? /* @__PURE__ */ jsx14(Tag2, { className, children: part.text }, i) : part.text
980
+ (part, i) => part.match ? /* @__PURE__ */ jsx15(Tag2, { className, children: part.text }, i) : part.text
655
981
  );
656
982
  }
657
983
 
658
984
  // src/listbox/ListBox.tsx
659
- import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
660
- var ListBoxSizeContext = createContext5("md");
985
+ import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
986
+ var ListBoxSizeContext = createContext6("md");
661
987
  function ListBox({ size = "md", className, ...props }) {
662
- return /* @__PURE__ */ jsx15(ListBoxSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx15(AriaListBox, { ...props, className: cx("medo-listbox", `medo-listbox--${size}`, className) }) });
988
+ return /* @__PURE__ */ jsx16(ListBoxSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsx16(AriaListBox, { ...props, className: cx("medo-listbox", `medo-listbox--${size}`, className) }) });
663
989
  }
664
990
  function Option({ children, description, icon, textValue, ...props }) {
665
- const size = useContext7(ListBoxSizeContext);
666
- return /* @__PURE__ */ jsx15(ListBoxItem, { ...props, textValue: textValue ?? (typeof children === "string" ? children : void 0), className: "medo-option", children: ({ isSelected, selectionMode }) => /* @__PURE__ */ jsxs14(Fragment7, { children: [
667
- selectionMode === "multiple" && /* @__PURE__ */ jsx15(
991
+ const size = useContext8(ListBoxSizeContext);
992
+ return /* @__PURE__ */ jsx16(ListBoxItem, { ...props, textValue: textValue ?? (typeof children === "string" ? children : void 0), className: "medo-option", children: ({ isSelected, selectionMode }) => /* @__PURE__ */ jsxs14(Fragment7, { children: [
993
+ selectionMode === "multiple" && /* @__PURE__ */ jsx16(
668
994
  "span",
669
995
  {
670
996
  className: cx("medo-choice", "medo-checkbox", `medo-choice--${size}`, "medo-option__checkbox"),
671
997
  "data-selected": isSelected || void 0,
672
998
  "aria-hidden": "true",
673
- children: /* @__PURE__ */ jsx15("span", { className: "medo-choice__control", children: isSelected && /* @__PURE__ */ jsx15(Check4, {}) })
999
+ children: /* @__PURE__ */ jsx16("span", { className: "medo-choice__control", children: isSelected && /* @__PURE__ */ jsx16(Check4, {}) })
674
1000
  }
675
1001
  ),
676
- icon && /* @__PURE__ */ jsx15("span", { className: "medo-option__icon", "aria-hidden": "true", children: icon }),
1002
+ icon && /* @__PURE__ */ jsx16("span", { className: "medo-option__icon", "aria-hidden": "true", children: icon }),
677
1003
  /* @__PURE__ */ jsxs14("span", { className: "medo-option__content", children: [
678
- /* @__PURE__ */ jsx15(Text6, { slot: "label", className: "medo-option__label", children: /* @__PURE__ */ jsx15(Highlight2, { children }) }),
679
- description && /* @__PURE__ */ jsx15(Text6, { slot: "description", className: "medo-option__description", children: description })
1004
+ /* @__PURE__ */ jsx16(Text6, { slot: "label", className: "medo-option__label", children: /* @__PURE__ */ jsx16(Highlight2, { children }) }),
1005
+ description && /* @__PURE__ */ jsx16(Text6, { slot: "description", className: "medo-option__description", children: description })
680
1006
  ] }),
681
- selectionMode !== "multiple" && isSelected && /* @__PURE__ */ jsx15("span", { className: "medo-option__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx15(Check4, {}) })
1007
+ selectionMode !== "multiple" && isSelected && /* @__PURE__ */ jsx16("span", { className: "medo-option__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(Check4, {}) })
682
1008
  ] }) });
683
1009
  }
684
1010
  function ListBoxSection({ title, children, items, id, ...props }) {
685
1011
  return /* @__PURE__ */ jsxs14(AriaListBoxSection, { id, "aria-label": props["aria-label"], className: "medo-listbox__section", children: [
686
- title && /* @__PURE__ */ jsx15(Header, { className: "medo-listbox__header", children: title }),
687
- typeof children === "function" ? /* @__PURE__ */ jsx15(Collection, { items, children }) : children
1012
+ title && /* @__PURE__ */ jsx16(Header, { className: "medo-listbox__header", children: title }),
1013
+ typeof children === "function" ? /* @__PURE__ */ jsx16(Collection, { items, children }) : children
688
1014
  ] });
689
1015
  }
690
1016
  function ListBoxMessage({ children }) {
691
- return /* @__PURE__ */ jsx15("div", { className: "medo-listbox__message", role: "status", children });
1017
+ return /* @__PURE__ */ jsx16("div", { className: "medo-listbox__message", role: "status", children });
692
1018
  }
693
- var OptionHighlightContext = createContext5(null);
1019
+ var OptionHighlightContext = createContext6(null);
694
1020
  function Highlight2({ children }) {
695
- const combo = useContext7(ComboBoxStateContext);
696
- const external = useContext7(OptionHighlightContext);
1021
+ const combo = useContext8(ComboBoxStateContext);
1022
+ const external = useContext8(OptionHighlightContext);
697
1023
  let query = (external ?? combo?.inputValue ?? "").trim();
698
1024
  if (combo?.selectedItems.some((item) => item?.textValue === query)) query = "";
699
- if (!query || typeof children !== "string") return /* @__PURE__ */ jsx15(Fragment7, { children });
700
- return /* @__PURE__ */ jsx15(Highlight, { text: children, query, as: "span", className: "medo-option__match" });
1025
+ if (!query || typeof children !== "string") return /* @__PURE__ */ jsx16(Fragment7, { children });
1026
+ return /* @__PURE__ */ jsx16(Highlight, { text: children, query, as: "span", className: "medo-option__match" });
701
1027
  }
702
1028
 
703
1029
  // src/select/Select.tsx
704
- import { useContext as useContext9, useEffect as useEffect4, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState5 } from "react";
1030
+ import { useContext as useContext10, useEffect as useEffect4, useLayoutEffect as useLayoutEffect2, useRef as useRef4, useState as useState5 } from "react";
705
1031
  import {
706
1032
  Button as AriaButton6,
707
1033
  Popover as Popover2,
@@ -712,10 +1038,10 @@ import {
712
1038
  import { ChevronDown, X as X4 } from "lucide-react";
713
1039
 
714
1040
  // src/bottom-sheet/BottomSheet.tsx
715
- import { useContext as useContext8, useId as useId2, useRef as useRef3 } from "react";
1041
+ import { useContext as useContext9, useId as useId2, useRef as useRef3 } from "react";
716
1042
  import { Dialog, Heading, Modal, ModalOverlay, OverlayTriggerStateContext, Popover } from "react-aria-components";
717
1043
  import { ChevronLeft, X as X3 } from "lucide-react";
718
- import { Fragment as Fragment8, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1044
+ import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
719
1045
  var CLOSE_DISTANCE = 0.25;
720
1046
  var CLOSE_VELOCITY = 0.5;
721
1047
  function BottomSheet({
@@ -723,24 +1049,25 @@ function BottomSheet({
723
1049
  children,
724
1050
  footer,
725
1051
  height = "content",
726
- closeLabel = "Close",
1052
+ closeLabel,
727
1053
  onBack,
728
- backLabel = "Back",
1054
+ backLabel,
729
1055
  isDismissable = true,
730
1056
  className,
731
1057
  ...props
732
1058
  }) {
733
- return /* @__PURE__ */ jsx16(ModalOverlay, { ...props, isDismissable, className: "medo-sheet-overlay", children: /* @__PURE__ */ jsx16(Modal, { className: cx("medo-sheet", height === "full" && "medo-sheet--full", className), children: /* @__PURE__ */ jsx16(Dialog, { className: "medo-sheet__dialog", children: ({ close }) => /* @__PURE__ */ jsxs15(Fragment8, { children: [
1059
+ const m = useMessages();
1060
+ return /* @__PURE__ */ jsx17(ModalOverlay, { ...props, isDismissable, className: "medo-sheet-overlay", children: /* @__PURE__ */ jsx17(Modal, { className: cx("medo-sheet", height === "full" && "medo-sheet--full", className), children: /* @__PURE__ */ jsx17(Dialog, { className: "medo-sheet__dialog", children: ({ close }) => /* @__PURE__ */ jsxs15(Fragment8, { children: [
734
1061
  /* @__PURE__ */ jsxs15(SwipeArea, { onClose: close, children: [
735
- /* @__PURE__ */ jsx16("span", { className: "medo-sheet__handle", "aria-hidden": "true" }),
1062
+ /* @__PURE__ */ jsx17("span", { className: "medo-sheet__handle", "aria-hidden": "true" }),
736
1063
  /* @__PURE__ */ jsxs15("div", { className: "medo-sheet__header", children: [
737
- onBack && /* @__PURE__ */ jsx16(IconButton, { variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx16(ChevronLeft, {}), "aria-label": backLabel, tooltip: false, onPress: onBack }),
738
- /* @__PURE__ */ jsx16(Heading, { slot: "title", className: "medo-sheet__title", children: title }),
739
- /* @__PURE__ */ jsx16(IconButton, { variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx16(X3, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
1064
+ onBack && /* @__PURE__ */ jsx17(IconButton, { variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx17(ChevronLeft, {}), "aria-label": backLabel ?? m.common.back, tooltip: false, onPress: onBack }),
1065
+ /* @__PURE__ */ jsx17(Heading, { slot: "title", className: "medo-sheet__title", children: title }),
1066
+ /* @__PURE__ */ jsx17(IconButton, { variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx17(X3, {}), "aria-label": closeLabel ?? m.common.close, tooltip: false, onPress: close })
740
1067
  ] })
741
1068
  ] }),
742
- /* @__PURE__ */ jsx16("div", { className: "medo-sheet__content", children }),
743
- footer && /* @__PURE__ */ jsx16("div", { className: "medo-sheet__footer", children: typeof footer === "function" ? footer(close) : footer })
1069
+ /* @__PURE__ */ jsx17("div", { className: "medo-sheet__content", children }),
1070
+ footer && /* @__PURE__ */ jsx17("div", { className: "medo-sheet__footer", children: typeof footer === "function" ? footer(close) : footer })
744
1071
  ] }) }) }) });
745
1072
  }
746
1073
  function SwipeArea({ onClose, children }) {
@@ -768,33 +1095,34 @@ function SwipeArea({ onClose, children }) {
768
1095
  d.sheet.style.transform = "";
769
1096
  if (dy > d.sheet.offsetHeight * CLOSE_DISTANCE || velocity > CLOSE_VELOCITY && dy > 24) onClose();
770
1097
  };
771
- return /* @__PURE__ */ jsx16("div", { className: "medo-sheet__grab", onPointerDown, onPointerMove, onPointerUp: end, onPointerCancel: end, children });
1098
+ return /* @__PURE__ */ jsx17("div", { className: "medo-sheet__grab", onPointerDown, onPointerMove, onPointerUp: end, onPointerCancel: end, children });
772
1099
  }
773
1100
  function BottomSheetPopover({
774
1101
  title,
775
1102
  children,
776
1103
  footer,
777
1104
  height = "content",
778
- closeLabel = "Close"
1105
+ closeLabel
779
1106
  }) {
780
- return /* @__PURE__ */ jsx16(Popover, { className: "medo-sheet-overlay medo-sheet-overlay--popover", offset: 0, containerPadding: 0, children: /* @__PURE__ */ jsx16(SheetPopoverBody, { title, footer, height, closeLabel, children }) });
1107
+ return /* @__PURE__ */ jsx17(Popover, { className: "medo-sheet-overlay medo-sheet-overlay--popover", offset: 0, containerPadding: 0, children: /* @__PURE__ */ jsx17(SheetPopoverBody, { title, footer, height, closeLabel, children }) });
781
1108
  }
782
1109
  function SheetPopoverBody({ title, children, footer, height, closeLabel }) {
783
- const state = useContext8(OverlayTriggerStateContext);
1110
+ const m = useMessages();
1111
+ const state = useContext9(OverlayTriggerStateContext);
784
1112
  const titleId = useId2();
785
1113
  const close = () => state?.close();
786
1114
  return (
787
1115
  // A tap on the scrim (outside the sheet) closes it.
788
- /* @__PURE__ */ jsx16("div", { className: "medo-sheet-scrim", onClick: (e) => e.target === e.currentTarget && close(), children: /* @__PURE__ */ jsxs15("section", { className: cx("medo-sheet", height === "full" && "medo-sheet--full"), "aria-labelledby": titleId, children: [
1116
+ /* @__PURE__ */ jsx17("div", { className: "medo-sheet-scrim", onClick: (e) => e.target === e.currentTarget && close(), children: /* @__PURE__ */ jsxs15("section", { className: cx("medo-sheet", height === "full" && "medo-sheet--full"), "aria-labelledby": titleId, children: [
789
1117
  /* @__PURE__ */ jsxs15(SwipeArea, { onClose: close, children: [
790
- /* @__PURE__ */ jsx16("span", { className: "medo-sheet__handle", "aria-hidden": "true" }),
1118
+ /* @__PURE__ */ jsx17("span", { className: "medo-sheet__handle", "aria-hidden": "true" }),
791
1119
  /* @__PURE__ */ jsxs15("div", { className: "medo-sheet__header", children: [
792
- /* @__PURE__ */ jsx16("h2", { id: titleId, className: "medo-sheet__title", children: title }),
793
- /* @__PURE__ */ jsx16(IconButton, { slot: null, variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx16(X3, {}), "aria-label": closeLabel ?? "Close", tooltip: false, onPress: close })
1120
+ /* @__PURE__ */ jsx17("h2", { id: titleId, className: "medo-sheet__title", children: title }),
1121
+ /* @__PURE__ */ jsx17(IconButton, { slot: null, variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx17(X3, {}), "aria-label": closeLabel ?? m.common.close, tooltip: false, onPress: close })
794
1122
  ] })
795
1123
  ] }),
796
- /* @__PURE__ */ jsx16("div", { className: "medo-sheet__content", children }),
797
- footer && /* @__PURE__ */ jsx16("div", { className: "medo-sheet__footer", children: typeof footer === "function" ? footer(close) : footer })
1124
+ /* @__PURE__ */ jsx17("div", { className: "medo-sheet__content", children }),
1125
+ footer && /* @__PURE__ */ jsx17("div", { className: "medo-sheet__footer", children: typeof footer === "function" ? footer(close) : footer })
798
1126
  ] }) })
799
1127
  );
800
1128
  }
@@ -847,12 +1175,12 @@ function useMediaQuery(query) {
847
1175
  }
848
1176
 
849
1177
  // src/select/Select.tsx
850
- import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1178
+ import { Fragment as Fragment9, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
851
1179
  function Select({
852
1180
  label,
853
1181
  description,
854
1182
  errorMessage,
855
- placeholder = "Select\u2026",
1183
+ placeholder: placeholderProp,
856
1184
  size = "md",
857
1185
  leadingIcon,
858
1186
  clearable,
@@ -862,11 +1190,14 @@ function Select({
862
1190
  overlay = "auto",
863
1191
  commit = "live",
864
1192
  onApply,
865
- resultLabel = () => "Show results",
1193
+ resultLabel: resultLabelProp,
866
1194
  className,
867
1195
  selectionMode,
868
1196
  ...props
869
1197
  }) {
1198
+ const m = useMessages();
1199
+ const placeholder = placeholderProp ?? m.select.placeholder;
1200
+ const resultLabel = resultLabelProp ?? (() => m.common.showResults);
870
1201
  const multiple = selectionMode === "multiple";
871
1202
  const mobile = useMediaQuery(MOBILE_QUERY);
872
1203
  const mode = overlay === "auto" ? mobile ? multiple ? "sheet" : "native" : "popover" : overlay === "native" && multiple ? "sheet" : overlay;
@@ -888,52 +1219,53 @@ function Select({
888
1219
  className
889
1220
  ),
890
1221
  children: [
891
- label && /* @__PURE__ */ jsx17(FieldLabel, { isRequired: props.isRequired, children: label }),
1222
+ label && /* @__PURE__ */ jsx18(FieldLabel, { isRequired: props.isRequired, children: label }),
892
1223
  /* @__PURE__ */ jsxs16("div", { ref: fieldRef, className: cx("medo-input", `medo-input--${size}`, "medo-select__field"), children: [
893
- /* @__PURE__ */ jsx17(ReadOnlyKeys, { isReadOnly, children: /* @__PURE__ */ jsxs16(AriaButton6, { className: "medo-select__trigger", excludeFromTabOrder: mode === "native", "aria-hidden": mode === "native" || void 0, children: [
894
- leadingIcon && /* @__PURE__ */ jsx17("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
895
- /* @__PURE__ */ jsx17(SelectValue, { className: "medo-select__value", children: ({ defaultChildren, isPlaceholder, selectedText }) => /* @__PURE__ */ jsxs16(Fragment9, { children: [
896
- isPlaceholder ? defaultChildren : multiple ? /* @__PURE__ */ jsx17(SelectedTags, { size }) : selectedText,
897
- isReadOnly && /* @__PURE__ */ jsx17("span", { className: "medo-visually-hidden", children: ", read only" })
1224
+ /* @__PURE__ */ jsx18(ReadOnlyKeys, { isReadOnly, children: /* @__PURE__ */ jsxs16(AriaButton6, { className: "medo-select__trigger", excludeFromTabOrder: mode === "native", "aria-hidden": mode === "native" || void 0, children: [
1225
+ leadingIcon && /* @__PURE__ */ jsx18("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
1226
+ /* @__PURE__ */ jsx18(SelectValue, { className: "medo-select__value", children: ({ defaultChildren, isPlaceholder, selectedText }) => /* @__PURE__ */ jsxs16(Fragment9, { children: [
1227
+ isPlaceholder ? defaultChildren : multiple ? /* @__PURE__ */ jsx18(SelectedTags, { size }) : selectedText,
1228
+ isReadOnly && /* @__PURE__ */ jsx18("span", { className: "medo-visually-hidden", children: ", read only" })
898
1229
  ] }) }),
899
- !isReadOnly && /* @__PURE__ */ jsx17("span", { className: "medo-select__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(ChevronDown, {}) })
1230
+ !isReadOnly && /* @__PURE__ */ jsx18("span", { className: "medo-select__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx18(ChevronDown, {}) })
900
1231
  ] }) }),
901
- mode === "native" && !isReadOnly && /* @__PURE__ */ jsx17(NativePicker, { label: label ?? props["aria-label"], placeholder, isRequired: props.isRequired }),
902
- /* @__PURE__ */ jsx17(ClearButton, { enabled: (multiple || !!clearable) && !isReadOnly && !props.isDisabled, onHasValue: setHasValue })
1232
+ mode === "native" && !isReadOnly && /* @__PURE__ */ jsx18(NativePicker, { label: label ?? props["aria-label"], placeholder, isRequired: props.isRequired }),
1233
+ /* @__PURE__ */ jsx18(ClearButton, { enabled: (multiple || !!clearable) && !isReadOnly && !props.isDisabled, onHasValue: setHasValue })
903
1234
  ] }),
904
- /* @__PURE__ */ jsx17(FieldFooter, { description, errorMessage }),
905
- commit === "onClose" && onApply && /* @__PURE__ */ jsx17(ApplyOnClose, { onApply }),
906
- mode === "sheet" ? /* @__PURE__ */ jsx17(
1235
+ /* @__PURE__ */ jsx18(FieldFooter, { description, errorMessage }),
1236
+ commit === "onClose" && onApply && /* @__PURE__ */ jsx18(ApplyOnClose, { onApply }),
1237
+ mode === "sheet" ? /* @__PURE__ */ jsx18(
907
1238
  BottomSheetPopover,
908
1239
  {
909
1240
  title: label ?? props["aria-label"],
910
- footer: multiple ? /* @__PURE__ */ jsx17(SheetFooter, { commit, resultLabel }) : void 0,
911
- children: /* @__PURE__ */ jsx17(ListBox, { size: "lg", items, children })
1241
+ footer: multiple ? /* @__PURE__ */ jsx18(SheetFooter, { commit, resultLabel }) : void 0,
1242
+ children: /* @__PURE__ */ jsx18(ListBox, { size: "lg", items, children })
912
1243
  }
913
- ) : /* @__PURE__ */ jsx17(Popover2, { triggerRef: fieldRef, offset: 4, className: "medo-listbox-popover", children: /* @__PURE__ */ jsx17(ListBox, { size: size === "lg" ? "lg" : "md", items, children }) })
1244
+ ) : /* @__PURE__ */ jsx18(Popover2, { triggerRef: fieldRef, offset: 4, className: "medo-listbox-popover", children: /* @__PURE__ */ jsx18(ListBox, { size: size === "lg" ? "lg" : "md", items, children }) })
914
1245
  ]
915
1246
  }
916
1247
  );
917
1248
  }
918
1249
  function ReadOnlyKeys({ isReadOnly, children }) {
919
- if (!isReadOnly) return /* @__PURE__ */ jsx17(Fragment9, { children });
1250
+ if (!isReadOnly) return /* @__PURE__ */ jsx18(Fragment9, { children });
920
1251
  const block = (e) => {
921
1252
  if (e.key !== "Tab") e.stopPropagation();
922
1253
  };
923
- return /* @__PURE__ */ jsx17("div", { style: { display: "contents" }, onKeyDownCapture: block, children });
1254
+ return /* @__PURE__ */ jsx18("div", { style: { display: "contents" }, onKeyDownCapture: block, children });
924
1255
  }
925
1256
  function ClearButton({ enabled, onHasValue }) {
926
- const state = useContext9(SelectStateContext);
1257
+ const m = useMessages();
1258
+ const state = useContext10(SelectStateContext);
927
1259
  const hasValue = !!state && (Array.isArray(state.value) ? state.value.length > 0 : state.value != null);
928
1260
  useLayoutEffect2(() => onHasValue(hasValue), [hasValue, onHasValue]);
929
1261
  const ref = useRef4(null);
930
1262
  if (!enabled || !hasValue || !state) return null;
931
- return /* @__PURE__ */ jsx17("span", { className: "medo-select__clear", ref, children: /* @__PURE__ */ jsx17(
1263
+ return /* @__PURE__ */ jsx18("span", { className: "medo-select__clear", ref, children: /* @__PURE__ */ jsx18(
932
1264
  InputAction,
933
1265
  {
934
1266
  slot: null,
935
- "aria-label": Array.isArray(state.value) ? "Clear all" : "Clear selection",
936
- icon: /* @__PURE__ */ jsx17(X4, {}),
1267
+ "aria-label": Array.isArray(state.value) ? m.common.clearAll : m.select.clearSelection,
1268
+ icon: /* @__PURE__ */ jsx18(X4, {}),
937
1269
  onPress: () => {
938
1270
  state.setValue(Array.isArray(state.value) ? [] : null);
939
1271
  ref.current?.parentElement?.querySelector(".medo-select__trigger")?.focus();
@@ -942,7 +1274,7 @@ function ClearButton({ enabled, onHasValue }) {
942
1274
  ) });
943
1275
  }
944
1276
  function SelectedTags({ size }) {
945
- const state = useContext9(SelectStateContext);
1277
+ const state = useContext10(SelectStateContext);
946
1278
  const labels = state?.selectedItems.map((item) => item.textValue) ?? [];
947
1279
  const key = labels.join("\0");
948
1280
  const rowRef = useRef4(null);
@@ -951,15 +1283,15 @@ function SelectedTags({ size }) {
951
1283
  const tagClass = cx("medo-tag", size === "lg" ? "medo-tag--md" : "medo-tag--sm");
952
1284
  const hidden = labels.length - visible;
953
1285
  return /* @__PURE__ */ jsxs16("span", { className: "medo-select__tags", ref: rowRef, children: [
954
- /* @__PURE__ */ jsx17("span", { className: "medo-visually-hidden", children: labels.join(", ") }),
1286
+ /* @__PURE__ */ jsx18("span", { className: "medo-visually-hidden", children: labels.join(", ") }),
955
1287
  /* @__PURE__ */ jsxs16("span", { className: "medo-select__measure", ref: measureRef, "aria-hidden": "true", children: [
956
- labels.map((label, i) => /* @__PURE__ */ jsx17("span", { className: tagClass, children: label }, i)),
1288
+ labels.map((label, i) => /* @__PURE__ */ jsx18("span", { className: tagClass, children: label }, i)),
957
1289
  /* @__PURE__ */ jsxs16("span", { className: tagClass, children: [
958
1290
  "+",
959
1291
  labels.length
960
1292
  ] })
961
1293
  ] }),
962
- labels.slice(0, visible).map((label, i) => /* @__PURE__ */ jsx17("span", { className: tagClass, "aria-hidden": "true", children: /* @__PURE__ */ jsx17("span", { className: "medo-select__tag-label", children: label }) }, i)),
1294
+ labels.slice(0, visible).map((label, i) => /* @__PURE__ */ jsx18("span", { className: tagClass, "aria-hidden": "true", children: /* @__PURE__ */ jsx18("span", { className: "medo-select__tag-label", children: label }) }, i)),
963
1295
  hidden > 0 && /* @__PURE__ */ jsxs16("span", { className: tagClass, "aria-hidden": "true", children: [
964
1296
  "+",
965
1297
  hidden
@@ -967,14 +1299,14 @@ function SelectedTags({ size }) {
967
1299
  ] });
968
1300
  }
969
1301
  function NativePicker({ label, placeholder, isRequired }) {
970
- const state = useContext9(SelectStateContext);
1302
+ const state = useContext10(SelectStateContext);
971
1303
  if (!state) return null;
972
1304
  const keys = /* @__PURE__ */ new Map();
973
1305
  const option = (key) => {
974
1306
  const node = state.collection.getItem(key);
975
1307
  if (!node || node.type !== "item") return null;
976
1308
  keys.set(String(key), key);
977
- return /* @__PURE__ */ jsx17("option", { value: String(key), disabled: state.selectionManager.isDisabled(key), children: node.textValue }, String(key));
1309
+ return /* @__PURE__ */ jsx18("option", { value: String(key), disabled: state.selectionManager.isDisabled(key), children: node.textValue }, String(key));
978
1310
  };
979
1311
  const value = state.value == null || Array.isArray(state.value) ? "" : String(state.value);
980
1312
  return /* @__PURE__ */ jsxs16(
@@ -986,31 +1318,29 @@ function NativePicker({ label, placeholder, isRequired }) {
986
1318
  value,
987
1319
  onChange: (e) => state.setValue(e.target.value === "" ? null : keys.get(e.target.value) ?? e.target.value),
988
1320
  children: [
989
- /* @__PURE__ */ jsx17("option", { value: "", disabled: isRequired, children: placeholder }),
1321
+ /* @__PURE__ */ jsx18("option", { value: "", disabled: isRequired, children: placeholder }),
990
1322
  [...state.collection].map(
991
- (node) => node.type === "section" ? /* @__PURE__ */ jsx17("optgroup", { label: node.textValue || node["aria-label"] || "", children: [...state.collection.getChildren(node.key)].map((child) => option(child.key)) }, String(node.key)) : option(node.key)
1323
+ (node) => node.type === "section" ? /* @__PURE__ */ jsx18("optgroup", { label: node.textValue || node["aria-label"] || "", children: [...state.collection.getChildren(node.key)].map((child) => option(child.key)) }, String(node.key)) : option(node.key)
992
1324
  )
993
1325
  ]
994
1326
  }
995
1327
  );
996
1328
  }
997
1329
  function SheetFooter({ commit, resultLabel }) {
998
- const state = useContext9(SelectStateContext);
1330
+ const m = useMessages();
1331
+ const state = useContext10(SelectStateContext);
999
1332
  if (!state) return null;
1000
1333
  const count = Array.isArray(state.value) ? state.value.length : state.value == null ? 0 : 1;
1001
1334
  return commit === "onClose" ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
1002
- /* @__PURE__ */ jsx17(Button, { size: "lg", onPress: () => state.close(), children: resultLabel(state.value) }),
1003
- /* @__PURE__ */ jsx17(Button, { size: "lg", variant: "secondary", onPress: () => state.setValue([]), isDisabled: count === 0, children: "Reset" })
1335
+ /* @__PURE__ */ jsx18(Button, { size: "lg", onPress: () => state.close(), children: resultLabel(state.value) }),
1336
+ /* @__PURE__ */ jsx18(Button, { size: "lg", variant: "secondary", onPress: () => state.setValue([]), isDisabled: count === 0, children: m.common.reset })
1004
1337
  ] }) : /* @__PURE__ */ jsxs16(Fragment9, { children: [
1005
- /* @__PURE__ */ jsxs16("p", { className: "medo-sheet__count", "aria-live": "polite", children: [
1006
- count,
1007
- " selected"
1008
- ] }),
1009
- /* @__PURE__ */ jsx17(Button, { size: "lg", onPress: () => state.close(), children: "Done" })
1338
+ /* @__PURE__ */ jsx18("p", { className: "medo-sheet__count", "aria-live": "polite", children: m.common.countSelected(count) }),
1339
+ /* @__PURE__ */ jsx18(Button, { size: "lg", onPress: () => state.close(), children: m.common.done })
1010
1340
  ] });
1011
1341
  }
1012
1342
  function ApplyOnClose({ onApply }) {
1013
- const state = useContext9(SelectStateContext);
1343
+ const state = useContext10(SelectStateContext);
1014
1344
  const opened = useRef4(null);
1015
1345
  const isOpen = !!state?.isOpen;
1016
1346
  useEffect4(() => {
@@ -1026,7 +1356,7 @@ function ApplyOnClose({ onApply }) {
1026
1356
  }
1027
1357
 
1028
1358
  // src/menu/Menu.tsx
1029
- import { createContext as createContext6, useContext as useContext10, useState as useState6 } from "react";
1359
+ import { createContext as createContext7, useContext as useContext11, useState as useState6 } from "react";
1030
1360
  import {
1031
1361
  Header as Header2,
1032
1362
  Keyboard,
@@ -1039,52 +1369,53 @@ import {
1039
1369
  Text as Text7
1040
1370
  } from "react-aria-components";
1041
1371
  import { ChevronRight, Ellipsis } from "lucide-react";
1042
- import { Fragment as Fragment10, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
1372
+ import { Fragment as Fragment10, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
1043
1373
  import { createElement } from "react";
1044
- var MenuModeContext = createContext6({ size: "md" });
1374
+ var MenuModeContext = createContext7({ size: "md" });
1045
1375
  function MenuTrigger(props) {
1046
- return /* @__PURE__ */ jsx18(AriaMenuTrigger, { ...props });
1376
+ return /* @__PURE__ */ jsx19(AriaMenuTrigger, { ...props });
1047
1377
  }
1048
1378
  function MenuButton({ "aria-label": label, size = "md" }) {
1049
- return /* @__PURE__ */ jsx18(IconButton, { variant: "ghost", size, icon: /* @__PURE__ */ jsx18(Ellipsis, {}), "aria-label": label });
1379
+ return /* @__PURE__ */ jsx19(IconButton, { variant: "ghost", size, icon: /* @__PURE__ */ jsx19(Ellipsis, {}), "aria-label": label });
1050
1380
  }
1051
1381
  function Menu({ title, overlay = "auto", className, ...props }) {
1052
1382
  const mobile = useMediaQuery(MOBILE_QUERY);
1053
1383
  const sheet = overlay === "sheet" || overlay === "auto" && mobile;
1054
- if (sheet) return /* @__PURE__ */ jsx18(SheetMenu, { title, className, ...props });
1055
- return /* @__PURE__ */ jsx18(Popover3, { placement: "bottom end", offset: 4, className: "medo-menu-popover", children: /* @__PURE__ */ jsx18(MenuModeContext.Provider, { value: { size: "md" }, children: /* @__PURE__ */ jsx18(AriaMenu, { ...props, className: cx("medo-menu", "medo-menu--md", className) }) }) });
1384
+ if (sheet) return /* @__PURE__ */ jsx19(SheetMenu, { title, className, ...props });
1385
+ return /* @__PURE__ */ jsx19(Popover3, { placement: "bottom end", offset: 4, className: "medo-menu-popover", children: /* @__PURE__ */ jsx19(MenuModeContext.Provider, { value: { size: "md" }, children: /* @__PURE__ */ jsx19(AriaMenu, { ...props, className: cx("medo-menu", "medo-menu--md", className) }) }) });
1056
1386
  }
1057
1387
  function SheetMenu({ title, className, ...props }) {
1058
1388
  const [view, setView] = useState6(null);
1059
- return /* @__PURE__ */ jsx18(
1389
+ return /* @__PURE__ */ jsx19(
1060
1390
  BottomSheet,
1061
1391
  {
1062
1392
  title: view ? view.title : title ?? props["aria-label"],
1063
1393
  onBack: view ? () => setView(null) : void 0,
1064
1394
  onOpenChange: (open) => !open && setView(null),
1065
- children: /* @__PURE__ */ jsx18(MenuModeContext.Provider, { value: { size: "lg", push: (t, c) => setView({ title: t, children: c }) }, children: view ? /* @__PURE__ */ jsx18(AriaMenu, { "aria-label": typeof view.title === "string" ? view.title : void 0, autoFocus: "first", className: cx("medo-menu", "medo-menu--lg", className), children: view.children }, "sub") : /* @__PURE__ */ createElement(AriaMenu, { ...props, key: "main", className: cx("medo-menu", "medo-menu--lg", className) }) })
1395
+ children: /* @__PURE__ */ jsx19(MenuModeContext.Provider, { value: { size: "lg", push: (t, c) => setView({ title: t, children: c }) }, children: view ? /* @__PURE__ */ jsx19(AriaMenu, { "aria-label": typeof view.title === "string" ? view.title : void 0, autoFocus: "first", className: cx("medo-menu", "medo-menu--lg", className), children: view.children }, "sub") : /* @__PURE__ */ createElement(AriaMenu, { ...props, key: "main", className: cx("medo-menu", "medo-menu--lg", className) }) })
1066
1396
  }
1067
1397
  );
1068
1398
  }
1069
1399
  function MenuItem({ children, icon, shortcut, variant = "default", textValue, ...props }) {
1070
- const { size } = useContext10(MenuModeContext);
1071
- return /* @__PURE__ */ jsx18(
1400
+ const m = useMessages();
1401
+ const { size } = useContext11(MenuModeContext);
1402
+ return /* @__PURE__ */ jsx19(
1072
1403
  AriaMenuItem,
1073
1404
  {
1074
1405
  ...props,
1075
1406
  textValue: textValue ?? children,
1076
1407
  className: cx("medo-menu-item", variant === "danger" && "medo-menu-item--danger"),
1077
1408
  children: ({ hasSubmenu }) => /* @__PURE__ */ jsxs17(Fragment10, { children: [
1078
- /* @__PURE__ */ jsx18("span", { className: "medo-menu-item__icon", "aria-hidden": "true", children: icon }),
1079
- /* @__PURE__ */ jsx18(Text7, { slot: "label", className: "medo-menu-item__label", children }),
1080
- shortcut && size === "md" && /* @__PURE__ */ jsx18(Keyboard, { className: "medo-menu-item__shortcut", children: formatShortcut(shortcut) }),
1081
- hasSubmenu && /* @__PURE__ */ jsx18("span", { className: "medo-menu-item__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx18(ChevronRight, {}) })
1409
+ /* @__PURE__ */ jsx19("span", { className: "medo-menu-item__icon", "aria-hidden": "true", children: icon }),
1410
+ /* @__PURE__ */ jsx19(Text7, { slot: "label", className: "medo-menu-item__label", children }),
1411
+ shortcut && size === "md" && /* @__PURE__ */ jsx19(Keyboard, { className: "medo-menu-item__shortcut", children: formatShortcut(shortcut, m.keys.control) }),
1412
+ hasSubmenu && /* @__PURE__ */ jsx19("span", { className: "medo-menu-item__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(ChevronRight, {}) })
1082
1413
  ] })
1083
1414
  }
1084
1415
  );
1085
1416
  }
1086
1417
  function Submenu({ label, icon, children, isDisabled }) {
1087
- const { size, push } = useContext10(MenuModeContext);
1418
+ const { size, push } = useContext11(MenuModeContext);
1088
1419
  if (push) {
1089
1420
  return /* @__PURE__ */ jsxs17(
1090
1421
  AriaMenuItem,
@@ -1095,33 +1426,33 @@ function Submenu({ label, icon, children, isDisabled }) {
1095
1426
  onAction: () => push(label, children),
1096
1427
  className: "medo-menu-item",
1097
1428
  children: [
1098
- /* @__PURE__ */ jsx18("span", { className: "medo-menu-item__icon", "aria-hidden": "true", children: icon }),
1099
- /* @__PURE__ */ jsx18(Text7, { slot: "label", className: "medo-menu-item__label", children: label }),
1100
- /* @__PURE__ */ jsx18("span", { className: "medo-menu-item__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx18(ChevronRight, {}) })
1429
+ /* @__PURE__ */ jsx19("span", { className: "medo-menu-item__icon", "aria-hidden": "true", children: icon }),
1430
+ /* @__PURE__ */ jsx19(Text7, { slot: "label", className: "medo-menu-item__label", children: label }),
1431
+ /* @__PURE__ */ jsx19("span", { className: "medo-menu-item__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(ChevronRight, {}) })
1101
1432
  ]
1102
1433
  }
1103
1434
  );
1104
1435
  }
1105
1436
  return /* @__PURE__ */ jsxs17(SubmenuTrigger, { children: [
1106
- /* @__PURE__ */ jsx18(MenuItem, { icon, isDisabled, children: label }),
1107
- /* @__PURE__ */ jsx18(Popover3, { placement: "end top", offset: 4, crossOffset: -5, className: "medo-menu-popover", children: /* @__PURE__ */ jsx18(AriaMenu, { "aria-label": label, className: cx("medo-menu", `medo-menu--${size}`), children }) })
1437
+ /* @__PURE__ */ jsx19(MenuItem, { icon, isDisabled, children: label }),
1438
+ /* @__PURE__ */ jsx19(Popover3, { placement: "end top", offset: 4, crossOffset: -5, className: "medo-menu-popover", children: /* @__PURE__ */ jsx19(AriaMenu, { "aria-label": label, className: cx("medo-menu", `medo-menu--${size}`), children }) })
1108
1439
  ] });
1109
1440
  }
1110
1441
  function MenuSection({ title, children, ...props }) {
1111
1442
  return /* @__PURE__ */ jsxs17(AriaMenuSection, { "aria-label": props["aria-label"], className: "medo-menu__section", children: [
1112
- title && /* @__PURE__ */ jsx18(Header2, { className: "medo-listbox__header", children: title }),
1443
+ title && /* @__PURE__ */ jsx19(Header2, { className: "medo-listbox__header", children: title }),
1113
1444
  children
1114
1445
  ] });
1115
1446
  }
1116
1447
 
1117
1448
  // src/dialog/Dialog.tsx
1118
- import { useContext as useContext11, useEffect as useEffect5, useId as useId3, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState7 } from "react";
1449
+ import { useContext as useContext12, useEffect as useEffect5, useId as useId3, useLayoutEffect as useLayoutEffect3, useRef as useRef5, useState as useState7 } from "react";
1119
1450
  import { Dialog as AriaDialog, DialogContext, Heading as Heading2, Modal as Modal2, ModalOverlay as ModalOverlay2, OverlayTriggerStateContext as OverlayTriggerStateContext2, Provider } from "react-aria-components";
1120
1451
  import { CircleAlert as CircleAlert2, Info, TriangleAlert, X as X5 } from "lucide-react";
1121
1452
  import { DialogTrigger } from "react-aria-components";
1122
- import { Fragment as Fragment11, jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
1453
+ import { Fragment as Fragment11, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
1123
1454
  function useOpenState({ isOpen, onOpenChange }) {
1124
- const trigger = useContext11(OverlayTriggerStateContext2);
1455
+ const trigger = useContext12(OverlayTriggerStateContext2);
1125
1456
  const open = isOpen ?? trigger?.isOpen ?? false;
1126
1457
  const setOpen = (next) => {
1127
1458
  onOpenChange?.(next);
@@ -1142,7 +1473,7 @@ function ActionButton({ action, close, size, variant }) {
1142
1473
  setPending(false);
1143
1474
  }
1144
1475
  };
1145
- return /* @__PURE__ */ jsx19(
1476
+ return /* @__PURE__ */ jsx20(
1146
1477
  Button,
1147
1478
  {
1148
1479
  variant: action.variant ?? variant,
@@ -1157,7 +1488,7 @@ function ActionButton({ action, close, size, variant }) {
1157
1488
  );
1158
1489
  }
1159
1490
  function Nested({ children }) {
1160
- return /* @__PURE__ */ jsx19(
1491
+ return /* @__PURE__ */ jsx20(
1161
1492
  Provider,
1162
1493
  {
1163
1494
  values: [
@@ -1175,8 +1506,15 @@ function useDirtyGuard({ isDirty = false, discardText, ...openProps }) {
1175
1506
  if (next || !isDirty) setOpen(next);
1176
1507
  else setConfirm(true);
1177
1508
  };
1178
- const discard = { ...DISCARD, ...discardText };
1179
- const confirmDiscard = /* @__PURE__ */ jsx19(Nested, { children: /* @__PURE__ */ jsx19(
1509
+ const m = useMessages();
1510
+ const discard = {
1511
+ title: m.dialog.discardTitle,
1512
+ description: m.dialog.discardDescription,
1513
+ actionLabel: m.dialog.discardAction,
1514
+ cancelLabel: m.dialog.discardCancel,
1515
+ ...discardText
1516
+ };
1517
+ const confirmDiscard = /* @__PURE__ */ jsx20(Nested, { children: /* @__PURE__ */ jsx20(
1180
1518
  AlertDialog,
1181
1519
  {
1182
1520
  tone: "warning",
@@ -1192,20 +1530,14 @@ function useDirtyGuard({ isDirty = false, discardText, ...openProps }) {
1192
1530
  const forceClose = () => setOpen(false);
1193
1531
  return { open, onOpenChange, confirmDiscard, forceClose };
1194
1532
  }
1195
- var DISCARD = {
1196
- title: "Discard changes?",
1197
- description: "Your changes will be lost.",
1198
- actionLabel: "Discard",
1199
- cancelLabel: "Keep editing"
1200
- };
1201
1533
  function Dialog2({
1202
1534
  title,
1203
1535
  description,
1204
1536
  children,
1205
1537
  size = "md",
1206
1538
  primaryAction,
1207
- cancelLabel = "Cancel",
1208
- closeLabel = "Close",
1539
+ cancelLabel: cancelLabelProp,
1540
+ closeLabel: closeLabelProp,
1209
1541
  showClose = true,
1210
1542
  isDirty = false,
1211
1543
  discardText,
@@ -1214,6 +1546,9 @@ function Dialog2({
1214
1546
  className,
1215
1547
  ...openProps
1216
1548
  }) {
1549
+ const m = useMessages();
1550
+ const cancelLabel = cancelLabelProp ?? m.common.cancel;
1551
+ const closeLabel = closeLabelProp ?? m.common.close;
1217
1552
  const { open, onOpenChange, confirmDiscard, forceClose } = useDirtyGuard({ isDirty, discardText, ...openProps });
1218
1553
  const isMobile = useMediaQuery(MOBILE_QUERY);
1219
1554
  const layout = overlay === "auto" ? isMobile ? mobile : "dialog" : overlay;
@@ -1229,25 +1564,25 @@ function Dialog2({
1229
1564
  isDismissable: !isDirty,
1230
1565
  className,
1231
1566
  footer: primaryAction && ((close) => /* @__PURE__ */ jsxs18(ButtonGroup, { children: [
1232
- /* @__PURE__ */ jsx19(Button, { variant: "secondary", size: "lg", onPress: close, children: cancelLabel }),
1233
- /* @__PURE__ */ jsx19(ActionButton, { action: primaryAction, close: forceClose, size: "lg", variant: "primary" })
1567
+ /* @__PURE__ */ jsx20(Button, { variant: "secondary", size: "lg", onPress: close, children: cancelLabel }),
1568
+ /* @__PURE__ */ jsx20(ActionButton, { action: primaryAction, close: forceClose, size: "lg", variant: "primary" })
1234
1569
  ] })),
1235
1570
  children: [
1236
- /* @__PURE__ */ jsx19(SheetContent, { description, children: content(forceClose) }),
1571
+ /* @__PURE__ */ jsx20(SheetContent, { description, children: content(forceClose) }),
1237
1572
  confirmDiscard
1238
1573
  ]
1239
1574
  }
1240
1575
  );
1241
1576
  }
1242
1577
  const fullscreen = layout === "fullscreen";
1243
- return /* @__PURE__ */ jsx19(
1578
+ return /* @__PURE__ */ jsx20(
1244
1579
  ModalOverlay2,
1245
1580
  {
1246
1581
  isOpen: open,
1247
1582
  onOpenChange,
1248
1583
  isDismissable: !isDirty,
1249
1584
  className: cx("medo-dialog-overlay", fullscreen && "medo-dialog-overlay--fullscreen"),
1250
- children: /* @__PURE__ */ jsx19(Modal2, { className: cx("medo-dialog", fullscreen ? "medo-dialog--fullscreen" : `medo-dialog--${size}`, className), children: /* @__PURE__ */ jsx19(
1585
+ children: /* @__PURE__ */ jsx20(Modal2, { className: cx("medo-dialog", fullscreen ? "medo-dialog--fullscreen" : `medo-dialog--${size}`, className), children: /* @__PURE__ */ jsx20(
1251
1586
  DialogFrame,
1252
1587
  {
1253
1588
  title,
@@ -1270,29 +1605,29 @@ function DialogFrame({ title, description, fullscreen, primaryAction, cancelLabe
1270
1605
  const ref = useRef5(null);
1271
1606
  const [scrolls, setScrolls] = useState7(false);
1272
1607
  useInitialFocus(ref);
1273
- return /* @__PURE__ */ jsx19(AriaDialog, { ref, className: "medo-dialog__dialog", "aria-describedby": description ? descriptionId : void 0, "data-scrolled": scrolls || void 0, children: ({ close }) => fullscreen ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
1608
+ return /* @__PURE__ */ jsx20(AriaDialog, { ref, className: "medo-dialog__dialog", "aria-describedby": description ? descriptionId : void 0, "data-scrolled": scrolls || void 0, children: ({ close }) => fullscreen ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
1274
1609
  /* @__PURE__ */ jsxs18("div", { className: "medo-dialog__bar", children: [
1275
- /* @__PURE__ */ jsx19(Button, { variant: "ghost", size: "md", onPress: close, children: primaryAction ? cancelLabel : closeLabel }),
1276
- /* @__PURE__ */ jsx19(Heading2, { slot: "title", className: "medo-dialog__bar-title", children: title }),
1277
- primaryAction ? /* @__PURE__ */ jsx19(ActionButton, { action: primaryAction, close: forceClose, size: "md", variant: "primary" }) : /* @__PURE__ */ jsx19("span", {})
1610
+ /* @__PURE__ */ jsx20(Button, { variant: "ghost", size: "md", onPress: close, children: primaryAction ? cancelLabel : closeLabel }),
1611
+ /* @__PURE__ */ jsx20(Heading2, { slot: "title", className: "medo-dialog__bar-title", children: title }),
1612
+ primaryAction ? /* @__PURE__ */ jsx20(ActionButton, { action: primaryAction, close: forceClose, size: "md", variant: "primary" }) : /* @__PURE__ */ jsx20("span", {})
1278
1613
  ] }),
1279
1614
  /* @__PURE__ */ jsxs18(DialogBody, { onScrollsChange: setScrolls, children: [
1280
- description && /* @__PURE__ */ jsx19("p", { id: descriptionId, className: "medo-dialog__description", children: description }),
1615
+ description && /* @__PURE__ */ jsx20("p", { id: descriptionId, className: "medo-dialog__description", children: description }),
1281
1616
  children(forceClose)
1282
1617
  ] }),
1283
1618
  nested
1284
1619
  ] }) : /* @__PURE__ */ jsxs18(Fragment11, { children: [
1285
1620
  /* @__PURE__ */ jsxs18("div", { className: "medo-dialog__header", children: [
1286
1621
  /* @__PURE__ */ jsxs18("div", { className: "medo-dialog__heading", children: [
1287
- /* @__PURE__ */ jsx19(Heading2, { slot: "title", className: "medo-dialog__title", children: title }),
1288
- description && /* @__PURE__ */ jsx19("p", { id: descriptionId, className: "medo-dialog__description", children: description })
1622
+ /* @__PURE__ */ jsx20(Heading2, { slot: "title", className: "medo-dialog__title", children: title }),
1623
+ description && /* @__PURE__ */ jsx20("p", { id: descriptionId, className: "medo-dialog__description", children: description })
1289
1624
  ] }),
1290
- showClose && /* @__PURE__ */ jsx19(IconButton, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx19(X5, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
1625
+ showClose && /* @__PURE__ */ jsx20(IconButton, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx20(X5, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
1291
1626
  ] }),
1292
- /* @__PURE__ */ jsx19(DialogBody, { onScrollsChange: setScrolls, children: children(forceClose) }),
1293
- primaryAction && /* @__PURE__ */ jsx19("div", { className: "medo-dialog__footer", children: /* @__PURE__ */ jsxs18(ButtonGroup, { children: [
1294
- /* @__PURE__ */ jsx19(Button, { variant: "secondary", onPress: close, children: cancelLabel }),
1295
- /* @__PURE__ */ jsx19(ActionButton, { action: primaryAction, close: forceClose, size: "md", variant: "primary" })
1627
+ /* @__PURE__ */ jsx20(DialogBody, { onScrollsChange: setScrolls, children: children(forceClose) }),
1628
+ primaryAction && /* @__PURE__ */ jsx20("div", { className: "medo-dialog__footer", children: /* @__PURE__ */ jsxs18(ButtonGroup, { children: [
1629
+ /* @__PURE__ */ jsx20(Button, { variant: "secondary", onPress: close, children: cancelLabel }),
1630
+ /* @__PURE__ */ jsx20(ActionButton, { action: primaryAction, close: forceClose, size: "md", variant: "primary" })
1296
1631
  ] }) }),
1297
1632
  nested
1298
1633
  ] }) });
@@ -1311,11 +1646,11 @@ function DialogBody({ children, onScrollsChange }) {
1311
1646
  return () => observer.disconnect();
1312
1647
  }, []);
1313
1648
  useEffect5(() => onScrollsChange(scrolls), [scrolls, onScrollsChange]);
1314
- return /* @__PURE__ */ jsx19("div", { ref, className: "medo-dialog__body", tabIndex: scrolls ? 0 : void 0, children: /* @__PURE__ */ jsx19("div", { className: "medo-dialog__body-inner", children }) });
1649
+ return /* @__PURE__ */ jsx20("div", { ref, className: "medo-dialog__body", tabIndex: scrolls ? 0 : void 0, children: /* @__PURE__ */ jsx20("div", { className: "medo-dialog__body-inner", children }) });
1315
1650
  }
1316
1651
  function SheetContent({ description, children }) {
1317
1652
  return /* @__PURE__ */ jsxs18("div", { className: "medo-dialog__sheet-body", children: [
1318
- description && /* @__PURE__ */ jsx19("p", { className: "medo-dialog__description", children: description }),
1653
+ description && /* @__PURE__ */ jsx20("p", { className: "medo-dialog__description", children: description }),
1319
1654
  children
1320
1655
  ] });
1321
1656
  }
@@ -1334,29 +1669,31 @@ var TONE_ICONS = {
1334
1669
  warning: TriangleAlert,
1335
1670
  info: Info
1336
1671
  };
1337
- function AlertDialog({ tone = "danger", title, children, actionLabel, onAction, cancelLabel = "Cancel", className, ...openProps }) {
1672
+ function AlertDialog({ tone = "danger", title, children, actionLabel, onAction, cancelLabel: cancelLabelProp, className, ...openProps }) {
1673
+ const m = useMessages();
1674
+ const cancelLabel = cancelLabelProp ?? m.common.cancel;
1338
1675
  const [open, setOpen] = useOpenState(openProps);
1339
1676
  const isMobile = useMediaQuery(MOBILE_QUERY);
1340
1677
  const descriptionId = useId3();
1341
1678
  const Icon = TONE_ICONS[tone];
1342
1679
  const size = isMobile ? "lg" : "md";
1343
- return /* @__PURE__ */ jsx19(ModalOverlay2, { isOpen: open, onOpenChange: setOpen, isDismissable: false, className: "medo-dialog-overlay", children: /* @__PURE__ */ jsx19(Modal2, { className: cx("medo-dialog", "medo-alert-dialog", `medo-alert-dialog--${tone}`, className), children: /* @__PURE__ */ jsx19(AriaDialog, { role: "alertdialog", "aria-describedby": children ? descriptionId : void 0, className: "medo-dialog__dialog", children: ({ close }) => /* @__PURE__ */ jsxs18(Fragment11, { children: [
1680
+ return /* @__PURE__ */ jsx20(ModalOverlay2, { isOpen: open, onOpenChange: setOpen, isDismissable: false, className: "medo-dialog-overlay", children: /* @__PURE__ */ jsx20(Modal2, { className: cx("medo-dialog", "medo-alert-dialog", `medo-alert-dialog--${tone}`, className), children: /* @__PURE__ */ jsx20(AriaDialog, { role: "alertdialog", "aria-describedby": children ? descriptionId : void 0, className: "medo-dialog__dialog", children: ({ close }) => /* @__PURE__ */ jsxs18(Fragment11, { children: [
1344
1681
  /* @__PURE__ */ jsxs18("div", { className: "medo-alert-dialog__content", children: [
1345
- /* @__PURE__ */ jsx19("span", { className: "medo-alert-dialog__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx19(Icon, {}) }),
1682
+ /* @__PURE__ */ jsx20("span", { className: "medo-alert-dialog__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(Icon, {}) }),
1346
1683
  /* @__PURE__ */ jsxs18("div", { className: "medo-alert-dialog__text", children: [
1347
- /* @__PURE__ */ jsx19(Heading2, { slot: "title", className: "medo-alert-dialog__title", children: title }),
1348
- children && /* @__PURE__ */ jsx19("div", { id: descriptionId, className: "medo-alert-dialog__description", children })
1684
+ /* @__PURE__ */ jsx20(Heading2, { slot: "title", className: "medo-alert-dialog__title", children: title }),
1685
+ children && /* @__PURE__ */ jsx20("div", { id: descriptionId, className: "medo-alert-dialog__description", children })
1349
1686
  ] })
1350
1687
  ] }),
1351
1688
  /* @__PURE__ */ jsxs18(ButtonGroup, { children: [
1352
- /* @__PURE__ */ jsx19(Button, { variant: "secondary", size, autoFocus: true, onPress: close, children: cancelLabel }),
1353
- /* @__PURE__ */ jsx19(ActionButton, { action: { label: actionLabel, onAction }, close, size, variant: tone === "danger" ? "danger" : "primary" })
1689
+ /* @__PURE__ */ jsx20(Button, { variant: "secondary", size, autoFocus: true, onPress: close, children: cancelLabel }),
1690
+ /* @__PURE__ */ jsx20(ActionButton, { action: { label: actionLabel, onAction }, close, size, variant: tone === "danger" ? "danger" : "primary" })
1354
1691
  ] })
1355
1692
  ] }) }) }) });
1356
1693
  }
1357
1694
 
1358
1695
  // src/combobox/Combobox.tsx
1359
- import { useContext as useContext12, useEffect as useEffect6, useId as useId4, useRef as useRef6, useState as useState8 } from "react";
1696
+ import { useContext as useContext13, useEffect as useEffect6, useId as useId4, useRef as useRef6, useState as useState8 } from "react";
1360
1697
  import {
1361
1698
  Autocomplete,
1362
1699
  Button as AriaButton7,
@@ -1371,23 +1708,23 @@ import {
1371
1708
  useFilter
1372
1709
  } from "react-aria-components";
1373
1710
  import { ChevronDown as ChevronDown2, CircleAlert as CircleAlert3, Plus, Search, X as X6 } from "lucide-react";
1374
- import { Fragment as Fragment12, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
1711
+ import { Fragment as Fragment12, jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
1375
1712
  var CREATE_KEY = "__medo_create__";
1376
1713
  function Combobox({
1377
1714
  label,
1378
1715
  description,
1379
1716
  errorMessage,
1380
- placeholder = "Search\u2026",
1717
+ placeholder: placeholderProp,
1381
1718
  size = "md",
1382
1719
  leadingIcon,
1383
1720
  isLoading,
1384
- noResultsMessage = (text) => text ? `No results for \u201E${text}\u201C` : "No results",
1721
+ noResultsMessage: noResultsProp,
1385
1722
  onCreate,
1386
1723
  children,
1387
1724
  overlay = "auto",
1388
1725
  commit = "live",
1389
1726
  onApply,
1390
- resultLabel = () => "Show results",
1727
+ resultLabel: resultLabelProp,
1391
1728
  className,
1392
1729
  selectionMode,
1393
1730
  value: valueProp,
@@ -1396,6 +1733,10 @@ function Combobox({
1396
1733
  onInputChange,
1397
1734
  ...props
1398
1735
  }) {
1736
+ const m = useMessages();
1737
+ const placeholder = placeholderProp ?? m.combobox.placeholder;
1738
+ const noResultsMessage = noResultsProp ?? ((text2) => text2 ? m.common.noResultsFor(text2) : m.common.noResults);
1739
+ const resultLabel = resultLabelProp ?? (() => m.common.showResults);
1399
1740
  const multiple = selectionMode === "multiple";
1400
1741
  const groupRef = useRef6(null);
1401
1742
  const inputRef = useRef6(null);
@@ -1421,7 +1762,7 @@ function Combobox({
1421
1762
  };
1422
1763
  const mobile = useMediaQuery(MOBILE_QUERY);
1423
1764
  if (overlay === "sheet" || overlay === "auto" && mobile) {
1424
- return /* @__PURE__ */ jsx20(
1765
+ return /* @__PURE__ */ jsx21(
1425
1766
  ComboboxSheet,
1426
1767
  {
1427
1768
  ...{
@@ -1478,22 +1819,22 @@ function Combobox({
1478
1819
  allowsEmptyCollection: true,
1479
1820
  className: cx("medo-field", "medo-combobox", className),
1480
1821
  children: [
1481
- /* @__PURE__ */ jsx20(FieldLabel, { isRequired: props.isRequired, children: label }),
1822
+ /* @__PURE__ */ jsx21(FieldLabel, { isRequired: props.isRequired, children: label }),
1482
1823
  /* @__PURE__ */ jsxs19(Group, { ref: groupRef, className: cx("medo-input", `medo-input--${size}`, "medo-combobox__field"), onMouseDown: focusInput, children: [
1483
- leadingIcon && /* @__PURE__ */ jsx20("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
1824
+ leadingIcon && /* @__PURE__ */ jsx21("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
1484
1825
  multiple ? (
1485
1826
  /* Tags and input share one line; the tags get what is left after 4 rem for typing. */
1486
1827
  /* @__PURE__ */ jsxs19("span", { className: "medo-combobox__entry", ref: entryRef, children: [
1487
- /* @__PURE__ */ jsx20(SelectedTags2, { entryRef, size, label, isDisabled: props.isDisabled, isReadOnly: props.isReadOnly }),
1488
- /* @__PURE__ */ jsx20(ComboInput, { ref: inputRef, placeholder, multiple: true, onRemoved: setAnnouncement })
1828
+ /* @__PURE__ */ jsx21(SelectedTags2, { entryRef, size, label, isDisabled: props.isDisabled, isReadOnly: props.isReadOnly }),
1829
+ /* @__PURE__ */ jsx21(ComboInput, { ref: inputRef, placeholder, multiple: true, onRemoved: setAnnouncement })
1489
1830
  ] })
1490
- ) : /* @__PURE__ */ jsx20(ComboInput, { ref: inputRef, placeholder, multiple: false, onRemoved: setAnnouncement }),
1491
- /* @__PURE__ */ jsx20(ClearButton2, { inputRef, isDisabled: props.isDisabled || props.isReadOnly }),
1492
- !props.isReadOnly && /* @__PURE__ */ jsx20(AriaButton7, { className: "medo-input__action medo-combobox__toggle", children: /* @__PURE__ */ jsx20(ChevronDown2, { "aria-hidden": "true" }) })
1831
+ ) : /* @__PURE__ */ jsx21(ComboInput, { ref: inputRef, placeholder, multiple: false, onRemoved: setAnnouncement }),
1832
+ /* @__PURE__ */ jsx21(ClearButton2, { inputRef, isDisabled: props.isDisabled || props.isReadOnly }),
1833
+ !props.isReadOnly && /* @__PURE__ */ jsx21(AriaButton7, { className: "medo-input__action medo-combobox__toggle", children: /* @__PURE__ */ jsx21(ChevronDown2, { "aria-hidden": "true" }) })
1493
1834
  ] }),
1494
- /* @__PURE__ */ jsx20(FieldFooter, { description, errorMessage }),
1495
- /* @__PURE__ */ jsx20("span", { className: "medo-visually-hidden", "aria-live": "polite", children: announcement }),
1496
- /* @__PURE__ */ jsx20(Popover4, { offset: 4, className: "medo-listbox-popover", children: /* @__PURE__ */ jsx20(
1835
+ /* @__PURE__ */ jsx21(FieldFooter, { description, errorMessage }),
1836
+ /* @__PURE__ */ jsx21("span", { className: "medo-visually-hidden", "aria-live": "polite", children: announcement }),
1837
+ /* @__PURE__ */ jsx21(Popover4, { offset: 4, className: "medo-listbox-popover", children: /* @__PURE__ */ jsx21(
1497
1838
  ComboList,
1498
1839
  {
1499
1840
  size,
@@ -1517,15 +1858,16 @@ function ComboInput({
1517
1858
  multiple,
1518
1859
  onRemoved
1519
1860
  }) {
1520
- const state = useContext12(ComboBoxStateContext2);
1861
+ const m = useMessages();
1862
+ const state = useContext13(ComboBoxStateContext2);
1521
1863
  const values = Array.isArray(state?.value) ? state.value : [];
1522
1864
  const onKeyDown = (e) => {
1523
1865
  if (!multiple || !state || e.key !== "Backspace" || state.inputValue !== "" || values.length === 0) return;
1524
1866
  const last = state.selectedItems.at(-1);
1525
1867
  state.setValue(values.slice(0, -1));
1526
- if (last) onRemoved(`${last.textValue} removed`);
1868
+ if (last) onRemoved(m.common.removed([last.textValue]));
1527
1869
  };
1528
- return /* @__PURE__ */ jsx20(
1870
+ return /* @__PURE__ */ jsx21(
1529
1871
  Input,
1530
1872
  {
1531
1873
  ref,
@@ -1536,17 +1878,18 @@ function ComboInput({
1536
1878
  );
1537
1879
  }
1538
1880
  function ClearButton2({ inputRef, isDisabled }) {
1539
- const state = useContext12(ComboBoxStateContext2);
1881
+ const m = useMessages();
1882
+ const state = useContext13(ComboBoxStateContext2);
1540
1883
  if (!state || isDisabled) return null;
1541
1884
  const hasValue = Array.isArray(state.value) ? state.value.length > 0 : state.value != null;
1542
1885
  if (!hasValue && !state.inputValue) return null;
1543
- return /* @__PURE__ */ jsx20(
1886
+ return /* @__PURE__ */ jsx21(
1544
1887
  InputAction,
1545
1888
  {
1546
1889
  slot: null,
1547
1890
  excludeFromTabOrder: true,
1548
- "aria-label": Array.isArray(state.value) ? "Clear all" : "Clear",
1549
- icon: /* @__PURE__ */ jsx20(X6, {}),
1891
+ "aria-label": Array.isArray(state.value) ? m.common.clearAll : m.common.clear,
1892
+ icon: /* @__PURE__ */ jsx21(X6, {}),
1550
1893
  onPress: () => {
1551
1894
  state.setValue(Array.isArray(state.value) ? [] : null);
1552
1895
  state.setInputValue("");
@@ -1562,7 +1905,8 @@ function SelectedTags2({
1562
1905
  isDisabled,
1563
1906
  isReadOnly
1564
1907
  }) {
1565
- const state = useContext12(ComboBoxStateContext2);
1908
+ const m = useMessages();
1909
+ const state = useContext13(ComboBoxStateContext2);
1566
1910
  const items = (state?.selectedItems ?? []).filter(Boolean);
1567
1911
  const values = Array.isArray(state?.value) ? state.value : [];
1568
1912
  const key = items.map((item) => item.key).join("\0");
@@ -1571,34 +1915,34 @@ function SelectedTags2({
1571
1915
  if (!state || items.length === 0) return null;
1572
1916
  const tagSize = size === "lg" ? "md" : "sm";
1573
1917
  const hidden = items.length - visible;
1574
- const name = typeof label === "string" ? label : "Selected";
1918
+ const name = typeof label === "string" ? label : m.common.selectedValues;
1575
1919
  return /* @__PURE__ */ jsxs19("span", { className: "medo-combobox__tags-row", children: [
1576
1920
  /* @__PURE__ */ jsxs19("span", { className: cx("medo-combobox__measure"), ref: measureRef, "aria-hidden": "true", children: [
1577
1921
  items.map((item) => /* @__PURE__ */ jsxs19("span", { className: cx("medo-tag", `medo-tag--${tagSize}`), "data-allows-removing": "", children: [
1578
- /* @__PURE__ */ jsx20("span", { className: "medo-tag__label", children: item.textValue }),
1579
- /* @__PURE__ */ jsx20("span", { className: "medo-tag__remove" })
1922
+ /* @__PURE__ */ jsx21("span", { className: "medo-tag__label", children: item.textValue }),
1923
+ /* @__PURE__ */ jsx21("span", { className: "medo-tag__remove" })
1580
1924
  ] }, item.key)),
1581
1925
  /* @__PURE__ */ jsxs19("span", { className: cx("medo-tag", `medo-tag--${tagSize}`), children: [
1582
1926
  "+",
1583
1927
  items.length
1584
1928
  ] })
1585
1929
  ] }),
1586
- /* @__PURE__ */ jsx20(
1930
+ /* @__PURE__ */ jsx21(
1587
1931
  TagGroup,
1588
1932
  {
1589
- "aria-label": `${name}: selected`,
1933
+ "aria-label": m.common.selected(name),
1590
1934
  size: tagSize,
1591
1935
  className: "medo-combobox__tags",
1592
1936
  items: items.slice(0, visible),
1593
1937
  disabledKeys: isDisabled ? items.map((item) => item.key) : void 0,
1594
1938
  onRemove: isReadOnly ? void 0 : (keys) => state.setValue(values.filter((k) => !keys.has(k))),
1595
- children: (item) => /* @__PURE__ */ jsx20(Tag, { id: item.key, children: item.textValue })
1939
+ children: (item) => /* @__PURE__ */ jsx21(Tag, { id: item.key, children: item.textValue })
1596
1940
  }
1597
1941
  ),
1598
1942
  hidden > 0 && /* @__PURE__ */ jsxs19("span", { className: cx("medo-tag", `medo-tag--${tagSize}`, "medo-combobox__more"), children: [
1599
1943
  "+",
1600
1944
  hidden,
1601
- /* @__PURE__ */ jsx20("span", { className: "medo-visually-hidden", children: " more selected" })
1945
+ /* @__PURE__ */ jsx21("span", { className: "medo-visually-hidden", children: " more selected" })
1602
1946
  ] })
1603
1947
  ] });
1604
1948
  }
@@ -1613,7 +1957,8 @@ function ComboList({
1613
1957
  onExactChange,
1614
1958
  children
1615
1959
  }) {
1616
- const state = useContext12(ComboBoxStateContext2);
1960
+ const m = useMessages();
1961
+ const state = useContext13(ComboBoxStateContext2);
1617
1962
  const nodes = state ? [...state.collection].filter((node) => node.key !== CREATE_KEY) : [];
1618
1963
  const hasItems = nodes.length > 0;
1619
1964
  const exactNow = nodes.some((node) => node.textValue.toLocaleLowerCase() === text.toLocaleLowerCase());
@@ -1642,14 +1987,17 @@ function ComboList({
1642
1987
  ListBox,
1643
1988
  {
1644
1989
  size: size === "lg" ? "lg" : "md",
1645
- renderEmptyState: () => /* @__PURE__ */ jsx20(ListBoxMessage, { children: isLoading ? "Loading\u2026" : noResultsMessage(text) }),
1990
+ renderEmptyState: () => /* @__PURE__ */ jsx21(ListBoxMessage, { children: isLoading ? `${m.common.loading}\u2026` : noResultsMessage(text) }),
1646
1991
  children: [
1647
- typeof children === "function" ? /* @__PURE__ */ jsx20(Collection2, { items, children }) : children,
1648
- creatable && text && !exact && /* @__PURE__ */ jsx20(ListBoxSection, { "aria-label": "Create", children: /* @__PURE__ */ jsx20(Option, { id: CREATE_KEY, icon: /* @__PURE__ */ jsx20(Plus, {}), textValue: text, children: `Add \u201E${text}\u201C` }) })
1992
+ typeof children === "function" ? /* @__PURE__ */ jsx21(Collection2, { items, children }) : children,
1993
+ creatable && text && !exact && /* @__PURE__ */ jsx21(ListBoxSection, { "aria-label": m.common.create, children: /* @__PURE__ */ jsx21(Option, { id: CREATE_KEY, icon: /* @__PURE__ */ jsx21(Plus, {}), textValue: text, children: m.common.add(text) }) })
1649
1994
  ]
1650
1995
  }
1651
1996
  ),
1652
- isLoading && hasItems && /* @__PURE__ */ jsx20(ListBoxMessage, { children: "Loading\u2026" })
1997
+ isLoading && hasItems && /* @__PURE__ */ jsxs19(ListBoxMessage, { children: [
1998
+ m.common.loading,
1999
+ "\u2026"
2000
+ ] })
1653
2001
  ] });
1654
2002
  }
1655
2003
  function ComboboxSheet({
@@ -1681,6 +2029,7 @@ function ComboboxSheet({
1681
2029
  onApply,
1682
2030
  resultLabel
1683
2031
  }) {
2032
+ const m = useMessages();
1684
2033
  const id = useId4();
1685
2034
  const [isOpen, setOpen] = useState8(false);
1686
2035
  const [ownSearch, setOwnSearch] = useState8("");
@@ -1695,7 +2044,7 @@ function ComboboxSheet({
1695
2044
  const keys = Array.isArray(value) ? value : value == null ? [] : [value];
1696
2045
  const opened = useRef6(null);
1697
2046
  const query = search.trim();
1698
- const content = typeof children === "function" ? /* @__PURE__ */ jsx20(Collection2, { items: list, children }) : children;
2047
+ const content = typeof children === "function" ? /* @__PURE__ */ jsx21(Collection2, { items: list, children }) : children;
1699
2048
  const open = (next) => {
1700
2049
  if (next) {
1701
2050
  setSearch("");
@@ -1717,7 +2066,7 @@ function ComboboxSheet({
1717
2066
  };
1718
2067
  const descId = description ? `${id}-desc` : void 0;
1719
2068
  const errId = isInvalid && errorMessage ? `${id}-err` : void 0;
1720
- return /* @__PURE__ */ jsx20(CollectionBuilder, { content, children: (collection) => {
2069
+ return /* @__PURE__ */ jsx21(CollectionBuilder, { content, children: (collection) => {
1721
2070
  const nodes = [...collection.getKeys()].map((key) => collection.getItem(key)).filter((node) => node?.type === "item");
1722
2071
  const text = keys.map((key) => collection.getItem(key)?.textValue ?? String(key));
1723
2072
  const exact = nodes.some((node) => node.textValue.toLocaleLowerCase() === query.toLocaleLowerCase());
@@ -1732,9 +2081,9 @@ function ComboboxSheet({
1732
2081
  children: [
1733
2082
  /* @__PURE__ */ jsxs19("span", { className: "medo-field__label", id: `${id}-label`, children: [
1734
2083
  label,
1735
- isRequired && /* @__PURE__ */ jsx20("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
2084
+ isRequired && /* @__PURE__ */ jsx21("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
1736
2085
  ] }),
1737
- /* @__PURE__ */ jsx20("div", { className: cx("medo-input", `medo-input--${size}`, "medo-select__field"), children: /* @__PURE__ */ jsxs19(
2086
+ /* @__PURE__ */ jsx21("div", { className: cx("medo-input", `medo-input--${size}`, "medo-select__field"), children: /* @__PURE__ */ jsxs19(
1738
2087
  AriaButton7,
1739
2088
  {
1740
2089
  className: "medo-select__trigger",
@@ -1744,21 +2093,21 @@ function ComboboxSheet({
1744
2093
  "aria-describedby": [errId ?? descId].filter(Boolean).join(" ") || void 0,
1745
2094
  onPress: () => !isReadOnly && open(true),
1746
2095
  children: [
1747
- leadingIcon && /* @__PURE__ */ jsx20("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
2096
+ leadingIcon && /* @__PURE__ */ jsx21("span", { className: "medo-input__icon", "aria-hidden": "true", children: leadingIcon }),
1748
2097
  /* @__PURE__ */ jsxs19("span", { className: "medo-select__value", id: `${id}-value`, "data-placeholder": keys.length === 0 || void 0, children: [
1749
- keys.length === 0 ? placeholder : multiple ? /* @__PURE__ */ jsx20(DisplayTags, { labels: text, size }) : text[0],
1750
- isReadOnly && /* @__PURE__ */ jsx20("span", { className: "medo-visually-hidden", children: ", read only" })
2098
+ keys.length === 0 ? placeholder : multiple ? /* @__PURE__ */ jsx21(DisplayTags, { labels: text, size }) : text[0],
2099
+ isReadOnly && /* @__PURE__ */ jsx21("span", { className: "medo-visually-hidden", children: ", read only" })
1751
2100
  ] }),
1752
- !isReadOnly && /* @__PURE__ */ jsx20("span", { className: "medo-select__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(ChevronDown2, {}) })
2101
+ !isReadOnly && /* @__PURE__ */ jsx21("span", { className: "medo-select__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx21(ChevronDown2, {}) })
1753
2102
  ]
1754
2103
  }
1755
2104
  ) }),
1756
- /* @__PURE__ */ jsx20("div", { className: "medo-field__footer", children: isInvalid && errorMessage ? /* @__PURE__ */ jsxs19("span", { className: "medo-field__error", id: errId, children: [
1757
- /* @__PURE__ */ jsx20(CircleAlert3, { "aria-hidden": "true" }),
1758
- /* @__PURE__ */ jsx20("span", { children: errorMessage })
1759
- ] }) : description && /* @__PURE__ */ jsx20("span", { className: "medo-field__description", id: descId, children: description }) }),
1760
- name && keys.map((key) => /* @__PURE__ */ jsx20("input", { type: "hidden", name, value: String(key) }, String(key))),
1761
- /* @__PURE__ */ jsx20(
2105
+ /* @__PURE__ */ jsx21("div", { className: "medo-field__footer", children: isInvalid && errorMessage ? /* @__PURE__ */ jsxs19("span", { className: "medo-field__error", id: errId, children: [
2106
+ /* @__PURE__ */ jsx21(CircleAlert3, { "aria-hidden": "true" }),
2107
+ /* @__PURE__ */ jsx21("span", { children: errorMessage })
2108
+ ] }) : description && /* @__PURE__ */ jsx21("span", { className: "medo-field__description", id: descId, children: description }) }),
2109
+ name && keys.map((key) => /* @__PURE__ */ jsx21("input", { type: "hidden", name, value: String(key) }, String(key))),
2110
+ /* @__PURE__ */ jsx21(
1762
2111
  BottomSheet,
1763
2112
  {
1764
2113
  title: label,
@@ -1766,21 +2115,18 @@ function ComboboxSheet({
1766
2115
  isOpen,
1767
2116
  onOpenChange: open,
1768
2117
  footer: multiple ? commit === "onClose" ? (close) => /* @__PURE__ */ jsxs19(Fragment12, { children: [
1769
- /* @__PURE__ */ jsx20(Button, { size: "lg", onPress: close, children: resultLabel(keys) }),
1770
- /* @__PURE__ */ jsx20(Button, { size: "lg", variant: "secondary", onPress: () => onValueChange([]), isDisabled: keys.length === 0, children: "Reset" })
2118
+ /* @__PURE__ */ jsx21(Button, { size: "lg", onPress: close, children: resultLabel(keys) }),
2119
+ /* @__PURE__ */ jsx21(Button, { size: "lg", variant: "secondary", onPress: () => onValueChange([]), isDisabled: keys.length === 0, children: m.common.reset })
1771
2120
  ] }) : (close) => /* @__PURE__ */ jsxs19(Fragment12, { children: [
1772
- /* @__PURE__ */ jsxs19("p", { className: "medo-sheet__count", "aria-live": "polite", children: [
1773
- keys.length,
1774
- " selected"
1775
- ] }),
1776
- /* @__PURE__ */ jsx20(Button, { size: "lg", onPress: close, children: "Done" })
2121
+ /* @__PURE__ */ jsx21("p", { className: "medo-sheet__count", "aria-live": "polite", children: m.common.countSelected(keys.length) }),
2122
+ /* @__PURE__ */ jsx21(Button, { size: "lg", onPress: close, children: m.common.done })
1777
2123
  ] }) : void 0,
1778
2124
  children: /* @__PURE__ */ jsxs19(Autocomplete, { inputValue: search, onInputChange: setSearch, filter: items ? void 0 : contains, children: [
1779
- /* @__PURE__ */ jsx20("div", { className: "medo-sheet__search", children: /* @__PURE__ */ jsxs19(AriaTextField2, { "aria-label": "Search", autoFocus: true, className: "medo-input medo-input--lg", children: [
1780
- /* @__PURE__ */ jsx20("span", { className: "medo-input__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(Search, {}) }),
1781
- /* @__PURE__ */ jsx20(Input, { className: "medo-input__control", placeholder })
2125
+ /* @__PURE__ */ jsx21("div", { className: "medo-sheet__search", children: /* @__PURE__ */ jsxs19(AriaTextField2, { "aria-label": m.common.search, autoFocus: true, className: "medo-input medo-input--lg", children: [
2126
+ /* @__PURE__ */ jsx21("span", { className: "medo-input__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx21(Search, {}) }),
2127
+ /* @__PURE__ */ jsx21(Input, { className: "medo-input__control", placeholder })
1782
2128
  ] }) }),
1783
- /* @__PURE__ */ jsx20(OptionHighlightContext.Provider, { value: query, children: /* @__PURE__ */ jsxs19(
2129
+ /* @__PURE__ */ jsx21(OptionHighlightContext.Provider, { value: query, children: /* @__PURE__ */ jsxs19(
1784
2130
  ListBox,
1785
2131
  {
1786
2132
  size: "lg",
@@ -1788,14 +2134,14 @@ function ComboboxSheet({
1788
2134
  selectionMode: multiple ? "multiple" : "single",
1789
2135
  selectedKeys: keys,
1790
2136
  onSelectionChange,
1791
- renderEmptyState: () => /* @__PURE__ */ jsx20(ListBoxMessage, { children: isLoading ? "Loading\u2026" : noResultsMessage(query) }),
2137
+ renderEmptyState: () => /* @__PURE__ */ jsx21(ListBoxMessage, { children: isLoading ? `${m.common.loading}\u2026` : noResultsMessage(query) }),
1792
2138
  children: [
1793
2139
  content,
1794
- multiple && onCreate && query && !exact && /* @__PURE__ */ jsx20(ListBoxSection, { "aria-label": "Create", children: /* @__PURE__ */ jsx20(Option, { id: CREATE_KEY, icon: /* @__PURE__ */ jsx20(Plus, {}), textValue: query, children: `Add \u201E${query}\u201C` }) })
2140
+ multiple && onCreate && query && !exact && /* @__PURE__ */ jsx21(ListBoxSection, { "aria-label": m.common.create, children: /* @__PURE__ */ jsx21(Option, { id: CREATE_KEY, icon: /* @__PURE__ */ jsx21(Plus, {}), textValue: query, children: m.common.add(query) }) })
1795
2141
  ]
1796
2142
  }
1797
2143
  ) }),
1798
- isLoading && list && [...list].length > 0 && /* @__PURE__ */ jsx20(ListBoxMessage, { children: "Loading\u2026" })
2144
+ isLoading && list && [...list].length > 0 && /* @__PURE__ */ jsx21(ListBoxMessage, { children: "Loading\u2026" })
1799
2145
  ] })
1800
2146
  }
1801
2147
  )
@@ -1810,15 +2156,15 @@ function DisplayTags({ labels, size }) {
1810
2156
  const visible = useFitCount(rowRef, measureRef, labels.join("\0"), labels.length);
1811
2157
  const tagClass = cx("medo-tag", size === "lg" ? "medo-tag--md" : "medo-tag--sm");
1812
2158
  return /* @__PURE__ */ jsxs19("span", { className: "medo-select__tags", ref: rowRef, children: [
1813
- /* @__PURE__ */ jsx20("span", { className: "medo-visually-hidden", children: labels.join(", ") }),
2159
+ /* @__PURE__ */ jsx21("span", { className: "medo-visually-hidden", children: labels.join(", ") }),
1814
2160
  /* @__PURE__ */ jsxs19("span", { className: "medo-select__measure", ref: measureRef, "aria-hidden": "true", children: [
1815
- labels.map((l, i) => /* @__PURE__ */ jsx20("span", { className: tagClass, children: l }, i)),
2161
+ labels.map((l, i) => /* @__PURE__ */ jsx21("span", { className: tagClass, children: l }, i)),
1816
2162
  /* @__PURE__ */ jsxs19("span", { className: tagClass, children: [
1817
2163
  "+",
1818
2164
  labels.length
1819
2165
  ] })
1820
2166
  ] }),
1821
- labels.slice(0, visible).map((l, i) => /* @__PURE__ */ jsx20("span", { className: tagClass, "aria-hidden": "true", children: /* @__PURE__ */ jsx20("span", { className: "medo-select__tag-label", children: l }) }, i)),
2167
+ labels.slice(0, visible).map((l, i) => /* @__PURE__ */ jsx21("span", { className: tagClass, "aria-hidden": "true", children: /* @__PURE__ */ jsx21("span", { className: "medo-select__tag-label", children: l }) }, i)),
1822
2168
  labels.length > visible && /* @__PURE__ */ jsxs19("span", { className: tagClass, "aria-hidden": "true", children: [
1823
2169
  "+",
1824
2170
  labels.length - visible
@@ -1838,7 +2184,7 @@ import {
1838
2184
  UNSTABLE_ToastRegion as AriaToastRegion
1839
2185
  } from "react-aria-components";
1840
2186
  import { X as X7 } from "lucide-react";
1841
- import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
2187
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
1842
2188
  var TIMEOUT = 5e3;
1843
2189
  var TIMEOUT_ACTION = 8e3;
1844
2190
  var MAX_VISIBLE = 3;
@@ -1873,6 +2219,7 @@ function closeOnEscape(el, key) {
1873
2219
  return () => el.removeEventListener("keydown", onKeyDown);
1874
2220
  }
1875
2221
  function ToastRegion({ closeLabel, ...props }) {
2222
+ const m = useMessages();
1876
2223
  const [active, setActive] = useState9(false);
1877
2224
  useEffect7(() => {
1878
2225
  if (regionMounted) return;
@@ -1886,7 +2233,7 @@ function ToastRegion({ closeLabel, ...props }) {
1886
2233
  };
1887
2234
  }, []);
1888
2235
  if (!active) return null;
1889
- return /* @__PURE__ */ jsx21(AriaToastRegion, { ...props, queue, className: "medo-toast-region", children: ({ toast: t }) => /* @__PURE__ */ jsxs20(
2236
+ return /* @__PURE__ */ jsx22(AriaToastRegion, { ...props, queue, className: "medo-toast-region", children: ({ toast: t }) => /* @__PURE__ */ jsxs20(
1890
2237
  AriaToast,
1891
2238
  {
1892
2239
  toast: t,
@@ -1894,8 +2241,8 @@ function ToastRegion({ closeLabel, ...props }) {
1894
2241
  style: { viewTransitionName: t.key },
1895
2242
  ref: (el) => closeOnEscape(el, t.key),
1896
2243
  children: [
1897
- /* @__PURE__ */ jsx21(AriaToastContent, { className: "medo-toast__content", children: /* @__PURE__ */ jsx21(Text8, { slot: "title", className: "medo-toast__message", children: t.content.message }) }),
1898
- t.content.action && /* @__PURE__ */ jsx21(
2244
+ /* @__PURE__ */ jsx22(AriaToastContent, { className: "medo-toast__content", children: /* @__PURE__ */ jsx22(Text8, { slot: "title", className: "medo-toast__message", children: t.content.message }) }),
2245
+ t.content.action && /* @__PURE__ */ jsx22(
1899
2246
  Button2,
1900
2247
  {
1901
2248
  className: "medo-toast__button medo-toast__action",
@@ -1906,7 +2253,7 @@ function ToastRegion({ closeLabel, ...props }) {
1906
2253
  children: t.content.action.label
1907
2254
  }
1908
2255
  ),
1909
- /* @__PURE__ */ jsx21(Button2, { slot: "close", "aria-label": closeLabel, className: "medo-toast__button medo-toast__close", children: /* @__PURE__ */ jsx21(X7, { "aria-hidden": "true" }) })
2256
+ /* @__PURE__ */ jsx22(Button2, { slot: "close", "aria-label": closeLabel ?? m.common.close, className: "medo-toast__button medo-toast__close", children: /* @__PURE__ */ jsx22(X7, { "aria-hidden": "true" }) })
1910
2257
  ]
1911
2258
  }
1912
2259
  ) });
@@ -1921,25 +2268,25 @@ import {
1921
2268
  TabPanel as AriaTabPanel,
1922
2269
  Tabs as AriaTabs
1923
2270
  } from "react-aria-components";
1924
- import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
2271
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
1925
2272
  function Tabs({ size = "md", fullWidth = false, className, ...props }) {
1926
- return /* @__PURE__ */ jsx22(AriaTabs, { ...props, className: cx("medo-tabs", `medo-tabs--${size}`, fullWidth && "medo-tabs--full", className) });
2273
+ return /* @__PURE__ */ jsx23(AriaTabs, { ...props, className: cx("medo-tabs", `medo-tabs--${size}`, fullWidth && "medo-tabs--full", className) });
1927
2274
  }
1928
2275
  function TabList({ className, ...props }) {
1929
2276
  const ref = useRef7(null);
1930
2277
  useScrollEdges(ref);
1931
- return /* @__PURE__ */ jsx22(AriaTabList, { ...props, ref, className: cx("medo-tabs__list", className) });
2278
+ return /* @__PURE__ */ jsx23(AriaTabList, { ...props, ref, className: cx("medo-tabs__list", className) });
1932
2279
  }
1933
2280
  function Tab({ children, icon, count, countLabel, ...props }) {
1934
2281
  return /* @__PURE__ */ jsxs21(AriaTab, { ...props, className: "medo-tab", children: [
1935
- /* @__PURE__ */ jsx22(SelectionIndicator2, { className: "medo-tab__thumb", ref: revealInList }),
1936
- icon && /* @__PURE__ */ jsx22("span", { className: "medo-tab__icon", "aria-hidden": "true", children: icon }),
1937
- /* @__PURE__ */ jsx22("span", { className: "medo-tab__label", children }),
1938
- count !== void 0 && /* @__PURE__ */ jsx22(BadgeCount, { count, tone: "neutral", size: "sm", label: countLabel ?? String(count) })
2282
+ /* @__PURE__ */ jsx23(SelectionIndicator2, { className: "medo-tab__thumb", ref: revealInList }),
2283
+ icon && /* @__PURE__ */ jsx23("span", { className: "medo-tab__icon", "aria-hidden": "true", children: icon }),
2284
+ /* @__PURE__ */ jsx23("span", { className: "medo-tab__label", children }),
2285
+ count !== void 0 && /* @__PURE__ */ jsx23(BadgeCount, { count, tone: "neutral", size: "sm", label: countLabel ?? String(count) })
1939
2286
  ] });
1940
2287
  }
1941
2288
  function TabPanel({ keepMounted = true, className, ...props }) {
1942
- return /* @__PURE__ */ jsx22(AriaTabPanel, { ...props, shouldForceMount: keepMounted, className: cx("medo-tabs__panel", className) });
2289
+ return /* @__PURE__ */ jsx23(AriaTabPanel, { ...props, shouldForceMount: keepMounted, className: cx("medo-tabs__panel", className) });
1943
2290
  }
1944
2291
  function revealInList(thumb) {
1945
2292
  const tab = thumb?.parentElement;
@@ -1972,7 +2319,7 @@ function useScrollEdges(ref) {
1972
2319
  }
1973
2320
 
1974
2321
  // src/popover/Popover.tsx
1975
- import { useContext as useContext13, useRef as useRef8 } from "react";
2322
+ import { useContext as useContext14, useRef as useRef8 } from "react";
1976
2323
  import {
1977
2324
  Dialog as AriaDialog2,
1978
2325
  DialogTrigger as DialogTrigger2,
@@ -1985,7 +2332,7 @@ import { Info as Info2, X as X8 } from "lucide-react";
1985
2332
  // src/link/Link.tsx
1986
2333
  import { Link as AriaLink2 } from "react-aria-components";
1987
2334
  import { ArrowRight, ExternalLink } from "lucide-react";
1988
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
2335
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
1989
2336
  function Link({
1990
2337
  children,
1991
2338
  variant = "inline",
@@ -2005,8 +2352,8 @@ function Link({
2005
2352
  className: cx("medo-link", variant === "standalone" && "medo-link--standalone", variant === "standalone" && `medo-link--${size}`, className),
2006
2353
  children: [
2007
2354
  children,
2008
- external && /* @__PURE__ */ jsx23(ExternalLink, { className: "medo-link__icon", "aria-hidden": "true" }),
2009
- !external && arrow && variant === "standalone" && /* @__PURE__ */ jsx23(ArrowRight, { className: "medo-link__icon", "aria-hidden": "true" }),
2355
+ external && /* @__PURE__ */ jsx24(ExternalLink, { className: "medo-link__icon", "aria-hidden": "true" }),
2356
+ !external && arrow && variant === "standalone" && /* @__PURE__ */ jsx24(ArrowRight, { className: "medo-link__icon", "aria-hidden": "true" }),
2010
2357
  newTab && /* @__PURE__ */ jsxs22("span", { className: "medo-visually-hidden", children: [
2011
2358
  " ",
2012
2359
  newTabLabel
@@ -2017,7 +2364,7 @@ function Link({
2017
2364
  }
2018
2365
 
2019
2366
  // src/popover/Popover.tsx
2020
- import { Fragment as Fragment13, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
2367
+ import { Fragment as Fragment13, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
2021
2368
  var PopoverTrigger = DialogTrigger2;
2022
2369
  function Popover5({
2023
2370
  title,
@@ -2025,62 +2372,65 @@ function Popover5({
2025
2372
  children,
2026
2373
  size = "md",
2027
2374
  primaryAction,
2028
- cancelLabel = "Cancel",
2029
- closeLabel = "Close",
2375
+ cancelLabel: cancelLabelProp,
2376
+ closeLabel: closeLabelProp,
2030
2377
  overlay = "auto",
2031
2378
  placement = "bottom start",
2032
2379
  className
2033
2380
  }) {
2381
+ const m = useMessages();
2382
+ const cancelLabel = cancelLabelProp ?? m.common.cancel;
2383
+ const closeLabel = closeLabelProp ?? m.common.close;
2034
2384
  const mobile = useMediaQuery(MOBILE_QUERY);
2035
2385
  const content = (close) => typeof children === "function" ? children(close) : children;
2036
2386
  if (overlay === "sheet" || overlay === "auto" && mobile) {
2037
- return /* @__PURE__ */ jsx24(
2387
+ return /* @__PURE__ */ jsx25(
2038
2388
  BottomSheet,
2039
2389
  {
2040
2390
  title: title ?? ariaLabel,
2041
2391
  closeLabel,
2042
2392
  className,
2043
2393
  footer: primaryAction && ((close) => /* @__PURE__ */ jsxs23(ButtonGroup, { children: [
2044
- /* @__PURE__ */ jsx24(Button, { variant: "secondary", size: "lg", onPress: close, children: cancelLabel }),
2045
- /* @__PURE__ */ jsx24(ActionButton, { action: primaryAction, close, size: "lg", variant: "primary" })
2394
+ /* @__PURE__ */ jsx25(Button, { variant: "secondary", size: "lg", onPress: close, children: cancelLabel }),
2395
+ /* @__PURE__ */ jsx25(ActionButton, { action: primaryAction, close, size: "lg", variant: "primary" })
2046
2396
  ] })),
2047
- children: /* @__PURE__ */ jsx24(SheetBody, { children: content })
2397
+ children: /* @__PURE__ */ jsx25(SheetBody, { children: content })
2048
2398
  }
2049
2399
  );
2050
2400
  }
2051
- return /* @__PURE__ */ jsx24(AriaPopover, { placement, offset: 8, containerPadding: 16, className: cx("medo-popover", `medo-popover--${size}`, className), children: /* @__PURE__ */ jsx24(PopoverDialog, { "aria-label": title ? void 0 : ariaLabel, children: ({ close }) => /* @__PURE__ */ jsxs23(Fragment13, { children: [
2401
+ return /* @__PURE__ */ jsx25(AriaPopover, { placement, offset: 8, containerPadding: 16, className: cx("medo-popover", `medo-popover--${size}`, className), children: /* @__PURE__ */ jsx25(PopoverDialog, { "aria-label": title ? void 0 : ariaLabel, children: ({ close }) => /* @__PURE__ */ jsxs23(Fragment13, { children: [
2052
2402
  title && /* @__PURE__ */ jsxs23("div", { className: "medo-popover__header", children: [
2053
- /* @__PURE__ */ jsx24(Heading3, { slot: "title", className: "medo-popover__title", children: title }),
2054
- /* @__PURE__ */ jsx24(IconButton, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx24(X8, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
2403
+ /* @__PURE__ */ jsx25(Heading3, { slot: "title", className: "medo-popover__title", children: title }),
2404
+ /* @__PURE__ */ jsx25(IconButton, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx25(X8, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
2055
2405
  ] }),
2056
- /* @__PURE__ */ jsx24("div", { className: "medo-popover__body", children: content(close) }),
2057
- primaryAction && /* @__PURE__ */ jsx24("div", { className: "medo-popover__footer", children: /* @__PURE__ */ jsxs23(ButtonGroup, { children: [
2058
- /* @__PURE__ */ jsx24(Button, { variant: "secondary", size: "sm", onPress: close, children: cancelLabel }),
2059
- /* @__PURE__ */ jsx24(ActionButton, { action: primaryAction, close, size: "sm", variant: "primary" })
2406
+ /* @__PURE__ */ jsx25("div", { className: "medo-popover__body", children: content(close) }),
2407
+ primaryAction && /* @__PURE__ */ jsx25("div", { className: "medo-popover__footer", children: /* @__PURE__ */ jsxs23(ButtonGroup, { children: [
2408
+ /* @__PURE__ */ jsx25(Button, { variant: "secondary", size: "sm", onPress: close, children: cancelLabel }),
2409
+ /* @__PURE__ */ jsx25(ActionButton, { action: primaryAction, close, size: "sm", variant: "primary" })
2060
2410
  ] }) })
2061
2411
  ] }) }) });
2062
2412
  }
2063
2413
  function PopoverDialog({ children, ...props }) {
2064
2414
  const ref = useRef8(null);
2065
2415
  useInitialFocus(ref);
2066
- return /* @__PURE__ */ jsx24(AriaDialog2, { ...props, ref, className: "medo-popover__dialog", children });
2416
+ return /* @__PURE__ */ jsx25(AriaDialog2, { ...props, ref, className: "medo-popover__dialog", children });
2067
2417
  }
2068
2418
  function SheetBody({ children }) {
2069
- const state = useContext13(OverlayTriggerStateContext3);
2070
- return /* @__PURE__ */ jsx24("div", { className: "medo-popover__sheet-body", children: children(() => state?.close()) });
2419
+ const state = useContext14(OverlayTriggerStateContext3);
2420
+ return /* @__PURE__ */ jsx25("div", { className: "medo-popover__sheet-body", children: children(() => state?.close()) });
2071
2421
  }
2072
2422
  function Toggletip({ "aria-label": label, children, link, className }) {
2073
2423
  return /* @__PURE__ */ jsxs23(DialogTrigger2, { children: [
2074
- /* @__PURE__ */ jsx24(IconButton, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx24(Info2, {}), "aria-label": label, tooltip: false }),
2075
- /* @__PURE__ */ jsx24(AriaPopover, { placement: "bottom start", offset: 8, containerPadding: 16, className: cx("medo-popover", "medo-toggletip", className), children: /* @__PURE__ */ jsxs23(AriaDialog2, { "aria-label": label, className: "medo-popover__dialog medo-toggletip__dialog", children: [
2076
- /* @__PURE__ */ jsx24("div", { className: "medo-toggletip__text", children }),
2077
- link && /* @__PURE__ */ jsx24(Link, { variant: "standalone", size: "md", href: link.href, external: link.external, target: link.external ? "_blank" : void 0, children: link.label })
2424
+ /* @__PURE__ */ jsx25(IconButton, { variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx25(Info2, {}), "aria-label": label, tooltip: false }),
2425
+ /* @__PURE__ */ jsx25(AriaPopover, { placement: "bottom start", offset: 8, containerPadding: 16, className: cx("medo-popover", "medo-toggletip", className), children: /* @__PURE__ */ jsxs23(AriaDialog2, { "aria-label": label, className: "medo-popover__dialog medo-toggletip__dialog", children: [
2426
+ /* @__PURE__ */ jsx25("div", { className: "medo-toggletip__text", children }),
2427
+ link && /* @__PURE__ */ jsx25(Link, { variant: "standalone", size: "md", href: link.href, external: link.external, target: link.external ? "_blank" : void 0, children: link.label })
2078
2428
  ] }) })
2079
2429
  ] });
2080
2430
  }
2081
2431
 
2082
2432
  // src/navigation/Navigation.tsx
2083
- import { Children as Children2, createContext as createContext7, isValidElement as isValidElement2, useContext as useContext14, useEffect as useEffect9, useId as useId5, useRef as useRef10, useState as useState10 } from "react";
2433
+ import { Children as Children2, createContext as createContext8, isValidElement as isValidElement2, useContext as useContext15, useEffect as useEffect9, useId as useId5, useRef as useRef10, useState as useState10 } from "react";
2084
2434
  import {
2085
2435
  Button as AriaButton8,
2086
2436
  Dialog as AriaDialog4,
@@ -2096,7 +2446,7 @@ import { ChevronDown as ChevronDown3, Ellipsis as Ellipsis2, Menu as MenuIcon, P
2096
2446
  import { useEffect as useEffect8, useRef as useRef9 } from "react";
2097
2447
  import { Dialog as AriaDialog3, Heading as Heading4, Modal as Modal3, ModalOverlay as ModalOverlay3 } from "react-aria-components";
2098
2448
  import { X as X9 } from "lucide-react";
2099
- import { Fragment as Fragment14, jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
2449
+ import { Fragment as Fragment14, jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
2100
2450
  function Drawer({
2101
2451
  title,
2102
2452
  "aria-label": ariaLabel,
@@ -2104,27 +2454,28 @@ function Drawer({
2104
2454
  footer,
2105
2455
  side = "right",
2106
2456
  size = "sm",
2107
- closeLabel = "Close",
2457
+ closeLabel,
2108
2458
  isDirty = false,
2109
2459
  discardText,
2110
2460
  className,
2111
2461
  ...openProps
2112
2462
  }) {
2463
+ const m = useMessages();
2113
2464
  const { open, onOpenChange, confirmDiscard, forceClose } = useDirtyGuard({ isDirty, discardText, ...openProps });
2114
- return /* @__PURE__ */ jsx25(ModalOverlay3, { isOpen: open, onOpenChange, isDismissable: !isDirty, className: cx("medo-drawer-overlay", `medo-drawer-overlay--${side}`), children: /* @__PURE__ */ jsx25(Modal3, { className: cx("medo-drawer", `medo-drawer--${side}`, `medo-drawer--${size}`, className), children: /* @__PURE__ */ jsx25(DrawerDialog, { "aria-label": ariaLabel, side, children: (close) => /* @__PURE__ */ jsxs24(Fragment14, { children: [
2465
+ return /* @__PURE__ */ jsx26(ModalOverlay3, { isOpen: open, onOpenChange, isDismissable: !isDirty, className: cx("medo-drawer-overlay", `medo-drawer-overlay--${side}`), children: /* @__PURE__ */ jsx26(Modal3, { className: cx("medo-drawer", `medo-drawer--${side}`, `medo-drawer--${size}`, className), children: /* @__PURE__ */ jsx26(DrawerDialog, { "aria-label": ariaLabel, side, children: (close) => /* @__PURE__ */ jsxs24(Fragment14, { children: [
2115
2466
  /* @__PURE__ */ jsxs24("div", { className: "medo-drawer__header", children: [
2116
- ariaLabel ? /* @__PURE__ */ jsx25("div", { className: "medo-drawer__title", children: title }) : /* @__PURE__ */ jsx25(Heading4, { slot: "title", className: "medo-drawer__title", children: title }),
2117
- /* @__PURE__ */ jsx25(IconButton, { variant: "ghost", size: "md", icon: /* @__PURE__ */ jsx25(X9, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
2467
+ ariaLabel ? /* @__PURE__ */ jsx26("div", { className: "medo-drawer__title", children: title }) : /* @__PURE__ */ jsx26(Heading4, { slot: "title", className: "medo-drawer__title", children: title }),
2468
+ /* @__PURE__ */ jsx26(IconButton, { variant: "ghost", size: "md", icon: /* @__PURE__ */ jsx26(X9, {}), "aria-label": closeLabel ?? m.common.close, tooltip: false, onPress: close })
2118
2469
  ] }),
2119
- /* @__PURE__ */ jsx25("div", { className: "medo-drawer__body", children: typeof children === "function" ? children(forceClose) : children }),
2120
- footer && /* @__PURE__ */ jsx25("div", { className: "medo-drawer__footer", children: typeof footer === "function" ? footer(forceClose, close) : footer }),
2470
+ /* @__PURE__ */ jsx26("div", { className: "medo-drawer__body", children: typeof children === "function" ? children(forceClose) : children }),
2471
+ footer && /* @__PURE__ */ jsx26("div", { className: "medo-drawer__footer", children: typeof footer === "function" ? footer(forceClose, close) : footer }),
2121
2472
  confirmDiscard
2122
2473
  ] }) }) }) });
2123
2474
  }
2124
2475
  function DrawerDialog({ children, side, ...props }) {
2125
2476
  const ref = useRef9(null);
2126
- return /* @__PURE__ */ jsx25(AriaDialog3, { ...props, ref, className: "medo-drawer__dialog", children: ({ close }) => /* @__PURE__ */ jsxs24(Fragment14, { children: [
2127
- /* @__PURE__ */ jsx25(SwipeToClose, { target: ref, side, onClose: close }),
2477
+ return /* @__PURE__ */ jsx26(AriaDialog3, { ...props, ref, className: "medo-drawer__dialog", children: ({ close }) => /* @__PURE__ */ jsxs24(Fragment14, { children: [
2478
+ /* @__PURE__ */ jsx26(SwipeToClose, { target: ref, side, onClose: close }),
2128
2479
  children(close)
2129
2480
  ] }) });
2130
2481
  }
@@ -2184,19 +2535,19 @@ function SwipeToClose({ target, side, onClose }) {
2184
2535
  }
2185
2536
 
2186
2537
  // src/navigation/Navigation.tsx
2187
- import { Fragment as Fragment15, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
2188
- var NavVariantContext = createContext7("sidebar");
2189
- var SideNavContext = createContext7(null);
2538
+ import { Fragment as Fragment15, jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
2539
+ var NavVariantContext = createContext8("sidebar");
2540
+ var SideNavContext = createContext8(null);
2190
2541
  var TABLET_QUERY = "(min-width: 640px) and (max-width: 1023.98px)";
2191
2542
  var SITE_MENU_QUERY = "(max-width: 767.98px)";
2192
2543
  function NavItem({ children, icon, isCurrent, count, countLabel, unread, ...props }) {
2193
- const variant = useContext14(NavVariantContext);
2194
- const sideNav = useContext14(SideNavContext);
2544
+ const variant = useContext15(NavVariantContext);
2545
+ const sideNav = useContext15(SideNavContext);
2195
2546
  const rail = variant === "rail";
2196
2547
  const content = /* @__PURE__ */ jsxs25(Fragment15, { children: [
2197
- icon && variant !== "header" && /* @__PURE__ */ jsx26("span", { className: "medo-nav-item__icon", "aria-hidden": "true", children: icon }),
2198
- /* @__PURE__ */ jsx26("span", { className: rail ? "medo-visually-hidden" : "medo-nav-item__label", children }),
2199
- count !== void 0 && (rail ? unread && count > 0 && /* @__PURE__ */ jsx26(BadgeDot, { tone: "danger", label: countLabel ?? String(count), className: "medo-nav-item__dot" }) : /* @__PURE__ */ jsx26(BadgeCount, { count, tone: "neutral", size: "sm", label: countLabel ?? String(count) }))
2548
+ icon && variant !== "header" && /* @__PURE__ */ jsx27("span", { className: "medo-nav-item__icon", "aria-hidden": "true", children: icon }),
2549
+ /* @__PURE__ */ jsx27("span", { className: rail ? "medo-visually-hidden" : "medo-nav-item__label", children }),
2550
+ count !== void 0 && (rail ? unread && count > 0 && /* @__PURE__ */ jsx27(BadgeDot, { tone: "danger", label: countLabel ?? String(count), className: "medo-nav-item__dot" }) : /* @__PURE__ */ jsx27(BadgeCount, { count, tone: "neutral", size: "sm", label: countLabel ?? String(count) }))
2200
2551
  ] });
2201
2552
  const linkProps = {
2202
2553
  ...props,
@@ -2207,20 +2558,20 @@ function NavItem({ children, icon, isCurrent, count, countLabel, unread, ...prop
2207
2558
  "aria-current": isCurrent ? "page" : void 0,
2208
2559
  className: cx("medo-nav-item", `medo-nav-item--${variant}`)
2209
2560
  };
2210
- return /* @__PURE__ */ jsx26("li", { className: "medo-nav__entry", children: rail ? (
2561
+ return /* @__PURE__ */ jsx27("li", { className: "medo-nav__entry", children: rail ? (
2211
2562
  // Collapsed: the label appears as tooltip on hover and focus.
2212
2563
  /* @__PURE__ */ jsxs25(TooltipTrigger, { children: [
2213
- /* @__PURE__ */ jsx26(TooltipLink, { ...linkProps, children: content }),
2214
- /* @__PURE__ */ jsx26(Tooltip, { placement: "end", children })
2564
+ /* @__PURE__ */ jsx27(TooltipLink, { ...linkProps, children: content }),
2565
+ /* @__PURE__ */ jsx27(Tooltip, { placement: "end", children })
2215
2566
  ] })
2216
- ) : /* @__PURE__ */ jsx26(AriaLink3, { ...linkProps, children: content }) });
2567
+ ) : /* @__PURE__ */ jsx27(AriaLink3, { ...linkProps, children: content }) });
2217
2568
  }
2218
2569
  function containsCurrent(children) {
2219
2570
  return Children2.toArray(children).some((c) => isValidElement2(c) && c.props.isCurrent);
2220
2571
  }
2221
2572
  function NavGroup({ label, icon, children, defaultOpen }) {
2222
- const variant = useContext14(NavVariantContext);
2223
- const sideNav = useContext14(SideNavContext);
2573
+ const variant = useContext15(NavVariantContext);
2574
+ const sideNav = useContext15(SideNavContext);
2224
2575
  const hasCurrent = containsCurrent(children);
2225
2576
  const [open, setOpen] = useState10(defaultOpen ?? (variant !== "header" && (hasCurrent || sideNav?.openGroup === label)));
2226
2577
  const panelId = useId5();
@@ -2247,7 +2598,7 @@ function NavGroup({ label, icon, children, defaultOpen }) {
2247
2598
  };
2248
2599
  }, [floating, open]);
2249
2600
  if (variant === "rail") {
2250
- return /* @__PURE__ */ jsx26("li", { className: "medo-nav__entry", children: /* @__PURE__ */ jsxs25(TooltipTrigger, { children: [
2601
+ return /* @__PURE__ */ jsx27("li", { className: "medo-nav__entry", children: /* @__PURE__ */ jsxs25(TooltipTrigger, { children: [
2251
2602
  /* @__PURE__ */ jsxs25(
2252
2603
  AriaButton8,
2253
2604
  {
@@ -2258,12 +2609,12 @@ function NavGroup({ label, icon, children, defaultOpen }) {
2258
2609
  sideNav?.expand(label);
2259
2610
  },
2260
2611
  children: [
2261
- /* @__PURE__ */ jsx26("span", { className: "medo-nav-item__icon", "aria-hidden": "true", children: icon }),
2262
- /* @__PURE__ */ jsx26("span", { className: "medo-visually-hidden", children: label })
2612
+ /* @__PURE__ */ jsx27("span", { className: "medo-nav-item__icon", "aria-hidden": "true", children: icon }),
2613
+ /* @__PURE__ */ jsx27("span", { className: "medo-visually-hidden", children: label })
2263
2614
  ]
2264
2615
  }
2265
2616
  ),
2266
- /* @__PURE__ */ jsx26(Tooltip, { placement: "end", children: label })
2617
+ /* @__PURE__ */ jsx27(Tooltip, { placement: "end", children: label })
2267
2618
  ] }) });
2268
2619
  }
2269
2620
  return /* @__PURE__ */ jsxs25("li", { ref: itemRef, className: cx("medo-nav__entry", "medo-nav-group", floating && "medo-nav-group--floating"), children: [
@@ -2277,45 +2628,50 @@ function NavGroup({ label, icon, children, defaultOpen }) {
2277
2628
  onPress: () => setOpen((o) => !o),
2278
2629
  className: cx("medo-nav-item", `medo-nav-item--${variant}`, "medo-nav-group__button"),
2279
2630
  children: [
2280
- icon && !floating && /* @__PURE__ */ jsx26("span", { className: "medo-nav-item__icon", "aria-hidden": "true", children: icon }),
2281
- /* @__PURE__ */ jsx26("span", { className: "medo-nav-item__label", children: label }),
2282
- /* @__PURE__ */ jsx26(ChevronDown3, { className: "medo-nav-group__chevron", "aria-hidden": "true" })
2631
+ icon && !floating && /* @__PURE__ */ jsx27("span", { className: "medo-nav-item__icon", "aria-hidden": "true", children: icon }),
2632
+ /* @__PURE__ */ jsx27("span", { className: "medo-nav-item__label", children: label }),
2633
+ /* @__PURE__ */ jsx27(ChevronDown3, { className: "medo-nav-group__chevron", "aria-hidden": "true" })
2283
2634
  ]
2284
2635
  }
2285
2636
  ),
2286
- /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: floating ? "sidebar" : variant, children: /* @__PURE__ */ jsx26("ul", { id: panelId, hidden: !open, className: cx("medo-nav__list", floating ? "medo-nav-group__panel" : "medo-nav-group__list"), children }) })
2637
+ /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: floating ? "sidebar" : variant, children: /* @__PURE__ */ jsx27("ul", { id: panelId, hidden: !open, className: cx("medo-nav__list", floating ? "medo-nav-group__panel" : "medo-nav-group__list"), children }) })
2287
2638
  ] });
2288
2639
  }
2289
2640
  function NavList({ variant = "sidebar", "aria-label": label, children, className }) {
2290
- return /* @__PURE__ */ jsx26("nav", { "aria-label": label, className, children: /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx26("ul", { className: cx("medo-nav__list", variant === "header" && "medo-nav__list--row", variant === "rail" && "medo-nav__list--rail"), children }) }) });
2641
+ return /* @__PURE__ */ jsx27("nav", { "aria-label": label, className, children: /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx27("ul", { className: cx("medo-nav__list", variant === "header" && "medo-nav__list--row", variant === "rail" && "medo-nav__list--rail"), children }) }) });
2291
2642
  }
2292
2643
  function NavSection({ title, children }) {
2293
- const variant = useContext14(NavVariantContext);
2644
+ const variant = useContext15(NavVariantContext);
2294
2645
  const id = useId5();
2295
2646
  return /* @__PURE__ */ jsxs25("li", { className: "medo-nav__entry medo-nav-section", children: [
2296
- variant === "rail" ? /* @__PURE__ */ jsx26("span", { className: "medo-nav-section__divider", role: "presentation" }) : /* @__PURE__ */ jsx26("span", { id, className: "medo-nav-section__title", children: title }),
2297
- /* @__PURE__ */ jsx26("ul", { className: "medo-nav__list", "aria-labelledby": variant === "rail" ? void 0 : id, "aria-label": variant === "rail" ? title : void 0, children })
2647
+ variant === "rail" ? /* @__PURE__ */ jsx27("span", { className: "medo-nav-section__divider", role: "presentation" }) : /* @__PURE__ */ jsx27("span", { id, className: "medo-nav-section__title", children: title }),
2648
+ /* @__PURE__ */ jsx27("ul", { className: "medo-nav__list", "aria-labelledby": variant === "rail" ? void 0 : id, "aria-label": variant === "rail" ? title : void 0, children })
2298
2649
  ] });
2299
2650
  }
2300
- function SkipLink({ href = "#main", children = "Skip to content" }) {
2301
- return /* @__PURE__ */ jsx26("a", { href, className: "medo-skip-link", children });
2651
+ function SkipLink({ href = "#main", children }) {
2652
+ const m = useMessages();
2653
+ return /* @__PURE__ */ jsx27("a", { href, className: "medo-skip-link", children: children ?? m.navigation.skipToContent });
2302
2654
  }
2303
2655
  function ActionLink({ action, size }) {
2304
- return /* @__PURE__ */ jsx26(AriaLink3, { href: action.href, onPress: action.onPress, className: cx("medo-button", `medo-button--${action.variant ?? "ghost"}`, `medo-button--${size}`), children: /* @__PURE__ */ jsx26("span", { className: "medo-button__label", children: action.label }) });
2656
+ return /* @__PURE__ */ jsx27(AriaLink3, { href: action.href, onPress: action.onPress, className: cx("medo-button", `medo-button--${action.variant ?? "ghost"}`, `medo-button--${size}`), children: /* @__PURE__ */ jsx27("span", { className: "medo-button__label", children: action.label }) });
2305
2657
  }
2306
- function SiteHeader({ logo, children, actions = [], "aria-label": label = "Main", menuLabel = "Menu", closeLabel = "Close", layout = "auto" }) {
2658
+ function SiteHeader({ logo, children, actions = [], "aria-label": labelProp, menuLabel: menuLabelProp, closeLabel: closeLabelProp, layout = "auto" }) {
2659
+ const m = useMessages();
2660
+ const label = labelProp ?? m.navigation.main;
2661
+ const menuLabel = menuLabelProp ?? m.navigation.menu;
2662
+ const closeLabel = closeLabelProp ?? m.common.close;
2307
2663
  const narrow = useMediaQuery(SITE_MENU_QUERY);
2308
2664
  const compact = layout === "mobile" || layout === "auto" && narrow;
2309
2665
  const scrolled = useScrolled();
2310
2666
  const primary = actions.find((a) => a.variant === "primary");
2311
2667
  return /* @__PURE__ */ jsxs25("header", { className: cx("medo-site-header", compact && "medo-site-header--compact"), "data-scrolled": scrolled || void 0, children: [
2312
- /* @__PURE__ */ jsx26("div", { className: "medo-site-header__logo", children: logo }),
2668
+ /* @__PURE__ */ jsx27("div", { className: "medo-site-header__logo", children: logo }),
2313
2669
  compact ? /* @__PURE__ */ jsxs25("div", { className: "medo-site-header__actions", children: [
2314
- primary && /* @__PURE__ */ jsx26(ActionLink, { action: primary, size: "sm" }),
2315
- /* @__PURE__ */ jsx26(NavFullscreen, { logo, actions, "aria-label": label, menuLabel, closeLabel, children })
2670
+ primary && /* @__PURE__ */ jsx27(ActionLink, { action: primary, size: "sm" }),
2671
+ /* @__PURE__ */ jsx27(NavFullscreen, { logo, actions, "aria-label": label, menuLabel, closeLabel, children })
2316
2672
  ] }) : /* @__PURE__ */ jsxs25(Fragment15, { children: [
2317
- /* @__PURE__ */ jsx26("nav", { "aria-label": label, className: "medo-site-header__nav", children: /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: "header", children: /* @__PURE__ */ jsx26("ul", { className: "medo-nav__list medo-nav__list--row", children }) }) }),
2318
- actions.length > 0 && /* @__PURE__ */ jsx26("div", { className: "medo-site-header__actions", children: actions.map((a) => /* @__PURE__ */ jsx26(ActionLink, { action: a, size: "md" }, a.label)) })
2673
+ /* @__PURE__ */ jsx27("nav", { "aria-label": label, className: "medo-site-header__nav", children: /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: "header", children: /* @__PURE__ */ jsx27("ul", { className: "medo-nav__list medo-nav__list--row", children }) }) }),
2674
+ actions.length > 0 && /* @__PURE__ */ jsx27("div", { className: "medo-site-header__actions", children: actions.map((a) => /* @__PURE__ */ jsx27(ActionLink, { action: a, size: "md" }, a.label)) })
2319
2675
  ] })
2320
2676
  ] });
2321
2677
  }
@@ -2329,24 +2685,24 @@ function NavFullscreen({
2329
2685
  }) {
2330
2686
  const ordered = [...actions].sort((a, b) => Number(b.variant === "primary") - Number(a.variant === "primary"));
2331
2687
  return /* @__PURE__ */ jsxs25(DialogTrigger3, { children: [
2332
- /* @__PURE__ */ jsx26(IconButton, { variant: "ghost", size: "md", icon: /* @__PURE__ */ jsx26(MenuIcon, {}), "aria-label": menuLabel, tooltip: false }),
2333
- /* @__PURE__ */ jsx26(ModalOverlay4, { className: "medo-nav-fullscreen-overlay", children: /* @__PURE__ */ jsx26(Modal4, { className: "medo-nav-fullscreen", children: /* @__PURE__ */ jsx26(AriaDialog4, { "aria-label": menuLabel, className: "medo-nav-fullscreen__dialog", children: ({ close }) => /* @__PURE__ */ jsxs25(Fragment15, { children: [
2688
+ /* @__PURE__ */ jsx27(IconButton, { variant: "ghost", size: "md", icon: /* @__PURE__ */ jsx27(MenuIcon, {}), "aria-label": menuLabel, tooltip: false }),
2689
+ /* @__PURE__ */ jsx27(ModalOverlay4, { className: "medo-nav-fullscreen-overlay", children: /* @__PURE__ */ jsx27(Modal4, { className: "medo-nav-fullscreen", children: /* @__PURE__ */ jsx27(AriaDialog4, { "aria-label": menuLabel, className: "medo-nav-fullscreen__dialog", children: ({ close }) => /* @__PURE__ */ jsxs25(Fragment15, { children: [
2334
2690
  /* @__PURE__ */ jsxs25("div", { className: "medo-nav-fullscreen__header", children: [
2335
- /* @__PURE__ */ jsx26("div", { className: "medo-site-header__logo", children: logo }),
2336
- /* @__PURE__ */ jsx26(IconButton, { variant: "ghost", size: "md", icon: /* @__PURE__ */ jsx26(X10, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
2691
+ /* @__PURE__ */ jsx27("div", { className: "medo-site-header__logo", children: logo }),
2692
+ /* @__PURE__ */ jsx27(IconButton, { variant: "ghost", size: "md", icon: /* @__PURE__ */ jsx27(X10, {}), "aria-label": closeLabel, tooltip: false, onPress: close })
2337
2693
  ] }),
2338
- /* @__PURE__ */ jsx26("nav", { "aria-label": label, className: "medo-nav-fullscreen__nav", children: /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: "sheet", children: /* @__PURE__ */ jsx26("ul", { className: "medo-nav__list", children }) }) }),
2339
- ordered.length > 0 && /* @__PURE__ */ jsx26("div", { className: "medo-nav-fullscreen__actions", children: ordered.map((a) => /* @__PURE__ */ jsx26(ActionLink, { action: a.variant === "ghost" || !a.variant ? { ...a, variant: "secondary" } : a, size: "lg" }, a.label)) })
2694
+ /* @__PURE__ */ jsx27("nav", { "aria-label": label, className: "medo-nav-fullscreen__nav", children: /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: "sheet", children: /* @__PURE__ */ jsx27("ul", { className: "medo-nav__list", children }) }) }),
2695
+ ordered.length > 0 && /* @__PURE__ */ jsx27("div", { className: "medo-nav-fullscreen__actions", children: ordered.map((a) => /* @__PURE__ */ jsx27(ActionLink, { action: a.variant === "ghost" || !a.variant ? { ...a, variant: "secondary" } : a, size: "lg" }, a.label)) })
2340
2696
  ] }) }) }) })
2341
2697
  ] });
2342
2698
  }
2343
2699
  function AppHeader({ title, headingLevel = 1, logo, search, actions }) {
2344
2700
  const scrolled = useScrolled();
2345
2701
  return /* @__PURE__ */ jsxs25("header", { className: "medo-app-header", "data-scrolled": scrolled || void 0, children: [
2346
- logo && /* @__PURE__ */ jsx26("div", { className: "medo-app-header__logo", children: logo }),
2347
- /* @__PURE__ */ jsx26(Heading5, { level: headingLevel, className: "medo-app-header__title", children: title }),
2348
- search && /* @__PURE__ */ jsx26("div", { className: "medo-app-header__search", children: search }),
2349
- actions && /* @__PURE__ */ jsx26("div", { className: "medo-app-header__actions", children: actions })
2702
+ logo && /* @__PURE__ */ jsx27("div", { className: "medo-app-header__logo", children: logo }),
2703
+ /* @__PURE__ */ jsx27(Heading5, { level: headingLevel, className: "medo-app-header__title", children: title }),
2704
+ search && /* @__PURE__ */ jsx27("div", { className: "medo-app-header__search", children: search }),
2705
+ actions && /* @__PURE__ */ jsx27("div", { className: "medo-app-header__actions", children: actions })
2350
2706
  ] });
2351
2707
  }
2352
2708
  function SideNav({
@@ -2357,11 +2713,16 @@ function SideNav({
2357
2713
  isCollapsed,
2358
2714
  defaultCollapsed = false,
2359
2715
  onCollapsedChange,
2360
- "aria-label": label = "App",
2361
- collapseLabel = "Collapse navigation",
2362
- expandLabel = "Expand navigation",
2363
- closeLabel = "Close"
2716
+ "aria-label": labelProp,
2717
+ collapseLabel: collapseLabelProp,
2718
+ expandLabel: expandLabelProp,
2719
+ closeLabel: closeLabelProp
2364
2720
  }) {
2721
+ const m = useMessages();
2722
+ const label = labelProp ?? m.navigation.app;
2723
+ const collapseLabel = collapseLabelProp ?? m.navigation.collapse;
2724
+ const expandLabel = expandLabelProp ?? m.navigation.expand;
2725
+ const closeLabel = closeLabelProp ?? m.common.close;
2365
2726
  const [ownCollapsed, setOwnCollapsed] = useState10(defaultCollapsed);
2366
2727
  const tablet = useMediaQuery(TABLET_QUERY);
2367
2728
  const [drawer, setDrawer] = useState10(false);
@@ -2380,12 +2741,12 @@ function SideNav({
2380
2741
  useEffect9(() => {
2381
2742
  if (!tablet) setDrawer(false);
2382
2743
  }, [tablet]);
2383
- const toggle = /* @__PURE__ */ jsx26(
2744
+ const toggle = /* @__PURE__ */ jsx27(
2384
2745
  IconButton,
2385
2746
  {
2386
2747
  variant: "ghost",
2387
2748
  size: "sm",
2388
- icon: /* @__PURE__ */ jsx26(PanelLeft, {}),
2749
+ icon: /* @__PURE__ */ jsx27(PanelLeft, {}),
2389
2750
  "aria-label": collapsed ? expandLabel : collapseLabel,
2390
2751
  "aria-expanded": tablet ? drawer : !collapsed,
2391
2752
  onPress: () => collapsed ? expand() : collapse()
@@ -2394,48 +2755,52 @@ function SideNav({
2394
2755
  return /* @__PURE__ */ jsxs25("aside", { className: cx("medo-sidenav", collapsed && "medo-sidenav--collapsed"), children: [
2395
2756
  /* @__PURE__ */ jsxs25("div", { className: "medo-sidenav__panel", children: [
2396
2757
  /* @__PURE__ */ jsxs25("div", { className: "medo-sidenav__top", children: [
2397
- /* @__PURE__ */ jsx26("div", { className: "medo-sidenav__logo", children: collapsed ? logoMark : logo }),
2758
+ /* @__PURE__ */ jsx27("div", { className: "medo-sidenav__logo", children: collapsed ? logoMark : logo }),
2398
2759
  !collapsed && toggle
2399
2760
  ] }),
2400
- /* @__PURE__ */ jsx26("nav", { "aria-label": label, className: "medo-sidenav__nav", children: /* @__PURE__ */ jsx26(SideNavContext.Provider, { value: { expand, openGroup }, children: /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: collapsed ? "rail" : "sidebar", children: /* @__PURE__ */ jsx26("ul", { className: "medo-nav__list", children }) }) }) }),
2761
+ /* @__PURE__ */ jsx27("nav", { "aria-label": label, className: "medo-sidenav__nav", children: /* @__PURE__ */ jsx27(SideNavContext.Provider, { value: { expand, openGroup }, children: /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: collapsed ? "rail" : "sidebar", children: /* @__PURE__ */ jsx27("ul", { className: "medo-nav__list", children }) }) }) }),
2401
2762
  /* @__PURE__ */ jsxs25("div", { className: "medo-sidenav__bottom", children: [
2402
2763
  collapsed && toggle,
2403
2764
  user && /* @__PURE__ */ jsxs25("div", { className: "medo-sidenav__user", children: [
2404
- /* @__PURE__ */ jsx26(Avatar, { name: user.name, src: user.src, size: "md", decorative: !collapsed }),
2765
+ /* @__PURE__ */ jsx27(Avatar, { name: user.name, src: user.src, size: "md", decorative: !collapsed }),
2405
2766
  !collapsed && /* @__PURE__ */ jsxs25("span", { className: "medo-sidenav__user-text", children: [
2406
- /* @__PURE__ */ jsx26("span", { className: "medo-sidenav__user-name", children: user.name }),
2407
- user.email && /* @__PURE__ */ jsx26("span", { className: "medo-sidenav__user-email", children: user.email })
2767
+ /* @__PURE__ */ jsx27("span", { className: "medo-sidenav__user-name", children: user.name }),
2768
+ user.email && /* @__PURE__ */ jsx27("span", { className: "medo-sidenav__user-email", children: user.email })
2408
2769
  ] })
2409
2770
  ] })
2410
2771
  ] })
2411
2772
  ] }),
2412
2773
  tablet && // Tablet: the full navigation as a Drawer on the left. Choosing a page closes it.
2413
- /* @__PURE__ */ jsx26(Drawer, { side: "left", size: "sm", title: logo, "aria-label": label, closeLabel, isOpen: drawer, onOpenChange: setDrawer, children: /* @__PURE__ */ jsx26("nav", { "aria-label": label, children: /* @__PURE__ */ jsx26(SideNavContext.Provider, { value: { expand, openGroup, onNavigate: () => setDrawer(false) }, children: /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: "sidebar", children: /* @__PURE__ */ jsx26("ul", { className: "medo-nav__list", children }) }) }) }) })
2774
+ /* @__PURE__ */ jsx27(Drawer, { side: "left", size: "sm", title: logo, "aria-label": label, closeLabel, isOpen: drawer, onOpenChange: setDrawer, children: /* @__PURE__ */ jsx27("nav", { "aria-label": label, children: /* @__PURE__ */ jsx27(SideNavContext.Provider, { value: { expand, openGroup, onNavigate: () => setDrawer(false) }, children: /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: "sidebar", children: /* @__PURE__ */ jsx27("ul", { className: "medo-nav__list", children }) }) }) }) })
2414
2775
  ] });
2415
2776
  }
2416
- function BottomTabBar({ children, "aria-label": label = "App", display = "mobile" }) {
2417
- return /* @__PURE__ */ jsx26("nav", { "aria-label": label, className: cx("medo-tab-bar", display === "always" && "medo-tab-bar--always"), children: /* @__PURE__ */ jsx26("ul", { className: "medo-tab-bar__list", children }) });
2777
+ function BottomTabBar({ children, "aria-label": labelProp, display = "mobile" }) {
2778
+ const m = useMessages();
2779
+ const label = labelProp ?? m.navigation.app;
2780
+ return /* @__PURE__ */ jsx27("nav", { "aria-label": label, className: cx("medo-tab-bar", display === "always" && "medo-tab-bar--always"), children: /* @__PURE__ */ jsx27("ul", { className: "medo-tab-bar__list", children }) });
2418
2781
  }
2419
2782
  function TabBarItem({ children, icon, isCurrent, dot, dotLabel = "new", ...props }) {
2420
- return /* @__PURE__ */ jsx26("li", { className: "medo-tab-bar__entry", children: /* @__PURE__ */ jsxs25(AriaLink3, { ...props, "aria-current": isCurrent ? "page" : void 0, className: "medo-tab-bar-item", children: [
2421
- /* @__PURE__ */ jsx26(TabBarIcon, { icon, dot, dotLabel }),
2422
- /* @__PURE__ */ jsx26("span", { className: "medo-tab-bar-item__label", children })
2783
+ return /* @__PURE__ */ jsx27("li", { className: "medo-tab-bar__entry", children: /* @__PURE__ */ jsxs25(AriaLink3, { ...props, "aria-current": isCurrent ? "page" : void 0, className: "medo-tab-bar-item", children: [
2784
+ /* @__PURE__ */ jsx27(TabBarIcon, { icon, dot, dotLabel }),
2785
+ /* @__PURE__ */ jsx27("span", { className: "medo-tab-bar-item__label", children })
2423
2786
  ] }) });
2424
2787
  }
2425
2788
  function TabBarIcon({ icon, dot, dotLabel }) {
2426
2789
  return /* @__PURE__ */ jsxs25("span", { className: "medo-tab-bar-item__indicator", children: [
2427
- /* @__PURE__ */ jsx26("span", { className: "medo-tab-bar-item__icon", "aria-hidden": "true", children: icon }),
2428
- dot && /* @__PURE__ */ jsx26(BadgeDot, { tone: "danger", label: dotLabel, className: "medo-tab-bar-item__dot" })
2790
+ /* @__PURE__ */ jsx27("span", { className: "medo-tab-bar-item__icon", "aria-hidden": "true", children: icon }),
2791
+ dot && /* @__PURE__ */ jsx27(BadgeDot, { tone: "danger", label: dotLabel, className: "medo-tab-bar-item__dot" })
2429
2792
  ] });
2430
2793
  }
2431
- function TabBarMore({ label = "More", children, closeLabel }) {
2794
+ function TabBarMore({ label: labelProp, children, closeLabel }) {
2795
+ const m = useMessages();
2796
+ const label = labelProp ?? m.common.more;
2432
2797
  const hasCurrent = containsCurrent(children);
2433
- return /* @__PURE__ */ jsx26("li", { className: "medo-tab-bar__entry", children: /* @__PURE__ */ jsxs25(DialogTrigger3, { children: [
2798
+ return /* @__PURE__ */ jsx27("li", { className: "medo-tab-bar__entry", children: /* @__PURE__ */ jsxs25(DialogTrigger3, { children: [
2434
2799
  /* @__PURE__ */ jsxs25(AriaButton8, { className: "medo-tab-bar-item", "aria-haspopup": "dialog", "data-current": hasCurrent || void 0, children: [
2435
- /* @__PURE__ */ jsx26(TabBarIcon, { icon: /* @__PURE__ */ jsx26(Ellipsis2, {}) }),
2436
- /* @__PURE__ */ jsx26("span", { className: "medo-tab-bar-item__label", children: label })
2800
+ /* @__PURE__ */ jsx27(TabBarIcon, { icon: /* @__PURE__ */ jsx27(Ellipsis2, {}) }),
2801
+ /* @__PURE__ */ jsx27("span", { className: "medo-tab-bar-item__label", children: label })
2437
2802
  ] }),
2438
- /* @__PURE__ */ jsx26(BottomSheet, { title: label, closeLabel, children: /* @__PURE__ */ jsx26("nav", { "aria-label": label, className: "medo-nav-sheet", children: /* @__PURE__ */ jsx26(NavVariantContext.Provider, { value: "sheet", children: /* @__PURE__ */ jsx26("ul", { className: "medo-nav__list", children }) }) }) })
2803
+ /* @__PURE__ */ jsx27(BottomSheet, { title: label, closeLabel, children: /* @__PURE__ */ jsx27("nav", { "aria-label": label, className: "medo-nav-sheet", children: /* @__PURE__ */ jsx27(NavVariantContext.Provider, { value: "sheet", children: /* @__PURE__ */ jsx27("ul", { className: "medo-nav__list", children }) }) }) })
2439
2804
  ] }) });
2440
2805
  }
2441
2806
  function useScrolled() {
@@ -2450,14 +2815,14 @@ function useScrolled() {
2450
2815
  }
2451
2816
 
2452
2817
  // src/list/List.tsx
2453
- import { createContext as createContext8, useContext as useContext15 } from "react";
2818
+ import { createContext as createContext9, useContext as useContext16 } from "react";
2454
2819
  import { Check as Check5, X as X11 } from "lucide-react";
2455
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
2456
- var ListTypeContext = createContext8("bullet");
2820
+ import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
2821
+ var ListTypeContext = createContext9("bullet");
2457
2822
  function List({ type = "bullet", size, start, className, style, children, ...props }) {
2458
2823
  const Tag2 = type === "number" ? "ol" : "ul";
2459
2824
  const counter = type === "number" && start !== void 0 ? { counterReset: `medo-list ${start - 1}` } : void 0;
2460
- return /* @__PURE__ */ jsx27(ListTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx27(
2825
+ return /* @__PURE__ */ jsx28(ListTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx28(
2461
2826
  Tag2,
2462
2827
  {
2463
2828
  ...props,
@@ -2469,66 +2834,68 @@ function List({ type = "bullet", size, start, className, style, children, ...pro
2469
2834
  }
2470
2835
  ) });
2471
2836
  }
2472
- function ListItem({ children, excluded, excludedLabel = "Not included:", className, ...props }) {
2473
- const type = useContext15(ListTypeContext);
2837
+ function ListItem({ children, excluded, excludedLabel, className, ...props }) {
2838
+ const m = useMessages();
2839
+ const type = useContext16(ListTypeContext);
2474
2840
  const check = type === "check";
2475
2841
  return /* @__PURE__ */ jsxs26("li", { ...props, className: cx("medo-list__item", check && excluded && "medo-list__item--excluded", className), children: [
2476
- check && /* @__PURE__ */ jsx27("span", { className: "medo-list__icon", "aria-hidden": "true", children: excluded ? /* @__PURE__ */ jsx27(X11, {}) : /* @__PURE__ */ jsx27(Check5, {}) }),
2842
+ check && /* @__PURE__ */ jsx28("span", { className: "medo-list__icon", "aria-hidden": "true", children: excluded ? /* @__PURE__ */ jsx28(X11, {}) : /* @__PURE__ */ jsx28(Check5, {}) }),
2477
2843
  check && excluded && /* @__PURE__ */ jsxs26("span", { className: "medo-visually-hidden", children: [
2478
- excludedLabel,
2844
+ excludedLabel ?? m.list.notIncluded,
2479
2845
  " "
2480
2846
  ] }),
2481
2847
  children
2482
2848
  ] });
2483
2849
  }
2484
2850
  function DescriptionList({ layout = "auto", className, children, ...props }) {
2485
- return /* @__PURE__ */ jsx27("dl", { ...props, className: cx("medo-dl", `medo-dl--${layout}`, className), children });
2851
+ return /* @__PURE__ */ jsx28("dl", { ...props, className: cx("medo-dl", `medo-dl--${layout}`, className), children });
2486
2852
  }
2487
2853
  function DescriptionItem({ term, children }) {
2488
2854
  return /* @__PURE__ */ jsxs26("div", { className: "medo-dl__row", children: [
2489
- /* @__PURE__ */ jsx27("dt", { className: "medo-dl__term", children: term }),
2490
- /* @__PURE__ */ jsx27("dd", { className: "medo-dl__value", children })
2855
+ /* @__PURE__ */ jsx28("dt", { className: "medo-dl__term", children: term }),
2856
+ /* @__PURE__ */ jsx28("dd", { className: "medo-dl__value", children })
2491
2857
  ] });
2492
2858
  }
2493
2859
 
2494
2860
  // src/list-view/ListView.tsx
2495
2861
  import { useEffect as useEffect10, useRef as useRef11, useState as useState11 } from "react";
2496
- import { GridList, GridListItem, useLocale } from "react-aria-components";
2862
+ import { GridList, GridListItem, useLocale as useLocale2 } from "react-aria-components";
2497
2863
  import { ChevronRight as ChevronRight2 } from "lucide-react";
2498
- import { Fragment as Fragment16, jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
2864
+ import { Fragment as Fragment16, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
2499
2865
  function ListView({ variant = "plain", isLoading = false, emptyState, className, children, items, ...props }) {
2500
2866
  if (isLoading) {
2501
- return /* @__PURE__ */ jsx28("div", { role: "list", "aria-busy": "true", "aria-label": props["aria-label"], className: cx("medo-list-view", `medo-list-view--${variant}`, className), children: Array.from(
2867
+ return /* @__PURE__ */ jsx29("div", { role: "list", "aria-busy": "true", "aria-label": props["aria-label"], className: cx("medo-list-view", `medo-list-view--${variant}`, className), children: Array.from(
2502
2868
  { length: 3 },
2503
- (_, i) => variant === "cards" ? /* @__PURE__ */ jsx28("div", { role: "listitem", className: "medo-list-card medo-list-card--loading", children: /* @__PURE__ */ jsxs27("span", { className: "medo-list-card__content", children: [
2504
- /* @__PURE__ */ jsx28(Skeleton, { width: "50%" }),
2505
- /* @__PURE__ */ jsx28(Skeleton, { width: "35%" }),
2506
- /* @__PURE__ */ jsx28(Skeleton, { width: "70%" })
2869
+ (_, i) => variant === "cards" ? /* @__PURE__ */ jsx29("div", { role: "listitem", className: "medo-list-card medo-list-card--loading", children: /* @__PURE__ */ jsxs27("span", { className: "medo-list-card__content", children: [
2870
+ /* @__PURE__ */ jsx29(Skeleton, { width: "50%" }),
2871
+ /* @__PURE__ */ jsx29(Skeleton, { width: "35%" }),
2872
+ /* @__PURE__ */ jsx29(Skeleton, { width: "70%" })
2507
2873
  ] }) }, i) : /* @__PURE__ */ jsxs27("div", { role: "listitem", className: "medo-list-row medo-list-row--loading", children: [
2508
- /* @__PURE__ */ jsx28("span", { className: "medo-list-row__leading", children: /* @__PURE__ */ jsx28(Skeleton, { shape: "circle", width: 40, height: 40 }) }),
2509
- /* @__PURE__ */ jsx28("span", { className: "medo-list-row__main", children: /* @__PURE__ */ jsxs27("span", { className: "medo-list-row__content", children: [
2510
- /* @__PURE__ */ jsx28(Skeleton, { width: "40%" }),
2511
- /* @__PURE__ */ jsx28(Skeleton, { width: "70%" })
2874
+ /* @__PURE__ */ jsx29("span", { className: "medo-list-row__leading", children: /* @__PURE__ */ jsx29(Skeleton, { shape: "circle", width: 40, height: 40 }) }),
2875
+ /* @__PURE__ */ jsx29("span", { className: "medo-list-row__main", children: /* @__PURE__ */ jsxs27("span", { className: "medo-list-row__content", children: [
2876
+ /* @__PURE__ */ jsx29(Skeleton, { width: "40%" }),
2877
+ /* @__PURE__ */ jsx29(Skeleton, { width: "70%" })
2512
2878
  ] }) })
2513
2879
  ] }, i)
2514
2880
  ) });
2515
2881
  }
2516
- return /* @__PURE__ */ jsx28(
2882
+ return /* @__PURE__ */ jsx29(
2517
2883
  GridList,
2518
2884
  {
2519
2885
  ...props,
2520
2886
  items,
2521
2887
  keyboardNavigationBehavior: "tab",
2522
- renderEmptyState: emptyState ? () => /* @__PURE__ */ jsx28("div", { className: "medo-list-view__empty", children: emptyState }) : void 0,
2888
+ renderEmptyState: emptyState ? () => /* @__PURE__ */ jsx29("div", { className: "medo-list-view__empty", children: emptyState }) : void 0,
2523
2889
  className: cx("medo-list-view", `medo-list-view--${variant}`, className),
2524
2890
  children
2525
2891
  }
2526
2892
  );
2527
2893
  }
2528
- function ListRow({ title, description, lines, leading, meta, trailing, chevron, unread, unreadLabel = "Unread", swipeActions, ...props }) {
2894
+ function ListRow({ title, description, lines, leading, meta, trailing, chevron, unread, unreadLabel, swipeActions, ...props }) {
2895
+ const m = useMessages();
2529
2896
  const rowLines = description ? lines ?? 2 : 1;
2530
2897
  const swipe = swipeActions?.start || swipeActions?.end;
2531
- return /* @__PURE__ */ jsx28(
2898
+ return /* @__PURE__ */ jsx29(
2532
2899
  GridListItem,
2533
2900
  {
2534
2901
  ...props,
@@ -2536,29 +2903,29 @@ function ListRow({ title, description, lines, leading, meta, trailing, chevron,
2536
2903
  className: cx("medo-list-row", `medo-list-row--lines-${rowLines}`, unread && "medo-list-row--unread", swipe && "medo-list-row--swipe"),
2537
2904
  children: ({ selectionMode }) => {
2538
2905
  const content = /* @__PURE__ */ jsxs27(Fragment16, { children: [
2539
- selectionMode !== "none" && /* @__PURE__ */ jsx28("span", { className: "medo-list-row__check", children: /* @__PURE__ */ jsx28(Checkbox, { slot: "selection" }) }),
2906
+ selectionMode !== "none" && /* @__PURE__ */ jsx29("span", { className: "medo-list-row__check", children: /* @__PURE__ */ jsx29(Checkbox, { slot: "selection" }) }),
2540
2907
  leading && // Avatars size themselves: sm in 1-line rows, lg in 2–3 lines.
2541
- /* @__PURE__ */ jsx28(AvatarSizeContext.Provider, { value: rowLines === 1 ? "sm" : "lg", children: /* @__PURE__ */ jsx28("span", { className: "medo-list-row__leading", children: leading }) }),
2908
+ /* @__PURE__ */ jsx29(AvatarSizeContext.Provider, { value: rowLines === 1 ? "sm" : "lg", children: /* @__PURE__ */ jsx29("span", { className: "medo-list-row__leading", children: leading }) }),
2542
2909
  /* @__PURE__ */ jsxs27("span", { className: "medo-list-row__main", children: [
2543
2910
  /* @__PURE__ */ jsxs27("span", { className: "medo-list-row__content", children: [
2544
2911
  /* @__PURE__ */ jsxs27("span", { className: "medo-list-row__title", children: [
2545
2912
  unread && /* @__PURE__ */ jsxs27("span", { className: "medo-visually-hidden", children: [
2546
- unreadLabel,
2913
+ unreadLabel ?? m.listView.unread,
2547
2914
  ": "
2548
2915
  ] }),
2549
2916
  title
2550
2917
  ] }),
2551
- description && /* @__PURE__ */ jsx28("span", { className: "medo-list-row__description", children: description })
2918
+ description && /* @__PURE__ */ jsx29("span", { className: "medo-list-row__description", children: description })
2552
2919
  ] }),
2553
2920
  (meta || unread) && /* @__PURE__ */ jsxs27("span", { className: "medo-list-row__meta", children: [
2554
- meta && /* @__PURE__ */ jsx28("span", { className: "medo-list-row__meta-text", children: meta }),
2555
- unread && /* @__PURE__ */ jsx28("span", { className: "medo-list-row__dot", "aria-hidden": "true" })
2921
+ meta && /* @__PURE__ */ jsx29("span", { className: "medo-list-row__meta-text", children: meta }),
2922
+ unread && /* @__PURE__ */ jsx29("span", { className: "medo-list-row__dot", "aria-hidden": "true" })
2556
2923
  ] }),
2557
- trailing && /* @__PURE__ */ jsx28("span", { className: "medo-list-row__trailing", children: trailing }),
2558
- chevron && /* @__PURE__ */ jsx28("span", { className: "medo-list-row__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx28(ChevronRight2, {}) })
2924
+ trailing && /* @__PURE__ */ jsx29("span", { className: "medo-list-row__trailing", children: trailing }),
2925
+ chevron && /* @__PURE__ */ jsx29("span", { className: "medo-list-row__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx29(ChevronRight2, {}) })
2559
2926
  ] })
2560
2927
  ] });
2561
- return swipe ? /* @__PURE__ */ jsx28(Swipeable, { actions: swipeActions, children: content }) : content;
2928
+ return swipe ? /* @__PURE__ */ jsx29(Swipeable, { actions: swipeActions, children: content }) : content;
2562
2929
  }
2563
2930
  }
2564
2931
  );
@@ -2575,7 +2942,7 @@ var SWIPE = {
2575
2942
  };
2576
2943
  var closeOpenRow = null;
2577
2944
  function Swipeable({ actions, children }) {
2578
- const { direction } = useLocale();
2945
+ const { direction } = useLocale2();
2579
2946
  const rtl = direction === "rtl";
2580
2947
  const surface = useRef11(null);
2581
2948
  const drag = useRef11(null);
@@ -2653,8 +3020,8 @@ function Swipeable({ actions, children }) {
2653
3020
  };
2654
3021
  const revealed = actionFor(offset);
2655
3022
  return /* @__PURE__ */ jsxs27(Fragment16, { children: [
2656
- revealed && // Visual shortcut for touch; keyboard and screen readers use the „…“ menu, so it is hidden from them.
2657
- /* @__PURE__ */ jsx28(
3023
+ revealed && // Visual shortcut for touch; keyboard and screen readers use the “…” menu, so it is hidden from them.
3024
+ /* @__PURE__ */ jsx29(
2658
3025
  "span",
2659
3026
  {
2660
3027
  className: cx(
@@ -2690,7 +3057,7 @@ function Swipeable({ actions, children }) {
2690
3057
  },
2691
3058
  children: [
2692
3059
  children,
2693
- open && /* @__PURE__ */ jsx28(
3060
+ open && /* @__PURE__ */ jsx29(
2694
3061
  "span",
2695
3062
  {
2696
3063
  className: "medo-list-row__swipe-shield",
@@ -2707,19 +3074,19 @@ function Swipeable({ actions, children }) {
2707
3074
  ] });
2708
3075
  }
2709
3076
  function ListRowIcon({ children }) {
2710
- return /* @__PURE__ */ jsx28("span", { className: "medo-list-row__icon", "aria-hidden": "true", children });
3077
+ return /* @__PURE__ */ jsx29("span", { className: "medo-list-row__icon", "aria-hidden": "true", children });
2711
3078
  }
2712
3079
  function ListCard({ title, amount, description, meta, status, ...props }) {
2713
- return /* @__PURE__ */ jsx28(GridListItem, { ...props, textValue: title, className: "medo-list-card", children: ({ selectionMode }) => /* @__PURE__ */ jsxs27(Fragment16, { children: [
2714
- selectionMode !== "none" && /* @__PURE__ */ jsx28("span", { className: "medo-list-card__check", children: /* @__PURE__ */ jsx28(Checkbox, { slot: "selection", size: "lg" }) }),
3080
+ return /* @__PURE__ */ jsx29(GridListItem, { ...props, textValue: title, className: "medo-list-card", children: ({ selectionMode }) => /* @__PURE__ */ jsxs27(Fragment16, { children: [
3081
+ selectionMode !== "none" && /* @__PURE__ */ jsx29("span", { className: "medo-list-card__check", children: /* @__PURE__ */ jsx29(Checkbox, { slot: "selection", size: "lg" }) }),
2715
3082
  /* @__PURE__ */ jsxs27("span", { className: "medo-list-card__content", children: [
2716
3083
  /* @__PURE__ */ jsxs27("span", { className: "medo-list-card__top", children: [
2717
- /* @__PURE__ */ jsx28("span", { className: "medo-list-card__title", children: title }),
2718
- amount && /* @__PURE__ */ jsx28("span", { className: "medo-list-card__amount", children: amount })
3084
+ /* @__PURE__ */ jsx29("span", { className: "medo-list-card__title", children: title }),
3085
+ amount && /* @__PURE__ */ jsx29("span", { className: "medo-list-card__amount", children: amount })
2719
3086
  ] }),
2720
- description && /* @__PURE__ */ jsx28(AvatarSizeContext.Provider, { value: "xs", children: /* @__PURE__ */ jsx28("span", { className: "medo-list-card__description", children: description }) }),
3087
+ description && /* @__PURE__ */ jsx29(AvatarSizeContext.Provider, { value: "xs", children: /* @__PURE__ */ jsx29("span", { className: "medo-list-card__description", children: description }) }),
2721
3088
  (meta || status) && /* @__PURE__ */ jsxs27("span", { className: "medo-list-card__bottom", children: [
2722
- /* @__PURE__ */ jsx28("span", { className: "medo-list-card__meta", children: meta }),
3089
+ /* @__PURE__ */ jsx29("span", { className: "medo-list-card__meta", children: meta }),
2723
3090
  status
2724
3091
  ] })
2725
3092
  ] })
@@ -2730,18 +3097,23 @@ function ListCard({ title, amount, description, meta, status, ...props }) {
2730
3097
  import { useEffect as useEffect11, useRef as useRef12 } from "react";
2731
3098
  import { Button as AriaButton9, Toolbar as Toolbar2 } from "react-aria-components";
2732
3099
  import { Ellipsis as Ellipsis3, X as X12 } from "lucide-react";
2733
- import { Fragment as Fragment17, jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
3100
+ import { Fragment as Fragment17, jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
2734
3101
  function BulkActionBar({
2735
3102
  count,
2736
3103
  actions,
2737
3104
  onClear,
2738
3105
  variant = "auto",
2739
- countLabel = (n) => `${n} selected`,
2740
- clearLabel = "Clear selection",
2741
- moreLabel = "More actions",
2742
- "aria-label": ariaLabel = "Bulk actions",
3106
+ countLabel: countLabelProp,
3107
+ clearLabel: clearLabelProp,
3108
+ moreLabel: moreLabelProp,
3109
+ "aria-label": ariaLabelProp,
2743
3110
  className
2744
3111
  }) {
3112
+ const m = useMessages();
3113
+ const countLabel = countLabelProp ?? m.bulkActionBar.count;
3114
+ const clearLabel = clearLabelProp ?? m.bulkActionBar.clear;
3115
+ const moreLabel = moreLabelProp ?? m.bulkActionBar.more;
3116
+ const ariaLabel = ariaLabelProp ?? m.bulkActionBar.label;
2745
3117
  const mobile = useMediaQuery(MOBILE_QUERY);
2746
3118
  const isMobile = variant === "mobile" || variant === "auto" && mobile;
2747
3119
  const visible = count > 0;
@@ -2752,8 +3124,9 @@ function BulkActionBar({
2752
3124
  focusInside.current = false;
2753
3125
  if (returnTo.current?.isConnected) returnTo.current.focus();
2754
3126
  }, [visible]);
2755
- const shown = actions.slice(0, 3);
2756
- const more = actions.slice(3);
3127
+ const max = isMobile ? actions.length > 2 ? 1 : 2 : 3;
3128
+ const shown = actions.slice(0, max);
3129
+ const more = actions.slice(max);
2757
3130
  const onKeyDown = (e) => {
2758
3131
  if (e.key === "Escape" && !e.defaultPrevented) {
2759
3132
  e.preventDefault();
@@ -2761,16 +3134,16 @@ function BulkActionBar({
2761
3134
  }
2762
3135
  };
2763
3136
  const overflow = more.length > 0 && (isMobile ? /* @__PURE__ */ jsxs28(MenuTrigger, { children: [
2764
- /* @__PURE__ */ jsx29(MenuButton, { "aria-label": moreLabel, size: "lg" }),
2765
- /* @__PURE__ */ jsx29(OverflowMenu, { actions: more })
3137
+ /* @__PURE__ */ jsx30(MenuButton, { "aria-label": moreLabel, size: "lg" }),
3138
+ /* @__PURE__ */ jsx30(OverflowMenu, { actions: more })
2766
3139
  ] }) : /* @__PURE__ */ jsxs28(MenuTrigger, { children: [
2767
- /* @__PURE__ */ jsx29(AriaButton9, { "aria-label": moreLabel, className: "medo-toast__button medo-toast__close", children: /* @__PURE__ */ jsx29(Ellipsis3, { "aria-hidden": "true" }) }),
2768
- /* @__PURE__ */ jsx29(OverflowMenu, { actions: more })
3140
+ /* @__PURE__ */ jsx30(AriaButton9, { "aria-label": moreLabel, className: "medo-toast__button medo-toast__close", children: /* @__PURE__ */ jsx30(Ellipsis3, { "aria-hidden": "true" }) }),
3141
+ /* @__PURE__ */ jsx30(OverflowMenu, { actions: more })
2769
3142
  ] }));
2770
3143
  return /* @__PURE__ */ jsxs28(Fragment17, { children: [
2771
- /* @__PURE__ */ jsx29("span", { role: "status", className: "medo-visually-hidden", children: visible ? countLabel(count) : "" }),
3144
+ /* @__PURE__ */ jsx30("span", { role: "status", className: "medo-visually-hidden", children: visible ? countLabel(count) : "" }),
2772
3145
  visible && // The wrapper handles Esc and remembers where focus came from (events bubble from the toolbar).
2773
- /* @__PURE__ */ jsx29(
3146
+ /* @__PURE__ */ jsx30(
2774
3147
  "div",
2775
3148
  {
2776
3149
  className: "medo-bulk-bar-host",
@@ -2783,41 +3156,41 @@ function BulkActionBar({
2783
3156
  onBlur: (e) => {
2784
3157
  if (!e.currentTarget.contains(e.relatedTarget)) focusInside.current = false;
2785
3158
  },
2786
- children: /* @__PURE__ */ jsx29(Toolbar2, { "aria-label": ariaLabel, className: cx("medo-bulk-bar", isMobile ? "medo-bulk-bar--mobile" : "medo-bulk-bar--desktop", className), children: isMobile ? /* @__PURE__ */ jsxs28(Fragment17, { children: [
3159
+ children: /* @__PURE__ */ jsx30(Toolbar2, { "aria-label": ariaLabel, className: cx("medo-bulk-bar", isMobile ? "medo-bulk-bar--mobile" : "medo-bulk-bar--desktop", className), children: isMobile ? /* @__PURE__ */ jsxs28(Fragment17, { children: [
2787
3160
  /* @__PURE__ */ jsxs28("span", { className: "medo-bulk-bar__start", children: [
2788
- /* @__PURE__ */ jsx29(IconButton, { variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx29(X12, {}), "aria-label": clearLabel, tooltip: false, onPress: onClear }),
2789
- /* @__PURE__ */ jsx29("span", { className: "medo-bulk-bar__count", children: countLabel(count) })
3161
+ /* @__PURE__ */ jsx30(IconButton, { variant: "ghost", size: "lg", icon: /* @__PURE__ */ jsx30(X12, {}), "aria-label": clearLabel, tooltip: false, onPress: onClear }),
3162
+ /* @__PURE__ */ jsx30("span", { className: "medo-bulk-bar__count", children: countLabel(count) })
2790
3163
  ] }),
2791
3164
  /* @__PURE__ */ jsxs28("span", { className: "medo-bulk-bar__actions", children: [
2792
- shown.map((a) => /* @__PURE__ */ jsx29(Button, { variant: a.variant === "danger" ? "ghost-danger" : "ghost", size: "lg", onPress: a.onAction, children: a.label }, a.label)),
3165
+ shown.map((a) => /* @__PURE__ */ jsx30(Button, { variant: a.variant === "danger" ? "ghost-danger" : "ghost", size: "lg", onPress: a.onAction, children: a.label }, a.label)),
2793
3166
  overflow
2794
3167
  ] })
2795
3168
  ] }) : /* @__PURE__ */ jsxs28(Fragment17, { children: [
2796
- /* @__PURE__ */ jsx29("span", { className: "medo-bulk-bar__count", children: countLabel(count) }),
2797
- /* @__PURE__ */ jsx29("span", { className: "medo-bulk-bar__divider", "aria-hidden": "true" }),
2798
- shown.map((a) => /* @__PURE__ */ jsx29(AriaButton9, { className: "medo-toast__button medo-toast__action", onPress: a.onAction, children: a.label }, a.label)),
3169
+ /* @__PURE__ */ jsx30("span", { className: "medo-bulk-bar__count", children: countLabel(count) }),
3170
+ /* @__PURE__ */ jsx30("span", { className: "medo-bulk-bar__divider", "aria-hidden": "true" }),
3171
+ shown.map((a) => /* @__PURE__ */ jsx30(AriaButton9, { className: "medo-toast__button medo-toast__action", onPress: a.onAction, children: a.label }, a.label)),
2799
3172
  overflow,
2800
- /* @__PURE__ */ jsx29("span", { className: "medo-bulk-bar__divider", "aria-hidden": "true" }),
2801
- /* @__PURE__ */ jsx29(AriaButton9, { "aria-label": clearLabel, className: "medo-toast__button medo-toast__close", onPress: onClear, children: /* @__PURE__ */ jsx29(X12, { "aria-hidden": "true" }) })
3173
+ /* @__PURE__ */ jsx30("span", { className: "medo-bulk-bar__divider", "aria-hidden": "true" }),
3174
+ /* @__PURE__ */ jsx30(AriaButton9, { "aria-label": clearLabel, className: "medo-toast__button medo-toast__close", onPress: onClear, children: /* @__PURE__ */ jsx30(X12, { "aria-hidden": "true" }) })
2802
3175
  ] }) })
2803
3176
  }
2804
3177
  )
2805
3178
  ] });
2806
3179
  }
2807
3180
  function OverflowMenu({ actions }) {
2808
- return /* @__PURE__ */ jsx29(Menu, { onAction: (key) => actions[Number(key)]?.onAction(), children: actions.map((a, i) => /* @__PURE__ */ jsx29(MenuItem, { id: i, icon: a.icon, variant: a.variant === "danger" ? "danger" : "default", children: a.label }, i)) });
3181
+ return /* @__PURE__ */ jsx30(Menu, { onAction: (key) => actions[Number(key)]?.onAction(), children: actions.map((a, i) => /* @__PURE__ */ jsx30(MenuItem, { id: i, icon: a.icon, variant: a.variant === "danger" ? "danger" : "default", children: a.label }, i)) });
2809
3182
  }
2810
3183
 
2811
3184
  // src/empty-state/EmptyState.tsx
2812
3185
  import { useId as useId6 } from "react";
2813
3186
  import { CircleAlert as CircleAlert4, CircleCheck, Folder, Lock, Search as Search2 } from "lucide-react";
2814
- import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
3187
+ import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
2815
3188
  var defaults = {
2816
- "first-use": { icon: /* @__PURE__ */ jsx30(Folder, {}), tone: "neutral" },
2817
- "no-results": { icon: /* @__PURE__ */ jsx30(Search2, {}), tone: "neutral" },
2818
- error: { icon: /* @__PURE__ */ jsx30(CircleAlert4, {}), tone: "danger" },
2819
- "no-access": { icon: /* @__PURE__ */ jsx30(Lock, {}), tone: "neutral" },
2820
- "all-done": { icon: /* @__PURE__ */ jsx30(CircleCheck, {}), tone: "success" }
3189
+ "first-use": { icon: /* @__PURE__ */ jsx31(Folder, {}), tone: "neutral" },
3190
+ "no-results": { icon: /* @__PURE__ */ jsx31(Search2, {}), tone: "neutral" },
3191
+ error: { icon: /* @__PURE__ */ jsx31(CircleAlert4, {}), tone: "danger" },
3192
+ "no-access": { icon: /* @__PURE__ */ jsx31(Lock, {}), tone: "neutral" },
3193
+ "all-done": { icon: /* @__PURE__ */ jsx31(CircleCheck, {}), tone: "success" }
2821
3194
  };
2822
3195
  var tileSize = { page: "lg", section: "md", inline: "sm" };
2823
3196
  function EmptyState({
@@ -2840,26 +3213,26 @@ function EmptyState({
2840
3213
  const Title = isInline ? "p" : `h${headingLevel ?? (size === "page" ? 2 : 3)}`;
2841
3214
  const buttonSize = size === "page" ? "md" : "sm";
2842
3215
  return /* @__PURE__ */ jsxs29(Tag2, { ...props, "aria-labelledby": isInline ? void 0 : titleId, className: cx("medo-empty-state", `medo-empty-state--${size}`, className), children: [
2843
- illustration ? /* @__PURE__ */ jsx30("span", { className: "medo-empty-state__illustration", "aria-hidden": "true", children: illustration }) : /* @__PURE__ */ jsx30(IconTile, { size: tileSize[size], tone, children: icon ?? defaultIcon }),
3216
+ illustration ? /* @__PURE__ */ jsx31("span", { className: "medo-empty-state__illustration", "aria-hidden": "true", children: illustration }) : /* @__PURE__ */ jsx31(IconTile, { size: tileSize[size], tone, children: icon ?? defaultIcon }),
2844
3217
  /* @__PURE__ */ jsxs29("div", { className: "medo-empty-state__content", role: type === "no-results" ? "status" : void 0, children: [
2845
- /* @__PURE__ */ jsx30(Title, { id: titleId, className: "medo-empty-state__title", children: title }),
2846
- description && /* @__PURE__ */ jsx30("p", { className: "medo-empty-state__description", children: description })
3218
+ /* @__PURE__ */ jsx31(Title, { id: titleId, className: "medo-empty-state__title", children: title }),
3219
+ description && /* @__PURE__ */ jsx31("p", { className: "medo-empty-state__description", children: description })
2847
3220
  ] }),
2848
3221
  (action || secondaryAction) && /* @__PURE__ */ jsxs29("div", { className: "medo-empty-state__actions", children: [
2849
- action && /* @__PURE__ */ jsx30(Button, { variant: type === "first-use" ? "primary" : "secondary", size: buttonSize, onPress: action.onPress, isDisabled: action.isDisabled, children: action.label }),
2850
- secondaryAction && (secondaryAction.href ? /* @__PURE__ */ jsx30(Link, { variant: "standalone", href: secondaryAction.href, isDisabled: secondaryAction.isDisabled, children: secondaryAction.label }) : /* @__PURE__ */ jsx30(Button, { variant: "text", size: buttonSize, onPress: secondaryAction.onPress, isDisabled: secondaryAction.isDisabled, children: secondaryAction.label }))
3222
+ action && /* @__PURE__ */ jsx31(Button, { variant: type === "first-use" ? "primary" : "secondary", size: buttonSize, onPress: action.onPress, isDisabled: action.isDisabled, children: action.label }),
3223
+ secondaryAction && (secondaryAction.href ? /* @__PURE__ */ jsx31(Link, { variant: "standalone", href: secondaryAction.href, isDisabled: secondaryAction.isDisabled, children: secondaryAction.label }) : /* @__PURE__ */ jsx31(Button, { variant: "text", size: buttonSize, onPress: secondaryAction.onPress, isDisabled: secondaryAction.isDisabled, children: secondaryAction.label }))
2851
3224
  ] })
2852
3225
  ] });
2853
3226
  }
2854
3227
  function IconTile({ size = "md", tone = "neutral", children }) {
2855
- return /* @__PURE__ */ jsx30("span", { className: cx("medo-icon-tile", `medo-icon-tile--${size}`, `medo-icon-tile--${tone}`), "aria-hidden": "true", children });
3228
+ return /* @__PURE__ */ jsx31("span", { className: cx("medo-icon-tile", `medo-icon-tile--${size}`, `medo-icon-tile--${tone}`), "aria-hidden": "true", children });
2856
3229
  }
2857
3230
 
2858
3231
  // src/pagination/Pagination.tsx
2859
3232
  import { useId as useId7, useRef as useRef13, useState as useState12 } from "react";
2860
3233
  import { Button as AriaButton10, Link as AriaLink4 } from "react-aria-components";
2861
3234
  import { ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3 } from "lucide-react";
2862
- import { Fragment as Fragment18, jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
3235
+ import { Fragment as Fragment18, jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
2863
3236
  function getPageItems(page, totalPages) {
2864
3237
  if (totalPages <= 7) return Array.from({ length: totalPages }, (_, i) => i + 1);
2865
3238
  if (page <= 4) return [1, 2, 3, 4, 5, "ellipsis", totalPages];
@@ -2878,15 +3251,23 @@ function Pagination({
2878
3251
  pageSizeOptions = [10, 20, 50, 100],
2879
3252
  variant = "auto",
2880
3253
  size = "md",
2881
- "aria-label": ariaLabel = "Pagination",
2882
- summary = (from, to, total) => `${from}\u2013${to} of ${total}`,
2883
- pageSizeLabel = "Rows per page",
2884
- previousLabel = "Previous page",
2885
- nextLabel = "Next page",
2886
- pageLabel = (p) => `Page ${p}`,
2887
- compactLabel = (p, total) => `Page ${p} of ${total}`,
3254
+ "aria-label": ariaLabelProp,
3255
+ summary: summaryProp,
3256
+ pageSizeLabel: pageSizeLabelProp,
3257
+ previousLabel: previousLabelProp,
3258
+ nextLabel: nextLabelProp,
3259
+ pageLabel: pageLabelProp,
3260
+ compactLabel: compactLabelProp,
2888
3261
  className
2889
3262
  }) {
3263
+ const m = useMessages();
3264
+ const ariaLabel = ariaLabelProp ?? m.pagination.label;
3265
+ const summary = summaryProp ?? m.pagination.summary;
3266
+ const pageSizeLabel = pageSizeLabelProp ?? m.pagination.pageSize;
3267
+ const previousLabel = previousLabelProp ?? m.pagination.previous;
3268
+ const nextLabel = nextLabelProp ?? m.pagination.next;
3269
+ const pageLabel = pageLabelProp ?? m.pagination.page;
3270
+ const compactLabel = compactLabelProp ?? m.pagination.pageOf;
2890
3271
  const [innerPage, setInnerPage] = useState12(defaultPage);
2891
3272
  const mobile = useMediaQuery(MOBILE_QUERY);
2892
3273
  const totalPages = totalPagesProp ?? (totalItems !== void 0 ? Math.ceil(totalItems / pageSize) : 1);
@@ -2905,23 +3286,23 @@ function Pagination({
2905
3286
  (nav.querySelector('[aria-current="page"]') ?? nav.querySelector(".medo-button:not([data-disabled])"))?.focus();
2906
3287
  });
2907
3288
  };
2908
- const item = (target, props) => getPageHref ? /* @__PURE__ */ jsx31(AriaLink4, { ...props, href: props.isDisabled ? void 0 : getPageHref(target), onPress: () => go(target) }) : /* @__PURE__ */ jsx31(AriaButton10, { ...props, onPress: () => go(target) });
3289
+ const item = (target, props) => getPageHref ? /* @__PURE__ */ jsx32(AriaLink4, { ...props, href: props.isDisabled ? void 0 : getPageHref(target), onPress: () => go(target) }) : /* @__PURE__ */ jsx32(AriaButton10, { ...props, onPress: () => go(target) });
2909
3290
  const step = (target, label, icon) => item(target, {
2910
3291
  className: cx("medo-button", "medo-button--icon-only", "medo-button--ghost", `medo-button--${itemSize}`),
2911
3292
  "aria-label": label,
2912
3293
  isDisabled: target < 1 || target > totalPages,
2913
- children: /* @__PURE__ */ jsx31("span", { className: "medo-button__icon", "aria-hidden": "true", children: icon })
3294
+ children: /* @__PURE__ */ jsx32("span", { className: "medo-button__icon", "aria-hidden": "true", children: icon })
2914
3295
  });
2915
3296
  const from = (page - 1) * pageSize + 1;
2916
3297
  const to = totalItems !== void 0 ? Math.min(page * pageSize, totalItems) : page * pageSize;
2917
- return /* @__PURE__ */ jsx31("nav", { ref: navRef, "aria-label": ariaLabel, className: cx("medo-pagination", compact ? "medo-pagination--compact" : "medo-pagination--full", className), children: compact ? /* @__PURE__ */ jsxs30(Fragment18, { children: [
2918
- step(page - 1, previousLabel, /* @__PURE__ */ jsx31(ChevronLeft2, {})),
2919
- /* @__PURE__ */ jsx31("p", { role: "status", className: "medo-pagination__compact-label", children: compactLabel(page, totalPages) }),
2920
- step(page + 1, nextLabel, /* @__PURE__ */ jsx31(ChevronRight3, {}))
3298
+ return /* @__PURE__ */ jsx32("nav", { ref: navRef, "aria-label": ariaLabel, className: cx("medo-pagination", compact ? "medo-pagination--compact" : "medo-pagination--full", className), children: compact ? /* @__PURE__ */ jsxs30(Fragment18, { children: [
3299
+ step(page - 1, previousLabel, /* @__PURE__ */ jsx32(ChevronLeft2, {})),
3300
+ /* @__PURE__ */ jsx32("p", { role: "status", className: "medo-pagination__compact-label", children: compactLabel(page, totalPages) }),
3301
+ step(page + 1, nextLabel, /* @__PURE__ */ jsx32(ChevronRight3, {}))
2921
3302
  ] }) : /* @__PURE__ */ jsxs30(Fragment18, { children: [
2922
3303
  (totalItems !== void 0 || onPageSizeChange) && /* @__PURE__ */ jsxs30("div", { className: "medo-pagination__info", children: [
2923
- totalItems !== void 0 && /* @__PURE__ */ jsx31("p", { id: statusId, role: "status", className: "medo-pagination__summary", children: summary(from, to, totalItems) }),
2924
- onPageSizeChange && /* @__PURE__ */ jsx31(
3304
+ totalItems !== void 0 && /* @__PURE__ */ jsx32("p", { id: statusId, role: "status", className: "medo-pagination__summary", children: summary(from, to, totalItems) }),
3305
+ onPageSizeChange && /* @__PURE__ */ jsx32(
2925
3306
  Select,
2926
3307
  {
2927
3308
  label: pageSizeLabel,
@@ -2929,24 +3310,24 @@ function Pagination({
2929
3310
  selectedKey: pageSize,
2930
3311
  onSelectionChange: (key) => key != null && onPageSizeChange(Number(key)),
2931
3312
  className: "medo-pagination__size",
2932
- children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx31(Option, { id: n, children: String(n) }, n))
3313
+ children: pageSizeOptions.map((n) => /* @__PURE__ */ jsx32(Option, { id: n, children: String(n) }, n))
2933
3314
  }
2934
3315
  )
2935
3316
  ] }),
2936
3317
  /* @__PURE__ */ jsxs30("ul", { className: "medo-pagination__pages", role: "list", children: [
2937
- /* @__PURE__ */ jsx31("li", { children: step(page - 1, previousLabel, /* @__PURE__ */ jsx31(ChevronLeft2, {})) }),
3318
+ /* @__PURE__ */ jsx32("li", { children: step(page - 1, previousLabel, /* @__PURE__ */ jsx32(ChevronLeft2, {})) }),
2938
3319
  getPageItems(page, totalPages).map(
2939
3320
  (p, i) => p === "ellipsis" ? (
2940
3321
  // Text, not a button – hidden from screen readers (the page names say where they jump).
2941
- /* @__PURE__ */ jsx31("li", { className: cx("medo-page-item", "medo-page-item--ellipsis", `medo-page-item--${itemSize}`), "aria-hidden": "true", children: "\u2026" }, `e${i}`)
2942
- ) : /* @__PURE__ */ jsx31("li", { children: item(p, {
3322
+ /* @__PURE__ */ jsx32("li", { className: cx("medo-page-item", "medo-page-item--ellipsis", `medo-page-item--${itemSize}`), "aria-hidden": "true", children: "\u2026" }, `e${i}`)
3323
+ ) : /* @__PURE__ */ jsx32("li", { children: item(p, {
2943
3324
  className: cx("medo-button", "medo-button--ghost", `medo-button--${itemSize}`, "medo-page-item", `medo-page-item--${itemSize}`),
2944
3325
  "aria-label": pageLabel(p),
2945
3326
  "aria-current": p === page ? "page" : void 0,
2946
3327
  children: p
2947
3328
  }) }, p)
2948
3329
  ),
2949
- /* @__PURE__ */ jsx31("li", { children: step(page + 1, nextLabel, /* @__PURE__ */ jsx31(ChevronRight3, {})) })
3330
+ /* @__PURE__ */ jsx32("li", { children: step(page + 1, nextLabel, /* @__PURE__ */ jsx32(ChevronRight3, {})) })
2950
3331
  ] })
2951
3332
  ] }) });
2952
3333
  }
@@ -2954,24 +3335,25 @@ function Pagination({
2954
3335
  // src/search/SearchField.tsx
2955
3336
  import { Button as AriaButton11, Input as AriaInput2, SearchField as AriaSearchField } from "react-aria-components";
2956
3337
  import { Search as Search3, X as X13 } from "lucide-react";
2957
- import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
2958
- function SearchField({ label, description, placeholder, size = "md", clearLabel = "Clear search", className, ...props }) {
3338
+ import { jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
3339
+ function SearchField({ label, description, placeholder, size = "md", clearLabel, className, ...props }) {
3340
+ const m = useMessages();
2959
3341
  return /* @__PURE__ */ jsxs31(AriaSearchField, { ...props, className: cx("medo-field", "medo-search-field", className), children: [
2960
- label && /* @__PURE__ */ jsx32(FieldLabel, { isRequired: props.isRequired, children: label }),
3342
+ label && /* @__PURE__ */ jsx33(FieldLabel, { isRequired: props.isRequired, children: label }),
2961
3343
  /* @__PURE__ */ jsxs31("div", { className: cx("medo-input", `medo-input--${size}`), children: [
2962
- /* @__PURE__ */ jsx32("span", { className: "medo-input__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx32(Search3, {}) }),
2963
- /* @__PURE__ */ jsx32(AriaInput2, { className: "medo-input__control", placeholder }),
2964
- /* @__PURE__ */ jsx32(AriaButton11, { "aria-label": clearLabel, className: "medo-input__action medo-search-field__clear", children: /* @__PURE__ */ jsx32(X13, {}) })
3344
+ /* @__PURE__ */ jsx33("span", { className: "medo-input__icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx33(Search3, {}) }),
3345
+ /* @__PURE__ */ jsx33(AriaInput2, { className: "medo-input__control", placeholder }),
3346
+ /* @__PURE__ */ jsx33(AriaButton11, { "aria-label": clearLabel ?? m.searchField.clear, className: "medo-input__action medo-search-field__clear", children: /* @__PURE__ */ jsx33(X13, {}) })
2965
3347
  ] }),
2966
- description && /* @__PURE__ */ jsx32(FieldFooter, { description })
3348
+ description && /* @__PURE__ */ jsx33(FieldFooter, { description })
2967
3349
  ] });
2968
3350
  }
2969
3351
 
2970
3352
  // src/search/SearchResult.tsx
2971
3353
  import { Link as AriaLink5 } from "react-aria-components";
2972
3354
  import { FileText, Globe } from "lucide-react";
2973
- import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
2974
- var icons = { page: /* @__PURE__ */ jsx33(Globe, {}), document: /* @__PURE__ */ jsx33(FileText, {}) };
3355
+ import { jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
3356
+ var icons = { page: /* @__PURE__ */ jsx34(Globe, {}), document: /* @__PURE__ */ jsx34(FileText, {}) };
2975
3357
  function SearchResult({
2976
3358
  type = "page",
2977
3359
  variant = "base",
@@ -2988,16 +3370,16 @@ function SearchResult({
2988
3370
  className
2989
3371
  }) {
2990
3372
  const Heading7 = `h${headingLevel}`;
2991
- const lead = leading ?? (icons[type] && /* @__PURE__ */ jsx33(IconTile, { size: "sm", children: icons[type] }));
3373
+ const lead = leading ?? (icons[type] && /* @__PURE__ */ jsx34(IconTile, { size: "sm", children: icons[type] }));
2992
3374
  return /* @__PURE__ */ jsxs32("article", { className: cx("medo-search-result", `medo-search-result--${variant}`, `medo-search-result--${type}`, className), children: [
2993
- lead && /* @__PURE__ */ jsx33(AvatarSizeContext.Provider, { value: "lg", children: /* @__PURE__ */ jsx33("span", { className: "medo-search-result__leading", children: lead }) }),
3375
+ lead && /* @__PURE__ */ jsx34(AvatarSizeContext.Provider, { value: "lg", children: /* @__PURE__ */ jsx34("span", { className: "medo-search-result__leading", children: lead }) }),
2994
3376
  /* @__PURE__ */ jsxs32("div", { className: "medo-search-result__content", children: [
2995
- path && /* @__PURE__ */ jsx33("span", { className: "medo-search-result__path", children: path }),
2996
- /* @__PURE__ */ jsx33(Heading7, { className: "medo-search-result__title", children: /* @__PURE__ */ jsx33(AriaLink5, { ...linkProps, href, className: "medo-search-result__link", children: /* @__PURE__ */ jsx33(Highlight, { text: title, query, all: true, className: "medo-search-result__match" }) }) }),
2997
- snippet && /* @__PURE__ */ jsx33("p", { className: "medo-search-result__snippet", children: typeof snippet === "string" ? /* @__PURE__ */ jsx33(Highlight, { text: snippet, query, all: true, className: "medo-search-result__match" }) : snippet }),
3377
+ path && /* @__PURE__ */ jsx34("span", { className: "medo-search-result__path", children: path }),
3378
+ /* @__PURE__ */ jsx34(Heading7, { className: "medo-search-result__title", children: /* @__PURE__ */ jsx34(AriaLink5, { ...linkProps, href, className: "medo-search-result__link", children: /* @__PURE__ */ jsx34(Highlight, { text: title, query, all: true, className: "medo-search-result__match" }) }) }),
3379
+ snippet && /* @__PURE__ */ jsx34("p", { className: "medo-search-result__snippet", children: typeof snippet === "string" ? /* @__PURE__ */ jsx34(Highlight, { text: snippet, query, all: true, className: "medo-search-result__match" }) : snippet }),
2998
3380
  (badge || meta) && /* @__PURE__ */ jsxs32("span", { className: "medo-search-result__meta", children: [
2999
- badge && /* @__PURE__ */ jsx33(Badge, { tone: "neutral", size: "sm", children: badge }),
3000
- meta && /* @__PURE__ */ jsx33("span", { className: "medo-search-result__meta-text", children: meta })
3381
+ badge && /* @__PURE__ */ jsx34(Badge, { tone: "neutral", size: "sm", children: badge }),
3382
+ meta && /* @__PURE__ */ jsx34("span", { className: "medo-search-result__meta-text", children: meta })
3001
3383
  ] })
3002
3384
  ] })
3003
3385
  ] });
@@ -3007,7 +3389,7 @@ function SearchResult({
3007
3389
  import { useEffect as useEffect12, useLayoutEffect as useLayoutEffect5, useState as useState13 } from "react";
3008
3390
  import { Autocomplete as Autocomplete2, Button as AriaButton12, Dialog as Dialog3, Modal as Modal5, ModalOverlay as ModalOverlay5, useFilter as useFilter2 } from "react-aria-components";
3009
3391
  import { Search as Search4 } from "lucide-react";
3010
- import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
3392
+ import { jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
3011
3393
  function QuickSearch({
3012
3394
  isOpen,
3013
3395
  defaultOpen,
@@ -3021,15 +3403,24 @@ function QuickSearch({
3021
3403
  onAction,
3022
3404
  allResultsHref,
3023
3405
  onSearch,
3024
- "aria-label": ariaLabel = "Search",
3025
- placeholder = "Search pages, files, people \u2026",
3026
- cancelLabel = "Cancel",
3027
- suggestionsLabel = "Suggestions",
3028
- allResultsLabel = (q) => `All results for \u201C${q}\u201D`,
3029
- noResultsLabel = (q) => `No results for \u201C${q}\u201D. Check the spelling or try other words.`,
3030
- searchAllLabel = (q) => `Search all content for \u201C${q}\u201D`,
3031
- hints = { navigate: "Navigate", open: "Open", close: "Close" }
3406
+ "aria-label": ariaLabelProp,
3407
+ placeholder: placeholderProp,
3408
+ cancelLabel: cancelLabelProp,
3409
+ suggestionsLabel: suggestionsLabelProp,
3410
+ allResultsLabel: allResultsLabelProp,
3411
+ noResultsLabel: noResultsLabelProp,
3412
+ searchAllLabel: searchAllLabelProp,
3413
+ hints: hintsProp
3032
3414
  }) {
3415
+ const m = useMessages();
3416
+ const ariaLabel = ariaLabelProp ?? m.common.search;
3417
+ const placeholder = placeholderProp ?? m.quickSearch.placeholder;
3418
+ const cancelLabel = cancelLabelProp ?? m.common.cancel;
3419
+ const suggestionsLabel = suggestionsLabelProp ?? m.quickSearch.suggestions;
3420
+ const allResultsLabel = allResultsLabelProp ?? m.quickSearch.allResults;
3421
+ const noResultsLabel = noResultsLabelProp ?? m.quickSearch.noResults;
3422
+ const searchAllLabel = searchAllLabelProp ?? m.quickSearch.searchAll;
3423
+ const hints = hintsProp ?? { navigate: m.quickSearch.navigate, open: m.quickSearch.open, close: m.common.close };
3033
3424
  const mobile = useMediaQuery(MOBILE_QUERY);
3034
3425
  const [innerOpen, setInnerOpen] = useState13(defaultOpen ?? false);
3035
3426
  const open = isOpen ?? innerOpen;
@@ -3059,17 +3450,17 @@ function QuickSearch({
3059
3450
  const term = query.trim();
3060
3451
  const close = () => setOpen(false);
3061
3452
  const [empty, setEmpty] = useState13(false);
3062
- return /* @__PURE__ */ jsx34(
3453
+ return /* @__PURE__ */ jsx35(
3063
3454
  ModalOverlay5,
3064
3455
  {
3065
3456
  isOpen: open,
3066
3457
  onOpenChange: setOpen,
3067
3458
  isDismissable: true,
3068
3459
  className: cx("medo-dialog-overlay", "medo-quick-search-overlay", mobile && "medo-quick-search-overlay--mobile"),
3069
- children: /* @__PURE__ */ jsx34(Modal5, { className: cx("medo-dialog", "medo-quick-search", mobile && "medo-quick-search--mobile"), children: /* @__PURE__ */ jsxs33(Dialog3, { "aria-label": ariaLabel, className: "medo-quick-search__dialog", children: [
3460
+ children: /* @__PURE__ */ jsx35(Modal5, { className: cx("medo-dialog", "medo-quick-search", mobile && "medo-quick-search--mobile"), children: /* @__PURE__ */ jsxs33(Dialog3, { "aria-label": ariaLabel, className: "medo-quick-search__dialog", children: [
3070
3461
  /* @__PURE__ */ jsxs33(Autocomplete2, { inputValue: query, onInputChange: setQuery, filter: clientFilter ? contains : void 0, children: [
3071
3462
  /* @__PURE__ */ jsxs33("div", { className: "medo-quick-search__bar", children: [
3072
- /* @__PURE__ */ jsx34(
3463
+ /* @__PURE__ */ jsx35(
3073
3464
  SearchField,
3074
3465
  {
3075
3466
  "aria-label": ariaLabel,
@@ -3080,10 +3471,10 @@ function QuickSearch({
3080
3471
  className: "medo-quick-search__field"
3081
3472
  }
3082
3473
  ),
3083
- mobile && /* @__PURE__ */ jsx34(Button, { variant: "text", size: "lg", onPress: close, children: cancelLabel })
3474
+ mobile && /* @__PURE__ */ jsx35(Button, { variant: "text", size: "lg", onPress: close, children: cancelLabel })
3084
3475
  ] }),
3085
3476
  /* @__PURE__ */ jsxs33("div", { className: "medo-quick-search__scroll", tabIndex: 0, "aria-label": suggestionsLabel, role: "region", children: [
3086
- /* @__PURE__ */ jsx34(OptionHighlightContext.Provider, { value: term, children: /* @__PURE__ */ jsx34(
3477
+ /* @__PURE__ */ jsx35(OptionHighlightContext.Provider, { value: term, children: /* @__PURE__ */ jsx35(
3087
3478
  ListBox,
3088
3479
  {
3089
3480
  "aria-label": ariaLabel,
@@ -3094,30 +3485,30 @@ function QuickSearch({
3094
3485
  close();
3095
3486
  },
3096
3487
  className: "medo-quick-search__list",
3097
- renderEmptyState: () => term ? /* @__PURE__ */ jsx34(EmptyReporter, { onChange: setEmpty, message: noResultsLabel(term) }) : null,
3488
+ renderEmptyState: () => term ? /* @__PURE__ */ jsx35(EmptyReporter, { onChange: setEmpty, message: noResultsLabel(term) }) : null,
3098
3489
  children
3099
3490
  }
3100
3491
  ) }),
3101
3492
  empty && term && onSearch && /* @__PURE__ */ jsxs33(AriaButton12, { className: "medo-quick-search__all", onPress: () => onSearch(term), children: [
3102
- /* @__PURE__ */ jsx34(Search4, { "aria-hidden": "true" }),
3493
+ /* @__PURE__ */ jsx35(Search4, { "aria-hidden": "true" }),
3103
3494
  searchAllLabel(term)
3104
3495
  ] })
3105
3496
  ] })
3106
3497
  ] }),
3107
3498
  !mobile && /* @__PURE__ */ jsxs33("div", { className: "medo-quick-search__footer", children: [
3108
3499
  /* @__PURE__ */ jsxs33("span", { className: "medo-quick-search__hint", "aria-hidden": "true", children: [
3109
- /* @__PURE__ */ jsx34(Badge, { size: "sm", children: "\u2191 \u2193" }),
3500
+ /* @__PURE__ */ jsx35(Badge, { size: "sm", children: "\u2191 \u2193" }),
3110
3501
  hints.navigate
3111
3502
  ] }),
3112
3503
  /* @__PURE__ */ jsxs33("span", { className: "medo-quick-search__hint", "aria-hidden": "true", children: [
3113
- /* @__PURE__ */ jsx34(Badge, { size: "sm", children: "Enter" }),
3504
+ /* @__PURE__ */ jsx35(Badge, { size: "sm", children: "Enter" }),
3114
3505
  hints.open
3115
3506
  ] }),
3116
3507
  /* @__PURE__ */ jsxs33("span", { className: "medo-quick-search__hint", "aria-hidden": "true", children: [
3117
- /* @__PURE__ */ jsx34(Badge, { size: "sm", children: "Esc" }),
3508
+ /* @__PURE__ */ jsx35(Badge, { size: "sm", children: "Esc" }),
3118
3509
  hints.close
3119
3510
  ] }),
3120
- term && !empty && allResultsHref && /* @__PURE__ */ jsx34(Link, { variant: "standalone", size: "md", arrow: true, href: allResultsHref(term), className: "medo-quick-search__all-results", onPress: close, children: allResultsLabel(term) })
3511
+ term && !empty && allResultsHref && /* @__PURE__ */ jsx35(Link, { variant: "standalone", size: "md", arrow: true, href: allResultsHref(term), className: "medo-quick-search__all-results", onPress: close, children: allResultsLabel(term) })
3121
3512
  ] })
3122
3513
  ] }) })
3123
3514
  }
@@ -3128,60 +3519,63 @@ function EmptyReporter({ message, onChange }) {
3128
3519
  onChange(true);
3129
3520
  return () => onChange(false);
3130
3521
  }, [onChange]);
3131
- return /* @__PURE__ */ jsx34("p", { role: "status", className: "medo-quick-search__message", children: message });
3522
+ return /* @__PURE__ */ jsx35("p", { role: "status", className: "medo-quick-search__message", children: message });
3132
3523
  }
3133
3524
 
3134
3525
  // src/breadcrumbs/Breadcrumbs.tsx
3135
3526
  import { useLayoutEffect as useLayoutEffect6, useRef as useRef14, useState as useState14 } from "react";
3136
3527
  import { Breadcrumb, Breadcrumbs as AriaBreadcrumbs, Button as AriaButton13, Link as AriaLink6 } from "react-aria-components";
3137
3528
  import { ChevronLeft as ChevronLeft3, ChevronRight as ChevronRight4, Ellipsis as Ellipsis4, Folder as Folder2, House } from "lucide-react";
3138
- import { jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
3529
+ import { jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
3139
3530
  function Breadcrumbs({
3140
3531
  items,
3141
3532
  size = "md",
3142
3533
  homeIcon = true,
3143
3534
  layout = "auto",
3144
- "aria-label": ariaLabel = "Breadcrumb",
3145
- moreLabel = (n) => `Show ${n} more levels`,
3535
+ "aria-label": ariaLabelProp,
3536
+ moreLabel: moreLabelProp,
3146
3537
  className
3147
3538
  }) {
3539
+ const m = useMessages();
3540
+ const ariaLabel = ariaLabelProp ?? m.breadcrumbs.label;
3541
+ const moreLabel = moreLabelProp ?? m.breadcrumbs.more;
3148
3542
  const mobile = useMediaQuery(MOBILE_QUERY);
3149
3543
  const back = layout === "back" || layout === "auto" && mobile;
3150
3544
  if (items.length < 2) return null;
3151
3545
  if (back) {
3152
3546
  const parent = items[items.length - 2];
3153
- return /* @__PURE__ */ jsx35("nav", { "aria-label": ariaLabel, className: cx("medo-breadcrumbs", `medo-breadcrumbs--${size}`, "medo-breadcrumbs--back", className), children: /* @__PURE__ */ jsxs34(AriaLink6, { href: parent.href, className: "medo-breadcrumbs__link medo-breadcrumbs__back", children: [
3154
- /* @__PURE__ */ jsx35(ChevronLeft3, { className: "medo-breadcrumbs__back-icon", "aria-hidden": "true" }),
3155
- /* @__PURE__ */ jsx35(Label3, { text: parent.label })
3547
+ return /* @__PURE__ */ jsx36("nav", { "aria-label": ariaLabel, className: cx("medo-breadcrumbs", `medo-breadcrumbs--${size}`, "medo-breadcrumbs--back", className), children: /* @__PURE__ */ jsxs34(AriaLink6, { href: parent.href, className: "medo-breadcrumbs__link medo-breadcrumbs__back", children: [
3548
+ /* @__PURE__ */ jsx36(ChevronLeft3, { className: "medo-breadcrumbs__back-icon", "aria-hidden": "true" }),
3549
+ /* @__PURE__ */ jsx36(Label3, { text: parent.label })
3156
3550
  ] }) });
3157
3551
  }
3158
3552
  const collapse = items.length >= 5;
3159
3553
  const hidden = collapse ? items.slice(1, -3) : [];
3160
3554
  const shown = collapse ? [items[0], null, ...items.slice(-3)] : items;
3161
3555
  const last = shown.length - 1;
3162
- return /* @__PURE__ */ jsx35("nav", { "aria-label": ariaLabel, className: cx("medo-breadcrumbs", `medo-breadcrumbs--${size}`, className), children: /* @__PURE__ */ jsx35(AriaBreadcrumbs, { className: "medo-breadcrumbs__list", children: shown.map((item, i) => {
3163
- const separator = i < last && /* @__PURE__ */ jsx35(ChevronRight4, { className: "medo-breadcrumbs__separator", "aria-hidden": "true" });
3556
+ return /* @__PURE__ */ jsx36("nav", { "aria-label": ariaLabel, className: cx("medo-breadcrumbs", `medo-breadcrumbs--${size}`, className), children: /* @__PURE__ */ jsx36(AriaBreadcrumbs, { className: "medo-breadcrumbs__list", children: shown.map((item, i) => {
3557
+ const separator = i < last && /* @__PURE__ */ jsx36(ChevronRight4, { className: "medo-breadcrumbs__separator", "aria-hidden": "true" });
3164
3558
  if (!item) {
3165
3559
  return /* @__PURE__ */ jsxs34(Breadcrumb, { id: "more", className: "medo-breadcrumbs__item", children: [
3166
3560
  /* @__PURE__ */ jsxs34(MenuTrigger, { children: [
3167
- /* @__PURE__ */ jsx35(AriaButton13, { "aria-label": moreLabel(hidden.length), className: "medo-breadcrumbs__icon-part", children: /* @__PURE__ */ jsx35(Ellipsis4, { "aria-hidden": "true" }) }),
3168
- /* @__PURE__ */ jsx35(Menu, { children: hidden.map((h) => /* @__PURE__ */ jsx35(MenuItem, { id: h.label, href: h.href, icon: /* @__PURE__ */ jsx35(Folder2, {}), children: h.label }, h.label)) })
3561
+ /* @__PURE__ */ jsx36(AriaButton13, { "aria-label": moreLabel(hidden.length), className: "medo-breadcrumbs__icon-part", children: /* @__PURE__ */ jsx36(Ellipsis4, { "aria-hidden": "true" }) }),
3562
+ /* @__PURE__ */ jsx36(Menu, { children: hidden.map((h) => /* @__PURE__ */ jsx36(MenuItem, { id: h.label, href: h.href, icon: /* @__PURE__ */ jsx36(Folder2, {}), children: h.label }, h.label)) })
3169
3563
  ] }),
3170
3564
  separator
3171
3565
  ] }, "more");
3172
3566
  }
3173
3567
  const isHome = homeIcon && i === 0;
3174
3568
  return /* @__PURE__ */ jsxs34(Breadcrumb, { id: `${i}-${item.label}`, className: "medo-breadcrumbs__item", children: [
3175
- isHome ? /* @__PURE__ */ jsx35(AriaLink6, { href: item.href, "aria-label": item.label, className: "medo-breadcrumbs__icon-part", children: /* @__PURE__ */ jsx35(House, { "aria-hidden": "true" }) }) : i === last ? (
3569
+ isHome ? /* @__PURE__ */ jsx36(AriaLink6, { href: item.href, "aria-label": item.label, className: "medo-breadcrumbs__icon-part", children: /* @__PURE__ */ jsx36(House, { "aria-hidden": "true" }) }) : i === last ? (
3176
3570
  // The current page: not a link (React Aria sets aria-current="page").
3177
- /* @__PURE__ */ jsx35(AriaLink6, { className: "medo-breadcrumbs__link medo-breadcrumbs__current", children: /* @__PURE__ */ jsx35(Label3, { text: item.label }) })
3178
- ) : /* @__PURE__ */ jsx35(TruncatedLink, { href: item.href, label: item.label }),
3571
+ /* @__PURE__ */ jsx36(AriaLink6, { className: "medo-breadcrumbs__link medo-breadcrumbs__current", children: /* @__PURE__ */ jsx36(Label3, { text: item.label }) })
3572
+ ) : /* @__PURE__ */ jsx36(TruncatedLink, { href: item.href, label: item.label }),
3179
3573
  separator
3180
3574
  ] }, `${i}-${item.label}`);
3181
3575
  }) }) });
3182
3576
  }
3183
3577
  function Label3({ text }) {
3184
- return /* @__PURE__ */ jsx35("span", { className: "medo-breadcrumbs__label", children: text });
3578
+ return /* @__PURE__ */ jsx36("span", { className: "medo-breadcrumbs__label", children: text });
3185
3579
  }
3186
3580
  function TruncatedLink({ href, label }) {
3187
3581
  const ref = useRef14(null);
@@ -3190,30 +3584,30 @@ function TruncatedLink({ href, label }) {
3190
3584
  const el = ref.current;
3191
3585
  if (el) setCut(el.scrollWidth > el.clientWidth);
3192
3586
  }, [label]);
3193
- const text = /* @__PURE__ */ jsx35("span", { ref, className: "medo-breadcrumbs__label", children: label });
3587
+ const text = /* @__PURE__ */ jsx36("span", { ref, className: "medo-breadcrumbs__label", children: label });
3194
3588
  if (!cut) {
3195
- return /* @__PURE__ */ jsx35(AriaLink6, { href, className: "medo-breadcrumbs__link", children: text });
3589
+ return /* @__PURE__ */ jsx36(AriaLink6, { href, className: "medo-breadcrumbs__link", children: text });
3196
3590
  }
3197
3591
  return /* @__PURE__ */ jsxs34(TooltipTrigger, { children: [
3198
- /* @__PURE__ */ jsx35(TooltipLink, { href, className: "medo-breadcrumbs__link", children: text }),
3199
- /* @__PURE__ */ jsx35(Tooltip, { children: label })
3592
+ /* @__PURE__ */ jsx36(TooltipLink, { href, className: "medo-breadcrumbs__link", children: text }),
3593
+ /* @__PURE__ */ jsx36(Tooltip, { children: label })
3200
3594
  ] });
3201
3595
  }
3202
3596
 
3203
3597
  // src/accordion/Accordion.tsx
3204
- import { Children as Children3, createContext as createContext9, isValidElement as isValidElement3, useContext as useContext16, useEffect as useEffect13, useId as useId8, useState as useState15 } from "react";
3598
+ import { Children as Children3, createContext as createContext10, isValidElement as isValidElement3, useContext as useContext17, useEffect as useEffect13, useId as useId8, useState as useState15 } from "react";
3205
3599
  import { Button as AriaButton14, Disclosure, DisclosureGroup, DisclosurePanel, Heading as Heading6 } from "react-aria-components";
3206
3600
  import { ChevronDown as ChevronDown4 } from "lucide-react";
3207
- import { jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
3208
- var AccordionContext = createContext9({ size: "md", headingLevel: 3 });
3601
+ import { jsx as jsx37, jsxs as jsxs35 } from "react/jsx-runtime";
3602
+ var AccordionContext = createContext10({ size: "md", headingLevel: 3 });
3209
3603
  var hashId = () => typeof window === "undefined" ? "" : decodeURIComponent(window.location.hash.slice(1));
3210
3604
  function Accordion({
3211
3605
  size = "md",
3212
3606
  headingLevel = 3,
3213
3607
  allowsMultipleExpanded = true,
3214
3608
  expandAll = true,
3215
- expandAllLabel = "Expand all",
3216
- collapseAllLabel = "Collapse all",
3609
+ expandAllLabel,
3610
+ collapseAllLabel,
3217
3611
  expandedKeys: expandedProp,
3218
3612
  defaultExpandedKeys,
3219
3613
  onExpandedChange,
@@ -3221,6 +3615,7 @@ function Accordion({
3221
3615
  className,
3222
3616
  ...props
3223
3617
  }) {
3618
+ const m = useMessages();
3224
3619
  const ids = Children3.toArray(children).filter((c) => isValidElement3(c)).filter((c) => !c.props.isDisabled).map((c) => c.props.id);
3225
3620
  const [inner, setInner] = useState15(() => {
3226
3621
  const start = new Set(defaultExpandedKeys ?? []);
@@ -3246,9 +3641,9 @@ function Accordion({
3246
3641
  });
3247
3642
  const allOpen = ids.length > 0 && ids.every((id) => expanded.has(id));
3248
3643
  const showToggle = expandAll && allowsMultipleExpanded && Children3.count(children) > 6;
3249
- return /* @__PURE__ */ jsx36(AccordionContext.Provider, { value: { size, headingLevel }, children: /* @__PURE__ */ jsxs35("div", { className: cx("medo-accordion-wrap", className), children: [
3250
- showToggle && /* @__PURE__ */ jsx36("div", { className: "medo-accordion__toolbar", children: /* @__PURE__ */ jsx36(Button, { variant: "text", size: "sm", onPress: () => setExpanded(allOpen ? /* @__PURE__ */ new Set() : new Set(ids)), children: allOpen ? collapseAllLabel : expandAllLabel }) }),
3251
- /* @__PURE__ */ jsx36(
3644
+ return /* @__PURE__ */ jsx37(AccordionContext.Provider, { value: { size, headingLevel }, children: /* @__PURE__ */ jsxs35("div", { className: cx("medo-accordion-wrap", className), children: [
3645
+ showToggle && /* @__PURE__ */ jsx37("div", { className: "medo-accordion__toolbar", children: /* @__PURE__ */ jsx37(Button, { variant: "text", size: "sm", onPress: () => setExpanded(allOpen ? /* @__PURE__ */ new Set() : new Set(ids)), children: allOpen ? collapseAllLabel ?? m.accordion.collapseAll : expandAllLabel ?? m.accordion.expandAll }) }),
3646
+ /* @__PURE__ */ jsx37(
3252
3647
  DisclosureGroup,
3253
3648
  {
3254
3649
  ...props,
@@ -3262,40 +3657,40 @@ function Accordion({
3262
3657
  ] }) });
3263
3658
  }
3264
3659
  function AccordionItem({ id, title, description, icon, badge, isDisabled, children }) {
3265
- const { headingLevel } = useContext16(AccordionContext);
3660
+ const { headingLevel } = useContext17(AccordionContext);
3266
3661
  const descId = useId8();
3267
3662
  return /* @__PURE__ */ jsxs35(Disclosure, { id, isDisabled, className: cx("medo-accordion__item", !!icon && "medo-accordion__item--icon"), children: [
3268
- /* @__PURE__ */ jsx36(Heading6, { level: headingLevel, id, className: "medo-accordion__heading", children: /* @__PURE__ */ jsxs35(AriaButton14, { slot: "trigger", className: "medo-accordion__trigger", "aria-describedby": description ? descId : void 0, children: [
3269
- icon && /* @__PURE__ */ jsx36("span", { className: "medo-accordion__icon", "aria-hidden": "true", children: icon }),
3663
+ /* @__PURE__ */ jsx37(Heading6, { level: headingLevel, id, className: "medo-accordion__heading", children: /* @__PURE__ */ jsxs35(AriaButton14, { slot: "trigger", className: "medo-accordion__trigger", "aria-describedby": description ? descId : void 0, children: [
3664
+ icon && /* @__PURE__ */ jsx37("span", { className: "medo-accordion__icon", "aria-hidden": "true", children: icon }),
3270
3665
  /* @__PURE__ */ jsxs35("span", { className: "medo-accordion__text", children: [
3271
- /* @__PURE__ */ jsx36("span", { className: "medo-accordion__title", children: title }),
3666
+ /* @__PURE__ */ jsx37("span", { className: "medo-accordion__title", children: title }),
3272
3667
  description && // Read as description, not as part of the name.
3273
- /* @__PURE__ */ jsx36("span", { id: descId, className: "medo-accordion__description", "aria-hidden": "true", children: description })
3668
+ /* @__PURE__ */ jsx37("span", { id: descId, className: "medo-accordion__description", "aria-hidden": "true", children: description })
3274
3669
  ] }),
3275
- badge && /* @__PURE__ */ jsx36("span", { className: "medo-accordion__badge", children: badge }),
3276
- /* @__PURE__ */ jsx36(ChevronDown4, { className: "medo-accordion__chevron", "aria-hidden": "true" })
3670
+ badge && /* @__PURE__ */ jsx37("span", { className: "medo-accordion__badge", children: badge }),
3671
+ /* @__PURE__ */ jsx37(ChevronDown4, { className: "medo-accordion__chevron", "aria-hidden": "true" })
3277
3672
  ] }) }),
3278
- /* @__PURE__ */ jsx36(DisclosurePanel, { className: "medo-accordion__panel", children: /* @__PURE__ */ jsx36("div", { className: "medo-accordion__content", children }) })
3673
+ /* @__PURE__ */ jsx37(DisclosurePanel, { className: "medo-accordion__panel", children: /* @__PURE__ */ jsx37("div", { className: "medo-accordion__content", children }) })
3279
3674
  ] });
3280
3675
  }
3281
3676
 
3282
3677
  // src/slider/Slider.tsx
3283
3678
  import { useMemo } from "react";
3284
- import { Label as Label4, Slider as AriaSlider, SliderOutput, SliderThumb, SliderTrack, useLocale as useLocale2 } from "react-aria-components";
3679
+ import { Label as Label4, Slider as AriaSlider, SliderOutput, SliderThumb, SliderTrack, useLocale as useLocale3 } from "react-aria-components";
3285
3680
 
3286
3681
  // src/number-field/NumberField.tsx
3287
3682
  import { Input as AriaInput3, NumberField as AriaNumberField } from "react-aria-components";
3288
- import { jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
3683
+ import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
3289
3684
  function NumberField({ label, description, errorMessage, placeholder, size = "md", className, ...props }) {
3290
3685
  return /* @__PURE__ */ jsxs36(AriaNumberField, { ...props, className: cx("medo-field", "medo-number-field", className), children: [
3291
- label && /* @__PURE__ */ jsx37(FieldLabel, { isRequired: props.isRequired, children: label }),
3292
- /* @__PURE__ */ jsx37("div", { className: cx("medo-input", `medo-input--${size}`), children: /* @__PURE__ */ jsx37(AriaInput3, { className: "medo-input__control medo-number-field__control", placeholder }) }),
3293
- (description || errorMessage) && /* @__PURE__ */ jsx37(FieldFooter, { description, errorMessage })
3686
+ label && /* @__PURE__ */ jsx38(FieldLabel, { isRequired: props.isRequired, children: label }),
3687
+ /* @__PURE__ */ jsx38("div", { className: cx("medo-input", `medo-input--${size}`), children: /* @__PURE__ */ jsx38(AriaInput3, { className: "medo-input__control medo-number-field__control", placeholder }) }),
3688
+ (description || errorMessage) && /* @__PURE__ */ jsx38(FieldFooter, { description, errorMessage })
3294
3689
  ] });
3295
3690
  }
3296
3691
 
3297
3692
  // src/slider/Slider.tsx
3298
- import { Fragment as Fragment19, jsx as jsx38, jsxs as jsxs37 } from "react/jsx-runtime";
3693
+ import { Fragment as Fragment19, jsx as jsx39, jsxs as jsxs37 } from "react/jsx-runtime";
3299
3694
  function Slider({
3300
3695
  label,
3301
3696
  thumbLabels,
@@ -3309,63 +3704,65 @@ function Slider({
3309
3704
  className,
3310
3705
  ...props
3311
3706
  }) {
3312
- const { locale } = useLocale2();
3707
+ const m = useMessages();
3708
+ const { locale } = useLocale3();
3313
3709
  const format = useMemo(() => new Intl.NumberFormat(locale, formatOptions), [locale, formatOptions]);
3314
3710
  const steps = Math.round((maxValue - minValue) / step);
3315
3711
  const labelText = typeof label === "string" ? label : props["aria-label"] ?? "";
3316
- return /* @__PURE__ */ jsx38(AriaSlider, { ...props, minValue, maxValue, step, formatOptions, className: cx("medo-slider", className), children: ({ state }) => {
3712
+ return /* @__PURE__ */ jsx39(AriaSlider, { ...props, minValue, maxValue, step, formatOptions, className: cx("medo-slider", className), children: ({ state }) => {
3317
3713
  const range = state.values.length > 1;
3318
3714
  const start = range ? state.getThumbPercent(0) : 0;
3319
3715
  const end = state.getThumbPercent(state.values.length - 1);
3320
3716
  return /* @__PURE__ */ jsxs37(Fragment19, { children: [
3321
3717
  (label || showValue) && /* @__PURE__ */ jsxs37("div", { className: "medo-slider__header", children: [
3322
- label && /* @__PURE__ */ jsx38(Label4, { className: "medo-slider__label", "aria-disabled": props.isDisabled || void 0, children: label }),
3323
- showValue && /* @__PURE__ */ jsx38(SliderOutput, { className: "medo-slider__value", "aria-disabled": props.isDisabled || void 0 })
3718
+ label && /* @__PURE__ */ jsx39(Label4, { className: "medo-slider__label", "aria-disabled": props.isDisabled || void 0, children: label }),
3719
+ showValue && /* @__PURE__ */ jsx39(SliderOutput, { className: "medo-slider__value", "aria-disabled": props.isDisabled || void 0 })
3324
3720
  ] }),
3325
3721
  /* @__PURE__ */ jsxs37(SliderTrack, { className: "medo-slider__track", children: [
3326
- /* @__PURE__ */ jsx38("span", { className: "medo-slider__rail", "aria-hidden": "true" }),
3327
- showTicks && steps <= 10 && /* @__PURE__ */ jsx38("span", { className: "medo-slider__ticks", "aria-hidden": "true", children: Array.from({ length: steps + 1 }, (_, i) => /* @__PURE__ */ jsx38("span", { className: "medo-slider__tick", style: { insetInlineStart: `${i / steps * 100}%` } }, i)) }),
3328
- /* @__PURE__ */ jsx38("span", { className: "medo-slider__fill", style: { insetInlineStart: `${start * 100}%`, inlineSize: `${(end - start) * 100}%` }, "aria-hidden": "true" }),
3329
- state.values.map((_, i) => /* @__PURE__ */ jsx38(
3722
+ /* @__PURE__ */ jsx39("span", { className: "medo-slider__rail", "aria-hidden": "true" }),
3723
+ showTicks && steps <= 10 && /* @__PURE__ */ jsx39("span", { className: "medo-slider__ticks", "aria-hidden": "true", children: Array.from({ length: steps + 1 }, (_, i) => /* @__PURE__ */ jsx39("span", { className: "medo-slider__tick", style: { insetInlineStart: `${i / steps * 100}%` } }, i)) }),
3724
+ /* @__PURE__ */ jsx39("span", { className: "medo-slider__fill", style: { insetInlineStart: `${start * 100}%`, inlineSize: `${(end - start) * 100}%` }, "aria-hidden": "true" }),
3725
+ state.values.map((_, i) => /* @__PURE__ */ jsx39(
3330
3726
  SliderThumb,
3331
3727
  {
3332
3728
  index: i,
3333
- "aria-label": range ? thumbLabels?.[i] ?? `${i === 0 ? "Minimum" : "Maximum"} ${labelText}`.trim() : void 0,
3729
+ "aria-label": range ? thumbLabels?.[i] ?? (i === 0 ? m.slider.minimum(labelText) : m.slider.maximum(labelText)) : void 0,
3334
3730
  className: "medo-slider__thumb",
3335
3731
  children: ({ isDragging }) => (
3336
3732
  // The finger covers the thumb: show the value above it while dragging.
3337
- isDragging && /* @__PURE__ */ jsx38("span", { className: "medo-tooltip medo-slider__bubble", "aria-hidden": "true", children: state.getThumbValueLabel(i) })
3733
+ isDragging && /* @__PURE__ */ jsx39("span", { className: "medo-tooltip medo-slider__bubble", "aria-hidden": "true", children: state.getThumbValueLabel(i) })
3338
3734
  )
3339
3735
  },
3340
3736
  i
3341
3737
  ))
3342
3738
  ] }),
3343
3739
  showMinMax && /* @__PURE__ */ jsxs37("div", { className: "medo-slider__limits", "aria-hidden": "true", children: [
3344
- /* @__PURE__ */ jsx38("span", { children: format.format(minValue) }),
3345
- /* @__PURE__ */ jsx38("span", { children: format.format(maxValue) })
3740
+ /* @__PURE__ */ jsx39("span", { children: format.format(minValue) }),
3741
+ /* @__PURE__ */ jsx39("span", { children: format.format(maxValue) })
3346
3742
  ] })
3347
3743
  ] });
3348
3744
  } });
3349
3745
  }
3350
3746
  function SliderField({ value, onChange, inputLabels, ...props }) {
3747
+ const m = useMessages();
3351
3748
  const { minValue = 0, maxValue = 100, step = 1, formatOptions, isDisabled, label, thumbLabels } = props;
3352
3749
  const labelText = typeof label === "string" ? label : props["aria-label"] ?? "";
3353
3750
  const field = { step, formatOptions, isDisabled, size: "md" };
3354
3751
  if (Array.isArray(value)) {
3355
3752
  const [lo, hi] = value;
3356
- const names = inputLabels ?? thumbLabels ?? [`Minimum ${labelText}`.trim(), `Maximum ${labelText}`.trim()];
3753
+ const names = inputLabels ?? thumbLabels ?? [m.slider.minimum(labelText), m.slider.maximum(labelText)];
3357
3754
  return /* @__PURE__ */ jsxs37("div", { className: "medo-slider-field medo-slider-field--range", children: [
3358
- /* @__PURE__ */ jsx38(Slider, { ...props, value, onChange }),
3755
+ /* @__PURE__ */ jsx39(Slider, { ...props, value, onChange }),
3359
3756
  /* @__PURE__ */ jsxs37("div", { className: "medo-slider-field__inputs", children: [
3360
- /* @__PURE__ */ jsx38(NumberField, { ...field, "aria-label": names[0], minValue, maxValue: hi, value: lo, onChange: (v) => !Number.isNaN(v) && onChange([v, hi]) }),
3361
- /* @__PURE__ */ jsx38("span", { className: "medo-slider-field__dash", "aria-hidden": "true", children: "\u2013" }),
3362
- /* @__PURE__ */ jsx38(NumberField, { ...field, "aria-label": names[1], minValue: lo, maxValue, value: hi, onChange: (v) => !Number.isNaN(v) && onChange([lo, v]) })
3757
+ /* @__PURE__ */ jsx39(NumberField, { ...field, "aria-label": names[0], minValue, maxValue: hi, value: lo, onChange: (v) => !Number.isNaN(v) && onChange([v, hi]) }),
3758
+ /* @__PURE__ */ jsx39("span", { className: "medo-slider-field__dash", "aria-hidden": "true", children: "\u2013" }),
3759
+ /* @__PURE__ */ jsx39(NumberField, { ...field, "aria-label": names[1], minValue: lo, maxValue, value: hi, onChange: (v) => !Number.isNaN(v) && onChange([lo, v]) })
3363
3760
  ] })
3364
3761
  ] });
3365
3762
  }
3366
3763
  return /* @__PURE__ */ jsxs37("div", { className: "medo-slider-field medo-slider-field--single", children: [
3367
- /* @__PURE__ */ jsx38(Slider, { ...props, value, onChange, showValue: false }),
3368
- /* @__PURE__ */ jsx38(
3764
+ /* @__PURE__ */ jsx39(Slider, { ...props, value, onChange, showValue: false }),
3765
+ /* @__PURE__ */ jsx39(
3369
3766
  NumberField,
3370
3767
  {
3371
3768
  ...field,
@@ -3382,7 +3779,7 @@ function SliderField({ value, onChange, inputLabels, ...props }) {
3382
3779
 
3383
3780
  // src/alert/Alert.tsx
3384
3781
  import { CircleAlert as CircleAlert5, CircleCheck as CircleCheck2, Info as Info3, TriangleAlert as TriangleAlert2, X as X14 } from "lucide-react";
3385
- import { jsx as jsx39, jsxs as jsxs38 } from "react/jsx-runtime";
3782
+ import { jsx as jsx40, jsxs as jsxs38 } from "react/jsx-runtime";
3386
3783
  var ICONS = {
3387
3784
  info: Info3,
3388
3785
  success: CircleCheck2,
@@ -3396,27 +3793,28 @@ function Alert({
3396
3793
  children,
3397
3794
  actions,
3398
3795
  onDismiss,
3399
- dismissLabel = "Dismiss",
3796
+ dismissLabel,
3400
3797
  announce,
3401
3798
  className,
3402
3799
  ...props
3403
3800
  }) {
3801
+ const m = useMessages();
3404
3802
  const Icon = ICONS[tone];
3405
3803
  const role = announce ? tone === "danger" || tone === "warning" ? "alert" : "status" : void 0;
3406
3804
  return /* @__PURE__ */ jsxs38("div", { ...props, role: role ?? props.role, className: cx("medo-alert", `medo-alert--${tone}`, variant === "banner" && "medo-alert--banner", className), children: [
3407
- /* @__PURE__ */ jsx39(Icon, { className: "medo-alert__icon", "aria-hidden": "true" }),
3805
+ /* @__PURE__ */ jsx40(Icon, { className: "medo-alert__icon", "aria-hidden": "true" }),
3408
3806
  /* @__PURE__ */ jsxs38("div", { className: "medo-alert__content", children: [
3409
- /* @__PURE__ */ jsx39("p", { className: "medo-alert__title", children: title }),
3410
- children && /* @__PURE__ */ jsx39("div", { className: "medo-alert__description", children }),
3411
- actions && /* @__PURE__ */ jsx39("div", { className: "medo-alert__actions", children: actions })
3807
+ /* @__PURE__ */ jsx40("p", { className: "medo-alert__title", children: title }),
3808
+ children && /* @__PURE__ */ jsx40("div", { className: "medo-alert__description", children }),
3809
+ actions && /* @__PURE__ */ jsx40("div", { className: "medo-alert__actions", children: actions })
3412
3810
  ] }),
3413
- onDismiss && /* @__PURE__ */ jsx39(IconButton, { className: "medo-alert__close", variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx39(X14, {}), "aria-label": dismissLabel, onPress: onDismiss })
3811
+ onDismiss && /* @__PURE__ */ jsx40(IconButton, { className: "medo-alert__close", variant: "ghost", size: "sm", icon: /* @__PURE__ */ jsx40(X14, {}), "aria-label": dismissLabel ?? m.alert.dismiss, onPress: onDismiss })
3414
3812
  ] });
3415
3813
  }
3416
3814
 
3417
3815
  // src/card/Card.tsx
3418
3816
  import { Link as AriaLink7 } from "react-aria-components";
3419
- import { jsx as jsx40, jsxs as jsxs39 } from "react/jsx-runtime";
3817
+ import { jsx as jsx41, jsxs as jsxs39 } from "react/jsx-runtime";
3420
3818
  function Card({
3421
3819
  title,
3422
3820
  subtitle,
@@ -3448,17 +3846,17 @@ function Card({
3448
3846
  ),
3449
3847
  style,
3450
3848
  children: [
3451
- media && /* @__PURE__ */ jsx40("div", { className: "medo-card__media", children: media }),
3849
+ media && /* @__PURE__ */ jsx41("div", { className: "medo-card__media", children: media }),
3452
3850
  /* @__PURE__ */ jsxs39("div", { className: "medo-card__main", children: [
3453
3851
  /* @__PURE__ */ jsxs39("div", { className: "medo-card__header", children: [
3454
3852
  /* @__PURE__ */ jsxs39("div", { className: "medo-card__heading", children: [
3455
- /* @__PURE__ */ jsx40(Heading7, { className: "medo-card__title", children: interactive ? /* @__PURE__ */ jsx40(AriaLink7, { ...linkProps, href, className: "medo-card__link", children: title }) : title }),
3456
- subtitle && /* @__PURE__ */ jsx40("p", { className: "medo-card__subtitle", children: subtitle })
3853
+ /* @__PURE__ */ jsx41(Heading7, { className: "medo-card__title", children: interactive ? /* @__PURE__ */ jsx41(AriaLink7, { ...linkProps, href, className: "medo-card__link", children: title }) : title }),
3854
+ subtitle && /* @__PURE__ */ jsx41("p", { className: "medo-card__subtitle", children: subtitle })
3457
3855
  ] }),
3458
- headerActions && /* @__PURE__ */ jsx40("div", { className: "medo-card__header-actions", children: headerActions })
3856
+ headerActions && /* @__PURE__ */ jsx41("div", { className: "medo-card__header-actions", children: headerActions })
3459
3857
  ] }),
3460
- children && /* @__PURE__ */ jsx40("div", { className: "medo-card__body", children }),
3461
- footer && /* @__PURE__ */ jsx40("div", { className: "medo-card__footer", children: footer })
3858
+ children && /* @__PURE__ */ jsx41("div", { className: "medo-card__body", children }),
3859
+ footer && /* @__PURE__ */ jsx41("div", { className: "medo-card__footer", children: footer })
3462
3860
  ] })
3463
3861
  ]
3464
3862
  }
@@ -3466,6 +3864,7 @@ function Card({
3466
3864
  }
3467
3865
 
3468
3866
  // src/table/Table.tsx
3867
+ import { useEffect as useEffect14, useId as useId9, useRef as useRef15, useState as useState16 } from "react";
3469
3868
  import {
3470
3869
  Cell as AriaCell,
3471
3870
  Checkbox as AriaCheckbox,
@@ -3478,86 +3877,108 @@ import {
3478
3877
  useTableOptions
3479
3878
  } from "react-aria-components";
3480
3879
  import { ArrowDown, ArrowUp, ArrowUpDown, Check as Check6, Minus as Minus2 } from "lucide-react";
3481
- import { jsx as jsx41, jsxs as jsxs40 } from "react/jsx-runtime";
3880
+ import { jsx as jsx42, jsxs as jsxs40 } from "react/jsx-runtime";
3881
+ function useScrollsSideways() {
3882
+ const ref = useRef15(null);
3883
+ const [scrolls, setScrolls] = useState16(false);
3884
+ useEffect14(() => {
3885
+ const el = ref.current;
3886
+ if (!el || typeof ResizeObserver === "undefined") return;
3887
+ const check = () => setScrolls(el.scrollWidth > el.clientWidth + 1);
3888
+ const observer = new ResizeObserver(check);
3889
+ observer.observe(el);
3890
+ if (el.firstElementChild) observer.observe(el.firstElementChild);
3891
+ check();
3892
+ return () => observer.disconnect();
3893
+ }, []);
3894
+ return [ref, scrolls];
3895
+ }
3482
3896
  function StaticTable({ children, caption, captionHidden, density = "standard", striped, plain: plain2, className, style }) {
3483
- return /* @__PURE__ */ jsx41("div", { className: cx("medo-table-container", plain2 && "medo-table-container--plain", className), style, children: /* @__PURE__ */ jsxs40("table", { className: cx("medo-table", density === "compact" && "medo-table--compact", striped && "medo-table--striped"), children: [
3484
- caption && /* @__PURE__ */ jsx41("caption", { className: captionHidden ? "medo-visually-hidden" : void 0, children: caption }),
3897
+ const [ref, scrolls] = useScrollsSideways();
3898
+ const captionId = useId9();
3899
+ const m = useMessages();
3900
+ const region = scrolls ? caption ? { role: "region", tabIndex: 0, "aria-labelledby": captionId } : { role: "region", tabIndex: 0, "aria-label": m.table.scrollRegion } : {};
3901
+ return /* @__PURE__ */ jsx42("div", { ref, ...region, className: cx("medo-table-container", plain2 && "medo-table-container--plain", className), style, children: /* @__PURE__ */ jsxs40("table", { className: cx("medo-table", density === "compact" && "medo-table--compact", striped && "medo-table--striped"), children: [
3902
+ caption && /* @__PURE__ */ jsx42("caption", { id: captionId, className: captionHidden ? "medo-visually-hidden" : void 0, children: caption }),
3485
3903
  children
3486
3904
  ] }) });
3487
3905
  }
3488
3906
  function Table({ density = "standard", striped, plain: plain2, toolbar, footer, className, style, ...props }) {
3489
- const table = /* @__PURE__ */ jsx41(AriaTable, { ...props, className: cx("medo-table", density === "compact" && "medo-table--compact", striped && "medo-table--striped") });
3907
+ const table = /* @__PURE__ */ jsx42(AriaTable, { ...props, className: cx("medo-table", density === "compact" && "medo-table--compact", striped && "medo-table--striped") });
3490
3908
  if (!toolbar && !footer) {
3491
- return /* @__PURE__ */ jsx41("div", { className: cx("medo-table-container", plain2 && "medo-table-container--plain", className), style, children: table });
3909
+ return /* @__PURE__ */ jsx42("div", { className: cx("medo-table-container", plain2 && "medo-table-container--plain", className), style, children: table });
3492
3910
  }
3493
3911
  return /* @__PURE__ */ jsxs40("div", { className: cx("medo-table-frame", plain2 && "medo-table-frame--plain", className), style, children: [
3494
- toolbar && /* @__PURE__ */ jsx41("div", { className: "medo-table__toolbar", children: toolbar }),
3495
- /* @__PURE__ */ jsx41("div", { className: "medo-table-container medo-table-container--plain", children: table }),
3496
- footer && /* @__PURE__ */ jsx41("div", { className: "medo-table__footer", children: footer })
3912
+ toolbar && /* @__PURE__ */ jsx42("div", { className: "medo-table__toolbar", children: toolbar }),
3913
+ /* @__PURE__ */ jsx42("div", { className: "medo-table-container medo-table-container--plain", children: table }),
3914
+ footer && /* @__PURE__ */ jsx42("div", { className: "medo-table__footer", children: footer })
3497
3915
  ] });
3498
3916
  }
3499
3917
  function SelectionCheckbox() {
3500
- return /* @__PURE__ */ jsx41(AriaCheckbox, { slot: "selection", className: "medo-choice medo-checkbox medo-choice--md medo-choice__button", children: ({ isSelected, isIndeterminate }) => /* @__PURE__ */ jsx41("span", { className: "medo-choice__control", "aria-hidden": "true", children: isIndeterminate ? /* @__PURE__ */ jsx41(Minus2, {}) : isSelected ? /* @__PURE__ */ jsx41(Check6, {}) : null }) });
3918
+ return /* @__PURE__ */ jsx42(AriaCheckbox, { slot: "selection", className: "medo-choice medo-checkbox medo-choice--md medo-choice__button", children: ({ isSelected, isIndeterminate }) => /* @__PURE__ */ jsx42("span", { className: "medo-choice__control", "aria-hidden": "true", children: isIndeterminate ? /* @__PURE__ */ jsx42(Minus2, {}) : isSelected ? /* @__PURE__ */ jsx42(Check6, {}) : null }) });
3501
3919
  }
3502
3920
  function TableHeader({ columns, children, ...props }) {
3503
3921
  const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions();
3504
3922
  return /* @__PURE__ */ jsxs40(AriaTableHeader, { ...props, className: "medo-table__header", children: [
3505
- allowsDragging && /* @__PURE__ */ jsx41(AriaColumn, { className: "medo-table__column medo-table__column--utility" }),
3506
- selectionBehavior === "toggle" && selectionMode !== "none" && /* @__PURE__ */ jsx41(AriaColumn, { className: "medo-table__column medo-table__column--utility", children: selectionMode === "multiple" && /* @__PURE__ */ jsx41(SelectionCheckbox, {}) }),
3507
- /* @__PURE__ */ jsx41(Collection3, { items: columns, children })
3923
+ allowsDragging && /* @__PURE__ */ jsx42(AriaColumn, { className: "medo-table__column medo-table__column--utility" }),
3924
+ selectionBehavior === "toggle" && selectionMode !== "none" && /* @__PURE__ */ jsx42(AriaColumn, { className: "medo-table__column medo-table__column--utility", children: selectionMode === "multiple" && /* @__PURE__ */ jsx42(SelectionCheckbox, {}) }),
3925
+ /* @__PURE__ */ jsx42(Collection3, { items: columns, children })
3508
3926
  ] });
3509
3927
  }
3510
3928
  function Column({ children, align = "start", ...props }) {
3511
- return /* @__PURE__ */ jsx41(AriaColumn, { ...props, "data-align": align, className: "medo-table__column", children: ({ allowsSorting, sortDirection }) => /* @__PURE__ */ jsxs40("span", { className: "medo-table__column-inner", children: [
3929
+ return /* @__PURE__ */ jsx42(AriaColumn, { ...props, "data-align": align, className: "medo-table__column", children: ({ allowsSorting, sortDirection }) => /* @__PURE__ */ jsxs40("span", { className: "medo-table__column-inner", children: [
3512
3930
  children,
3513
- allowsSorting && (sortDirection === "ascending" ? /* @__PURE__ */ jsx41(ArrowUp, { className: "medo-table__sort", "aria-hidden": "true" }) : sortDirection === "descending" ? /* @__PURE__ */ jsx41(ArrowDown, { className: "medo-table__sort", "aria-hidden": "true" }) : /* @__PURE__ */ jsx41(ArrowUpDown, { className: "medo-table__sort", "aria-hidden": "true" }))
3931
+ allowsSorting && (sortDirection === "ascending" ? /* @__PURE__ */ jsx42(ArrowUp, { className: "medo-table__sort", "aria-hidden": "true" }) : sortDirection === "descending" ? /* @__PURE__ */ jsx42(ArrowDown, { className: "medo-table__sort", "aria-hidden": "true" }) : /* @__PURE__ */ jsx42(ArrowUpDown, { className: "medo-table__sort", "aria-hidden": "true" }))
3514
3932
  ] }) });
3515
3933
  }
3516
3934
  function TableBody(props) {
3517
- return /* @__PURE__ */ jsx41(AriaTableBody, { ...props, className: "medo-table__body" });
3935
+ return /* @__PURE__ */ jsx42(AriaTableBody, { ...props, className: "medo-table__body" });
3518
3936
  }
3519
3937
  function Row({ id, columns, children, ...props }) {
3520
3938
  const { selectionBehavior, selectionMode, allowsDragging } = useTableOptions();
3521
3939
  return /* @__PURE__ */ jsxs40(AriaRow, { id, ...props, className: "medo-table__row", children: [
3522
- allowsDragging && /* @__PURE__ */ jsx41(AriaCell, { className: "medo-table__cell medo-table__cell--utility" }),
3523
- selectionBehavior === "toggle" && selectionMode !== "none" && /* @__PURE__ */ jsx41(AriaCell, { className: "medo-table__cell medo-table__cell--utility", children: /* @__PURE__ */ jsx41(SelectionCheckbox, {}) }),
3524
- /* @__PURE__ */ jsx41(Collection3, { items: columns, children })
3940
+ allowsDragging && /* @__PURE__ */ jsx42(AriaCell, { className: "medo-table__cell medo-table__cell--utility" }),
3941
+ selectionBehavior === "toggle" && selectionMode !== "none" && /* @__PURE__ */ jsx42(AriaCell, { className: "medo-table__cell medo-table__cell--utility", children: /* @__PURE__ */ jsx42(SelectionCheckbox, {}) }),
3942
+ /* @__PURE__ */ jsx42(Collection3, { items: columns, children })
3525
3943
  ] });
3526
3944
  }
3527
3945
  function Cell({ align = "start", ...props }) {
3528
- return /* @__PURE__ */ jsx41(AriaCell, { ...props, "data-align": align, className: "medo-table__cell" });
3946
+ return /* @__PURE__ */ jsx42(AriaCell, { ...props, "data-align": align, className: "medo-table__cell" });
3529
3947
  }
3530
3948
 
3531
3949
  // src/table/ColumnsMenu.tsx
3532
3950
  import { Columns3 } from "lucide-react";
3533
- import { jsx as jsx42, jsxs as jsxs41 } from "react/jsx-runtime";
3534
- function ColumnsMenu({ columns, visibleColumns, onVisibleColumnsChange, label = "Columns", title = "Show columns" }) {
3951
+ import { jsx as jsx43, jsxs as jsxs41 } from "react/jsx-runtime";
3952
+ function ColumnsMenu({ columns, visibleColumns, onVisibleColumnsChange, label: labelProp, title: titleProp }) {
3953
+ const m = useMessages();
3954
+ const label = labelProp ?? m.table.columns;
3955
+ const title = titleProp ?? m.table.showColumns;
3535
3956
  const locked = columns.filter((c) => c.isLocked).map((c) => c.id);
3536
3957
  return /* @__PURE__ */ jsxs41(PopoverTrigger, { children: [
3537
- /* @__PURE__ */ jsx42(Button, { variant: "ghost", size: "sm", startIcon: /* @__PURE__ */ jsx42(Columns3, {}), children: label }),
3538
- /* @__PURE__ */ jsx42(Popover5, { size: "sm", "aria-label": title, children: /* @__PURE__ */ jsx42(
3958
+ /* @__PURE__ */ jsx43(Button, { variant: "ghost", size: "sm", startIcon: /* @__PURE__ */ jsx43(Columns3, {}), children: label }),
3959
+ /* @__PURE__ */ jsx43(Popover5, { size: "sm", "aria-label": title, children: /* @__PURE__ */ jsx43(
3539
3960
  CheckboxGroup,
3540
3961
  {
3541
3962
  label: title,
3542
3963
  value: visibleColumns,
3543
3964
  onChange: (ids) => onVisibleColumnsChange(columns.map((c) => c.id).filter((id) => ids.includes(id) || locked.includes(id))),
3544
- children: columns.map((c) => /* @__PURE__ */ jsx42(Checkbox, { value: c.id, isDisabled: c.isLocked, children: c.label }, c.id))
3965
+ children: columns.map((c) => /* @__PURE__ */ jsx43(Checkbox, { value: c.id, isDisabled: c.isLocked, children: c.label }, c.id))
3545
3966
  }
3546
3967
  ) })
3547
3968
  ] });
3548
3969
  }
3549
3970
 
3550
3971
  // src/upload/Upload.tsx
3551
- import { useEffect as useEffect14, useId as useId9, useLayoutEffect as useLayoutEffect7, useMemo as useMemo2, useRef as useRef15, useState as useState16 } from "react";
3972
+ import { useEffect as useEffect15, useId as useId10, useLayoutEffect as useLayoutEffect7, useMemo as useMemo2, useRef as useRef16, useState as useState17 } from "react";
3552
3973
  import {
3553
3974
  Button as AriaButton15,
3554
3975
  DropZone,
3555
3976
  FileTrigger as AriaFileTrigger,
3556
3977
  Text as Text9,
3557
- useLocale as useLocale3
3978
+ useLocale as useLocale4
3558
3979
  } from "react-aria-components";
3559
3980
  import { CircleAlert as CircleAlert6, CircleCheck as CircleCheck3, CloudUpload, FileText as FileText2, Image as ImageIcon, RotateCw, Trash2, Upload, X as X15 } from "lucide-react";
3560
- import { Fragment as Fragment20, jsx as jsx43, jsxs as jsxs42 } from "react/jsx-runtime";
3981
+ import { Fragment as Fragment20, jsx as jsx44, jsxs as jsxs42 } from "react/jsx-runtime";
3561
3982
  var units = ["byte", "kilobyte", "megabyte", "gigabyte"];
3562
3983
  function unitOf(bytes) {
3563
3984
  let i = 0;
@@ -3593,43 +4014,27 @@ function FileName({ name, className }) {
3593
4014
  const start = name.length > keep + 4 ? name.slice(0, -keep) : name;
3594
4015
  const end = name.length > keep + 4 ? name.slice(-keep) : "";
3595
4016
  return /* @__PURE__ */ jsxs42("span", { className: cx("medo-file-name", className), children: [
3596
- /* @__PURE__ */ jsx43("span", { className: "medo-visually-hidden", children: name }),
4017
+ /* @__PURE__ */ jsx44("span", { className: "medo-visually-hidden", children: name }),
3597
4018
  /* @__PURE__ */ jsxs42("span", { className: "medo-file-name__visual", title: name, "aria-hidden": "true", children: [
3598
- /* @__PURE__ */ jsx43("span", { className: "medo-file-name__start", children: start }),
3599
- end && /* @__PURE__ */ jsx43("span", { className: "medo-file-name__end", children: end })
4019
+ /* @__PURE__ */ jsx44("span", { className: "medo-file-name__start", children: start }),
4020
+ end && /* @__PURE__ */ jsx44("span", { className: "medo-file-name__end", children: end })
3600
4021
  ] })
3601
4022
  ] });
3602
4023
  }
3603
- var defaultUploadTexts = {
3604
- title: "Drag and drop files here",
3605
- dropTitle: "Drop files to upload",
3606
- chooseFiles: "Choose files",
3607
- chooseFile: "Choose file",
3608
- listLabel: "Uploaded files",
3609
- cancel: (name) => `Cancel upload of ${name}`,
3610
- remove: (name) => `Remove ${name}`,
3611
- retry: (name) => `Retry ${name}`,
3612
- retryShort: "Retry",
3613
- uploading: (name) => `Uploading ${name}`,
3614
- progress: (loaded, total, percent) => `${loaded} of ${total} \xB7 ${percent} %`,
3615
- typeNotAllowed: (names, types) => `${names} ${names.includes(",") ? "are" : "is"} not allowed.${types ? ` Use ${types}.` : ""}`,
3616
- tooLarge: (size, max) => `File is ${size} \u2013 max. ${max} allowed`,
3617
- tooMany: (max) => `You can add up to ${max} files. Remove one to add another.`,
3618
- uploaded: (name) => `${name} uploaded`,
3619
- failed: (name, error) => `${name}: ${error}`
3620
- };
4024
+ var defaultUploadTexts = en.upload;
3621
4025
  var isImage = (file) => !!file.previewUrl && (!file.type || file.type.startsWith("image/"));
3622
4026
  var percentOf = (file) => file.loaded != null && file.size > 0 ? Math.min(100, Math.round(file.loaded / file.size * 100)) : void 0;
3623
4027
  function FileItem({ file, onRemove, onCancel, onRetry, texts: own, className }) {
3624
- const t = { ...defaultUploadTexts, ...own };
3625
- const { locale } = useLocale3();
4028
+ const m = useMessages();
4029
+ const t = { ...m.upload, ...own };
4030
+ const { locale } = useLocale4();
3626
4031
  const percent = percentOf(file);
3627
4032
  const size = formatBytes(file.size, locale);
3628
4033
  let meta;
3629
4034
  if (file.status === "uploading") {
3630
4035
  meta = /* @__PURE__ */ jsxs42(Fragment20, { children: [
3631
- /* @__PURE__ */ jsx43("span", { className: "medo-file-item__meta", children: percent != null ? t.progress(formatLoaded(file.loaded ?? 0, file.size, locale), size, percent) : size }),
3632
- /* @__PURE__ */ jsx43(
4036
+ /* @__PURE__ */ jsx44("span", { className: "medo-file-item__meta", children: percent != null ? t.progress(formatLoaded(file.loaded ?? 0, file.size, locale), size, percent) : size }),
4037
+ /* @__PURE__ */ jsx44(
3633
4038
  ProgressBar,
3634
4039
  {
3635
4040
  size: "sm",
@@ -3644,33 +4049,34 @@ function FileItem({ file, onRemove, onCancel, onRetry, texts: own, className })
3644
4049
  } else {
3645
4050
  const error = file.status === "error";
3646
4051
  meta = /* @__PURE__ */ jsxs42("span", { className: cx("medo-file-item__meta", error && "medo-file-item__meta--error"), children: [
3647
- error ? /* @__PURE__ */ jsx43(CircleAlert6, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx43(CircleCheck3, { "aria-hidden": "true", className: "medo-file-item__done" }),
3648
- /* @__PURE__ */ jsx43("span", { children: error ? file.error : size })
4052
+ error ? /* @__PURE__ */ jsx44(CircleAlert6, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx44(CircleCheck3, { "aria-hidden": "true", className: "medo-file-item__done" }),
4053
+ /* @__PURE__ */ jsx44("span", { children: error ? file.error : size })
3649
4054
  ] });
3650
4055
  }
3651
4056
  return /* @__PURE__ */ jsxs42("div", { className: cx("medo-file-item", `medo-file-item--${file.status}`, className), children: [
3652
- isImage(file) ? /* @__PURE__ */ jsx43("img", { className: "medo-file-item__thumb", src: file.previewUrl, alt: "" }) : /* @__PURE__ */ jsx43("span", { className: "medo-file-item__icon", "aria-hidden": "true", children: file.type?.startsWith("image/") ? /* @__PURE__ */ jsx43(ImageIcon, {}) : /* @__PURE__ */ jsx43(FileText2, {}) }),
4057
+ isImage(file) ? /* @__PURE__ */ jsx44("img", { className: "medo-file-item__thumb", src: file.previewUrl, alt: "" }) : /* @__PURE__ */ jsx44("span", { className: "medo-file-item__icon", "aria-hidden": "true", children: file.type?.startsWith("image/") ? /* @__PURE__ */ jsx44(ImageIcon, {}) : /* @__PURE__ */ jsx44(FileText2, {}) }),
3653
4058
  /* @__PURE__ */ jsxs42("div", { className: "medo-file-item__content", children: [
3654
- /* @__PURE__ */ jsx43(FileName, { name: file.name, className: "medo-file-item__name" }),
4059
+ /* @__PURE__ */ jsx44(FileName, { name: file.name, className: "medo-file-item__name" }),
3655
4060
  meta
3656
4061
  ] }),
3657
4062
  /* @__PURE__ */ jsxs42("div", { className: "medo-file-item__actions", children: [
3658
- file.status === "uploading" && /* @__PURE__ */ jsx43(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx43(X15, {}), "aria-label": t.cancel(file.name), onPress: () => (onCancel ?? onRemove)(file.id) }),
3659
- file.status === "error" && onRetry && file.canRetry !== false && /* @__PURE__ */ jsx43(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx43(RotateCw, {}), "aria-label": t.retry(file.name), onPress: () => onRetry(file.id) }),
3660
- file.status !== "uploading" && /* @__PURE__ */ jsx43(IconButton, { size: "sm", icon: file.status === "done" ? /* @__PURE__ */ jsx43(Trash2, {}) : /* @__PURE__ */ jsx43(X15, {}), "aria-label": t.remove(file.name), onPress: () => onRemove(file.id) })
4063
+ file.status === "uploading" && /* @__PURE__ */ jsx44(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx44(X15, {}), "aria-label": t.cancel(file.name), onPress: () => (onCancel ?? onRemove)(file.id) }),
4064
+ file.status === "error" && onRetry && file.canRetry !== false && /* @__PURE__ */ jsx44(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx44(RotateCw, {}), "aria-label": t.retry(file.name), onPress: () => onRetry(file.id) }),
4065
+ file.status !== "uploading" && /* @__PURE__ */ jsx44(IconButton, { size: "sm", icon: file.status === "done" ? /* @__PURE__ */ jsx44(Trash2, {}) : /* @__PURE__ */ jsx44(X15, {}), "aria-label": t.remove(file.name), onPress: () => onRemove(file.id) })
3661
4066
  ] })
3662
4067
  ] });
3663
4068
  }
3664
4069
  function FileTile({ file, onRemove, onCancel, onRetry, texts: own, className }) {
3665
- const t = { ...defaultUploadTexts, ...own };
4070
+ const m = useMessages();
4071
+ const t = { ...m.upload, ...own };
3666
4072
  const percent = percentOf(file);
3667
4073
  const retry = file.status === "error" && onRetry && file.canRetry !== false;
3668
4074
  return /* @__PURE__ */ jsxs42("div", { className: cx("medo-file-tile", `medo-file-tile--${file.status}`, className), children: [
3669
4075
  /* @__PURE__ */ jsxs42("div", { className: "medo-file-tile__media", children: [
3670
- file.previewUrl ? /* @__PURE__ */ jsx43("img", { className: "medo-file-tile__image", src: file.previewUrl, alt: "" }) : /* @__PURE__ */ jsx43("span", { className: "medo-file-tile__placeholder", "aria-hidden": "true", children: /* @__PURE__ */ jsx43(ImageIcon, {}) }),
4076
+ file.previewUrl ? /* @__PURE__ */ jsx44("img", { className: "medo-file-tile__image", src: file.previewUrl, alt: "" }) : /* @__PURE__ */ jsx44("span", { className: "medo-file-tile__placeholder", "aria-hidden": "true", children: /* @__PURE__ */ jsx44(ImageIcon, {}) }),
3671
4077
  file.status === "uploading" && /* @__PURE__ */ jsxs42("div", { className: "medo-file-tile__overlay", children: [
3672
- /* @__PURE__ */ jsx43("span", { className: "medo-file-tile__percent", "aria-hidden": "true", children: percent != null ? `${percent} %` : "" }),
3673
- /* @__PURE__ */ jsx43(
4078
+ /* @__PURE__ */ jsx44("span", { className: "medo-file-tile__percent", "aria-hidden": "true", children: percent != null ? `${percent} %` : "" }),
4079
+ /* @__PURE__ */ jsx44(
3674
4080
  ProgressBar,
3675
4081
  {
3676
4082
  size: "sm",
@@ -3683,15 +4089,15 @@ function FileTile({ file, onRemove, onCancel, onRetry, texts: own, className })
3683
4089
  )
3684
4090
  ] }),
3685
4091
  file.status === "error" && (retry ? /* @__PURE__ */ jsxs42(AriaButton15, { className: "medo-file-tile__overlay medo-file-tile__retry", "aria-label": t.retry(file.name), onPress: () => onRetry(file.id), children: [
3686
- /* @__PURE__ */ jsx43(CircleAlert6, { "aria-hidden": "true" }),
3687
- /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", children: t.retryShort })
3688
- ] }) : /* @__PURE__ */ jsx43("div", { className: "medo-file-tile__overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsx43(CircleAlert6, {}) })),
3689
- /* @__PURE__ */ jsx43(
4092
+ /* @__PURE__ */ jsx44(CircleAlert6, { "aria-hidden": "true" }),
4093
+ /* @__PURE__ */ jsx44("span", { "aria-hidden": "true", children: t.retryShort })
4094
+ ] }) : /* @__PURE__ */ jsx44("div", { className: "medo-file-tile__overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsx44(CircleAlert6, {}) })),
4095
+ /* @__PURE__ */ jsx44(
3690
4096
  IconButton,
3691
4097
  {
3692
4098
  variant: "media",
3693
4099
  size: "sm",
3694
- icon: /* @__PURE__ */ jsx43(X15, {}),
4100
+ icon: /* @__PURE__ */ jsx44(X15, {}),
3695
4101
  "aria-label": file.status === "uploading" ? t.cancel(file.name) : t.remove(file.name),
3696
4102
  onPress: () => (file.status === "uploading" ? onCancel ?? onRemove : onRemove)(file.id),
3697
4103
  className: "medo-file-tile__remove"
@@ -3704,7 +4110,7 @@ function FileTile({ file, onRemove, onCancel, onRetry, texts: own, className })
3704
4110
  ": "
3705
4111
  ] }),
3706
4112
  file.error
3707
- ] }) : /* @__PURE__ */ jsx43(FileName, { name: file.name, className: "medo-file-tile__caption" })
4113
+ ] }) : /* @__PURE__ */ jsx44(FileName, { name: file.name, className: "medo-file-tile__caption" })
3708
4114
  ] });
3709
4115
  }
3710
4116
  async function filesFrom(e) {
@@ -3723,10 +4129,11 @@ function Dropzone({
3723
4129
  className,
3724
4130
  ...props
3725
4131
  }) {
3726
- const t = { ...defaultUploadTexts, ...own };
3727
- const hintId = useId9();
3728
- const errorId = useId9();
3729
- return /* @__PURE__ */ jsx43(
4132
+ const m = useMessages();
4133
+ const t = { ...m.upload, ...own };
4134
+ const hintId = useId10();
4135
+ const errorId = useId10();
4136
+ return /* @__PURE__ */ jsx44(
3730
4137
  DropZone,
3731
4138
  {
3732
4139
  "aria-labelledby": props["aria-labelledby"],
@@ -3734,16 +4141,16 @@ function Dropzone({
3734
4141
  onDrop: async (e) => onSelect(await filesFrom(e)),
3735
4142
  className: cx("medo-dropzone", !!errorMessage && "medo-dropzone--invalid", className),
3736
4143
  children: ({ isDropTarget }) => /* @__PURE__ */ jsxs42(Fragment20, { children: [
3737
- /* @__PURE__ */ jsx43(IconTile, { size: "md", children: /* @__PURE__ */ jsx43(CloudUpload, {}) }),
3738
- /* @__PURE__ */ jsx43(Text9, { slot: "label", className: "medo-dropzone__title", "aria-disabled": isDisabled || void 0, children: isDropTarget ? t.dropTitle : t.title }),
3739
- /* @__PURE__ */ jsx43(
4144
+ /* @__PURE__ */ jsx44(IconTile, { size: "md", children: /* @__PURE__ */ jsx44(CloudUpload, {}) }),
4145
+ /* @__PURE__ */ jsx44(Text9, { slot: "label", className: "medo-dropzone__title", "aria-disabled": isDisabled || void 0, children: isDropTarget ? t.dropTitle : t.title }),
4146
+ /* @__PURE__ */ jsx44(
3740
4147
  AriaFileTrigger,
3741
4148
  {
3742
4149
  acceptedFileTypes,
3743
4150
  allowsMultiple,
3744
4151
  defaultCamera,
3745
4152
  onSelect: (list) => list && onSelect([...list]),
3746
- children: /* @__PURE__ */ jsx43(
4153
+ children: /* @__PURE__ */ jsx44(
3747
4154
  Button,
3748
4155
  {
3749
4156
  variant: "secondary",
@@ -3756,10 +4163,10 @@ function Dropzone({
3756
4163
  )
3757
4164
  }
3758
4165
  ),
3759
- hint && /* @__PURE__ */ jsx43("span", { id: hintId, className: "medo-dropzone__hint", "aria-disabled": isDisabled || void 0, children: hint }),
4166
+ hint && /* @__PURE__ */ jsx44("span", { id: hintId, className: "medo-dropzone__hint", "aria-disabled": isDisabled || void 0, children: hint }),
3760
4167
  errorMessage && /* @__PURE__ */ jsxs42("span", { id: errorId, className: "medo-field__error medo-dropzone__error", children: [
3761
- /* @__PURE__ */ jsx43(CircleAlert6, { "aria-hidden": "true" }),
3762
- /* @__PURE__ */ jsx43("span", { children: errorMessage })
4168
+ /* @__PURE__ */ jsx44(CircleAlert6, { "aria-hidden": "true" }),
4169
+ /* @__PURE__ */ jsx44("span", { children: errorMessage })
3763
4170
  ] })
3764
4171
  ] })
3765
4172
  }
@@ -3778,29 +4185,30 @@ function FileTrigger({
3778
4185
  texts: own,
3779
4186
  className
3780
4187
  }) {
3781
- const t = { ...defaultUploadTexts, ...own };
3782
- const labelId = useId9();
3783
- const buttonId = useId9();
3784
- const hintId = useId9();
3785
- const errorId = useId9();
4188
+ const m = useMessages();
4189
+ const t = { ...m.upload, ...own };
4190
+ const labelId = useId10();
4191
+ const buttonId = useId10();
4192
+ const hintId = useId10();
4193
+ const errorId = useId10();
3786
4194
  return /* @__PURE__ */ jsxs42("div", { className: cx("medo-field", "medo-file-trigger", className), children: [
3787
4195
  label && /* @__PURE__ */ jsxs42("span", { id: labelId, className: "medo-field__label", children: [
3788
4196
  label,
3789
- isRequired && /* @__PURE__ */ jsx43("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
4197
+ isRequired && /* @__PURE__ */ jsx44("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
3790
4198
  ] }),
3791
- /* @__PURE__ */ jsx43("div", { children: /* @__PURE__ */ jsx43(
4199
+ /* @__PURE__ */ jsx44("div", { children: /* @__PURE__ */ jsx44(
3792
4200
  AriaFileTrigger,
3793
4201
  {
3794
4202
  acceptedFileTypes,
3795
4203
  allowsMultiple,
3796
4204
  defaultCamera,
3797
4205
  onSelect: (list) => list && onSelect([...list]),
3798
- children: /* @__PURE__ */ jsx43(
4206
+ children: /* @__PURE__ */ jsx44(
3799
4207
  Button,
3800
4208
  {
3801
4209
  id: buttonId,
3802
4210
  variant: "secondary",
3803
- startIcon: /* @__PURE__ */ jsx43(Upload, {}),
4211
+ startIcon: /* @__PURE__ */ jsx44(Upload, {}),
3804
4212
  isDisabled,
3805
4213
  className: "medo-upload__choose",
3806
4214
  "aria-labelledby": label ? `${labelId} ${buttonId}` : void 0,
@@ -3811,10 +4219,10 @@ function FileTrigger({
3811
4219
  }
3812
4220
  ) }),
3813
4221
  (hint || errorMessage) && /* @__PURE__ */ jsxs42("div", { className: "medo-field__footer", children: [
3814
- hint && !errorMessage && /* @__PURE__ */ jsx43("span", { id: hintId, className: "medo-field__description", children: hint }),
4222
+ hint && !errorMessage && /* @__PURE__ */ jsx44("span", { id: hintId, className: "medo-field__description", children: hint }),
3815
4223
  errorMessage && /* @__PURE__ */ jsxs42("span", { id: errorId, className: "medo-field__error", children: [
3816
- /* @__PURE__ */ jsx43(CircleAlert6, { "aria-hidden": "true" }),
3817
- /* @__PURE__ */ jsx43("span", { children: errorMessage })
4224
+ /* @__PURE__ */ jsx44(CircleAlert6, { "aria-hidden": "true" }),
4225
+ /* @__PURE__ */ jsx44("span", { children: errorMessage })
3818
4226
  ] })
3819
4227
  ] })
3820
4228
  ] });
@@ -3840,14 +4248,15 @@ function UploadField({
3840
4248
  texts: own,
3841
4249
  className
3842
4250
  }) {
3843
- const t = useMemo2(() => ({ ...defaultUploadTexts, ...own }), [own]);
3844
- const { locale } = useLocale3();
4251
+ const m = useMessages();
4252
+ const t = useMemo2(() => ({ ...m.upload, ...own }), [m, own]);
4253
+ const { locale } = useLocale4();
3845
4254
  const mobile = useMediaQuery(MOBILE_QUERY);
3846
- const labelId = useId9();
3847
- const rootRef = useRef15(null);
3848
- const [rejected, setRejected] = useState16([]);
3849
- const [pickerError, setPickerError] = useState16();
3850
- const [announcement, setAnnouncement] = useState16("");
4255
+ const labelId = useId10();
4256
+ const rootRef = useRef16(null);
4257
+ const [rejected, setRejected] = useState17([]);
4258
+ const [pickerError, setPickerError] = useState17();
4259
+ const [announcement, setAnnouncement] = useState17("");
3851
4260
  const compact = layout === "compact" || layout !== "list" && mobile;
3852
4261
  const grid = layout === "grid";
3853
4262
  const allowsMultiple = maxFiles !== 1;
@@ -3878,8 +4287,8 @@ function UploadField({
3878
4287
  setAnnouncement([...messages, ...errors.map((e) => t.failed(e.name, e.error))].join(" "));
3879
4288
  if (ok.length) onAdd(ok);
3880
4289
  };
3881
- const previous = useRef15(/* @__PURE__ */ new Map());
3882
- useEffect14(() => {
4290
+ const previous = useRef16(/* @__PURE__ */ new Map());
4291
+ useEffect15(() => {
3883
4292
  const said = [];
3884
4293
  for (const f of files) {
3885
4294
  const before = previous.current.get(f.id);
@@ -3890,7 +4299,7 @@ function UploadField({
3890
4299
  previous.current = new Map(files.map((f) => [f.id, f.status]));
3891
4300
  if (said.length) setAnnouncement(said.join(" "));
3892
4301
  }, [files, t]);
3893
- const focusAt = useRef15(null);
4302
+ const focusAt = useRef16(null);
3894
4303
  const all = [...files, ...rejected];
3895
4304
  useLayoutEffect7(() => {
3896
4305
  if (focusAt.current == null) return;
@@ -3923,22 +4332,22 @@ function UploadField({
3923
4332
  "aria-label": label || compact ? void 0 : ariaLabel,
3924
4333
  className: cx("medo-upload", grid && "medo-upload--grid", compact && "medo-upload--compact", className),
3925
4334
  children: [
3926
- compact ? /* @__PURE__ */ jsx43(FileTrigger, { ...picker, label, isRequired }) : /* @__PURE__ */ jsxs42(Fragment20, { children: [
4335
+ compact ? /* @__PURE__ */ jsx44(FileTrigger, { ...picker, label, isRequired }) : /* @__PURE__ */ jsxs42(Fragment20, { children: [
3927
4336
  label && /* @__PURE__ */ jsxs42("span", { id: labelId, className: "medo-field__label", children: [
3928
4337
  label,
3929
- isRequired && /* @__PURE__ */ jsx43("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
4338
+ isRequired && /* @__PURE__ */ jsx44("span", { className: "medo-field__required", "aria-hidden": "true", children: "*" })
3930
4339
  ] }),
3931
- /* @__PURE__ */ jsx43(Dropzone, { ...picker, "aria-labelledby": label ? labelId : void 0 })
4340
+ /* @__PURE__ */ jsx44(Dropzone, { ...picker, "aria-labelledby": label ? labelId : void 0 })
3932
4341
  ] }),
3933
- all.length > 0 && /* @__PURE__ */ jsx43("ul", { className: cx("medo-upload__list", grid && "medo-upload__list--grid"), "aria-label": t.listLabel, children: all.map((file) => /* @__PURE__ */ jsx43("li", { className: "medo-upload__item", children: grid ? /* @__PURE__ */ jsx43(FileTile, { file, ...actions }) : /* @__PURE__ */ jsx43(FileItem, { file, ...actions }) }, file.id)) }),
3934
- /* @__PURE__ */ jsx43("span", { role: "status", className: "medo-visually-hidden", children: announcement })
4342
+ all.length > 0 && /* @__PURE__ */ jsx44("ul", { className: cx("medo-upload__list", grid && "medo-upload__list--grid"), "aria-label": t.listLabel, children: all.map((file) => /* @__PURE__ */ jsx44("li", { className: "medo-upload__item", children: grid ? /* @__PURE__ */ jsx44(FileTile, { file, ...actions }) : /* @__PURE__ */ jsx44(FileItem, { file, ...actions }) }, file.id)) }),
4343
+ /* @__PURE__ */ jsx44("span", { role: "status", className: "medo-visually-hidden", children: announcement })
3935
4344
  ]
3936
4345
  }
3937
4346
  );
3938
4347
  }
3939
4348
 
3940
4349
  // src/date-time/Calendar.tsx
3941
- import { useEffect as useEffect15, useMemo as useMemo3, useRef as useRef16, useState as useState17 } from "react";
4350
+ import { useEffect as useEffect16, useMemo as useMemo3, useRef as useRef17, useState as useState18 } from "react";
3942
4351
  import {
3943
4352
  Button as AriaButton16,
3944
4353
  Calendar as AriaCalendar,
@@ -3948,22 +4357,12 @@ import {
3948
4357
  CalendarGridHeader,
3949
4358
  CalendarHeaderCell,
3950
4359
  RangeCalendar as AriaRangeCalendar,
3951
- useLocale as useLocale4
4360
+ useLocale as useLocale5
3952
4361
  } from "react-aria-components";
3953
4362
  import { DateFormatter, getDayOfWeek, getLocalTimeZone, today } from "@internationalized/date";
3954
4363
  import { ChevronDown as ChevronDown5, ChevronLeft as ChevronLeft4, ChevronRight as ChevronRight5 } from "lucide-react";
3955
- import { jsx as jsx44, jsxs as jsxs43 } from "react/jsx-runtime";
3956
- var defaultCalendarTexts = {
3957
- previousMonth: "Previous month",
3958
- nextMonth: "Next month",
3959
- previousYear: "Previous year",
3960
- nextYear: "Next year",
3961
- previousYears: "Previous years",
3962
- nextYears: "Next years",
3963
- chooseMonth: (title) => `${title} \u2013 choose month and year`,
3964
- chooseYear: (year) => `${year} \u2013 choose year`,
3965
- weekNumber: "Wk"
3966
- };
4364
+ import { jsx as jsx45, jsxs as jsxs43 } from "react/jsx-runtime";
4365
+ var defaultCalendarTexts = en.calendar;
3967
4366
  function isoWeek(date) {
3968
4367
  const d = new Date(Date.UTC(date.year, date.month - 1, date.day));
3969
4368
  const day = d.getUTCDay() || 7;
@@ -3979,7 +4378,7 @@ function Header3({
3979
4378
  months,
3980
4379
  t
3981
4380
  }) {
3982
- const { locale } = useLocale4();
4381
+ const { locale } = useLocale5();
3983
4382
  const monthTitle = useMemo3(() => new DateFormatter(locale, { month: "long", year: "numeric", timeZone: getLocalTimeZone() }), [locale]);
3984
4383
  const yearTitle = useMemo3(() => new DateFormatter(locale, { year: "numeric", timeZone: getLocalTimeZone() }), [locale]);
3985
4384
  const tz = getLocalTimeZone();
@@ -3990,35 +4389,35 @@ function Header3({
3990
4389
  if (view !== "days") {
3991
4390
  const title = view === "months" ? yearTitle.format(focused.toDate(tz)) : `${yearStart} \u2013 ${yearStart + 11}`;
3992
4391
  return /* @__PURE__ */ jsxs43("div", { className: "medo-calendar__header", children: [
3993
- view === "months" ? /* @__PURE__ */ jsx44(
4392
+ view === "months" ? /* @__PURE__ */ jsx45(
3994
4393
  Button,
3995
4394
  {
3996
4395
  slot: null,
3997
4396
  variant: "ghost",
3998
4397
  size: buttonSize,
3999
- endIcon: /* @__PURE__ */ jsx44(ChevronDown5, {}),
4398
+ endIcon: /* @__PURE__ */ jsx45(ChevronDown5, {}),
4000
4399
  onPress: () => setView("years"),
4001
4400
  "aria-label": t.chooseYear(title),
4002
4401
  className: "medo-calendar__title",
4003
4402
  children: title
4004
4403
  }
4005
- ) : /* @__PURE__ */ jsx44("span", { className: "medo-calendar__title medo-calendar__title--static", "aria-live": "polite", children: title }),
4404
+ ) : /* @__PURE__ */ jsx45("span", { className: "medo-calendar__title medo-calendar__title--static", "aria-live": "polite", children: title }),
4006
4405
  /* @__PURE__ */ jsxs43("div", { className: "medo-calendar__nav", children: [
4007
- /* @__PURE__ */ jsx44(IconButton, { slot: null, size: buttonSize, icon: /* @__PURE__ */ jsx44(ChevronLeft4, {}), "aria-label": view === "months" ? t.previousYear : t.previousYears, onPress: () => shift(-1) }),
4008
- /* @__PURE__ */ jsx44(IconButton, { slot: null, size: buttonSize, icon: /* @__PURE__ */ jsx44(ChevronRight5, {}), "aria-label": view === "months" ? t.nextYear : t.nextYears, onPress: () => shift(1) })
4406
+ /* @__PURE__ */ jsx45(IconButton, { slot: null, size: buttonSize, icon: /* @__PURE__ */ jsx45(ChevronLeft4, {}), "aria-label": view === "months" ? t.previousYear : t.previousYears, onPress: () => shift(-1) }),
4407
+ /* @__PURE__ */ jsx45(IconButton, { slot: null, size: buttonSize, icon: /* @__PURE__ */ jsx45(ChevronRight5, {}), "aria-label": view === "months" ? t.nextYear : t.nextYears, onPress: () => shift(1) })
4009
4408
  ] })
4010
4409
  ] });
4011
4410
  }
4012
- return /* @__PURE__ */ jsx44("div", { className: "medo-calendar__headers", style: { gridTemplateColumns: `repeat(${months}, 1fr)` }, children: Array.from({ length: months }, (_, i) => {
4411
+ return /* @__PURE__ */ jsx45("div", { className: "medo-calendar__headers", style: { gridTemplateColumns: `repeat(${months}, 1fr)` }, children: Array.from({ length: months }, (_, i) => {
4013
4412
  const title = monthTitle.format(focused.add({ months: i }).toDate(tz));
4014
4413
  return /* @__PURE__ */ jsxs43("div", { className: "medo-calendar__header", children: [
4015
- /* @__PURE__ */ jsx44(
4414
+ /* @__PURE__ */ jsx45(
4016
4415
  Button,
4017
4416
  {
4018
4417
  slot: null,
4019
4418
  variant: "ghost",
4020
4419
  size: buttonSize,
4021
- endIcon: /* @__PURE__ */ jsx44(ChevronDown5, {}),
4420
+ endIcon: /* @__PURE__ */ jsx45(ChevronDown5, {}),
4022
4421
  onPress: () => setView("months"),
4023
4422
  "aria-label": t.chooseMonth(title),
4024
4423
  className: "medo-calendar__title",
@@ -4026,19 +4425,19 @@ function Header3({
4026
4425
  }
4027
4426
  ),
4028
4427
  /* @__PURE__ */ jsxs43("div", { className: "medo-calendar__nav", children: [
4029
- i === 0 && /* @__PURE__ */ jsx44(IconButton, { slot: "previous", size: buttonSize, icon: /* @__PURE__ */ jsx44(ChevronLeft4, {}), "aria-label": t.previousMonth }),
4030
- i === months - 1 && /* @__PURE__ */ jsx44(IconButton, { slot: "next", size: buttonSize, icon: /* @__PURE__ */ jsx44(ChevronRight5, {}), "aria-label": t.nextMonth })
4428
+ i === 0 && /* @__PURE__ */ jsx45(IconButton, { slot: "previous", size: buttonSize, icon: /* @__PURE__ */ jsx45(ChevronLeft4, {}), "aria-label": t.previousMonth }),
4429
+ i === months - 1 && /* @__PURE__ */ jsx45(IconButton, { slot: "next", size: buttonSize, icon: /* @__PURE__ */ jsx45(ChevronRight5, {}), "aria-label": t.nextMonth })
4031
4430
  ] })
4032
4431
  ] }, i);
4033
4432
  }) });
4034
4433
  }
4035
4434
  function PeriodGrid({ view, setView, state }) {
4036
- const { locale } = useLocale4();
4435
+ const { locale } = useLocale5();
4037
4436
  const tz = getLocalTimeZone();
4038
4437
  const format = useMemo3(() => new DateFormatter(locale, { month: "short", timeZone: tz }), [locale, tz]);
4039
4438
  const focused = state.focusedDate;
4040
4439
  const now2 = today(tz);
4041
- const ref = useRef16(null);
4440
+ const ref = useRef17(null);
4042
4441
  const yearStart = focused.year - 5;
4043
4442
  const items = Array.from({ length: 12 }, (_, i) => {
4044
4443
  const date = view === "months" ? focused.set({ month: i + 1, day: 1 }) : focused.set({ year: yearStart + i, month: 1, day: 1 });
@@ -4058,10 +4457,10 @@ function PeriodGrid({ view, setView, state }) {
4058
4457
  }
4059
4458
  };
4060
4459
  });
4061
- useEffect15(() => {
4460
+ useEffect16(() => {
4062
4461
  ref.current?.querySelector("[data-focus-target]")?.focus();
4063
4462
  }, [view]);
4064
- return /* @__PURE__ */ jsx44("div", { ref, className: "medo-calendar__periods", role: "group", children: items.map((item) => /* @__PURE__ */ jsx44(
4463
+ return /* @__PURE__ */ jsx45("div", { ref, className: "medo-calendar__periods", role: "group", children: items.map((item) => /* @__PURE__ */ jsx45(
4065
4464
  AriaButton16,
4066
4465
  {
4067
4466
  slot: null,
@@ -4079,23 +4478,23 @@ function PeriodGrid({ view, setView, state }) {
4079
4478
  )) });
4080
4479
  }
4081
4480
  function DayGrid({ offset, showWeekNumbers, t }) {
4082
- const { locale } = useLocale4();
4481
+ const { locale } = useLocale5();
4083
4482
  return /* @__PURE__ */ jsxs43("div", { className: cx("medo-calendar__month", showWeekNumbers && "medo-calendar__month--weeks"), children: [
4084
- showWeekNumbers && /* @__PURE__ */ jsx44("span", { className: "medo-calendar__weeks-label", "aria-hidden": "true", children: t.weekNumber }),
4483
+ showWeekNumbers && /* @__PURE__ */ jsx45("span", { className: "medo-calendar__weeks-label", "aria-hidden": "true", children: t.weekNumber }),
4085
4484
  /* @__PURE__ */ jsxs43(CalendarGrid, { offset: offset ? { months: offset } : void 0, weekdayStyle: "short", className: "medo-calendar__grid", children: [
4086
- /* @__PURE__ */ jsx44(CalendarGridHeader, { children: (day) => /* @__PURE__ */ jsx44(CalendarHeaderCell, { className: "medo-calendar__weekday", children: day.replace(/\.$/, "").slice(0, 2) }) }),
4087
- /* @__PURE__ */ jsx44(CalendarGridBody, { children: (date) => /* @__PURE__ */ jsx44(CalendarCell, { date, className: "medo-calendar__cell", children: ({ formattedDate }) => (
4485
+ /* @__PURE__ */ jsx45(CalendarGridHeader, { children: (day) => /* @__PURE__ */ jsx45(CalendarHeaderCell, { className: "medo-calendar__weekday", children: day.replace(/\.$/, "").slice(0, 2) }) }),
4486
+ /* @__PURE__ */ jsx45(CalendarGridBody, { children: (date) => /* @__PURE__ */ jsx45(CalendarCell, { date, className: "medo-calendar__cell", children: ({ formattedDate }) => (
4088
4487
  // The week number is drawn by CSS (data-week), so it is not part of the day's visible name (WCAG 2.5.3).
4089
- /* @__PURE__ */ jsx44("span", { className: "medo-calendar__day", "data-week": showWeekNumbers && getDayOfWeek(date, locale) === 0 ? isoWeek(date.add({ days: 3 })) : void 0, children: formattedDate })
4488
+ /* @__PURE__ */ jsx45("span", { className: "medo-calendar__day", "data-week": showWeekNumbers && getDayOfWeek(date, locale) === 0 ? isoWeek(date.add({ days: 3 })) : void 0, children: formattedDate })
4090
4489
  ) }) })
4091
4490
  ] })
4092
4491
  ] });
4093
4492
  }
4094
4493
  function CalendarBody({ state, size, months, showWeekNumbers, t }) {
4095
- const [view, setView] = useState17("days");
4096
- const ref = useRef16(null);
4097
- const back = useRef16(false);
4098
- useEffect15(() => {
4494
+ const [view, setView] = useState18("days");
4495
+ const ref = useRef17(null);
4496
+ const back = useRef17(false);
4497
+ useEffect16(() => {
4099
4498
  if (view !== "days" || !back.current) return;
4100
4499
  back.current = false;
4101
4500
  ref.current?.querySelector('.medo-calendar__cell[tabindex="0"]')?.focus();
@@ -4105,19 +4504,21 @@ function CalendarBody({ state, size, months, showWeekNumbers, t }) {
4105
4504
  setView(v);
4106
4505
  };
4107
4506
  return /* @__PURE__ */ jsxs43("div", { ref, className: "medo-calendar__body", children: [
4108
- /* @__PURE__ */ jsx44(Header3, { view, setView: changeView, state, size, months: view === "days" ? months : 1, t }),
4109
- view === "days" ? /* @__PURE__ */ jsx44("div", { className: "medo-calendar__months", style: { gridTemplateColumns: `repeat(${months}, auto)` }, children: Array.from({ length: months }, (_, i) => /* @__PURE__ */ jsx44(DayGrid, { offset: i, showWeekNumbers, t }, i)) }) : /* @__PURE__ */ jsx44(PeriodGrid, { view, setView: changeView, state })
4507
+ /* @__PURE__ */ jsx45(Header3, { view, setView: changeView, state, size, months: view === "days" ? months : 1, t }),
4508
+ view === "days" ? /* @__PURE__ */ jsx45("div", { className: "medo-calendar__months", style: { gridTemplateColumns: `repeat(${months}, auto)` }, children: Array.from({ length: months }, (_, i) => /* @__PURE__ */ jsx45(DayGrid, { offset: i, showWeekNumbers, t }, i)) }) : /* @__PURE__ */ jsx45(PeriodGrid, { view, setView: changeView, state })
4110
4509
  ] });
4111
4510
  }
4112
4511
  function Calendar({ size = "md", showWeekNumbers, texts, className, ...props }) {
4113
- const t = { ...defaultCalendarTexts, ...texts };
4114
- return /* @__PURE__ */ jsx44(AriaCalendar, { ...props, className: cx("medo-calendar", `medo-calendar--${size}`, className), children: ({ state }) => /* @__PURE__ */ jsx44(CalendarBody, { state, size, months: 1, showWeekNumbers, t }) });
4512
+ const m = useMessages();
4513
+ const t = { ...m.calendar, ...texts };
4514
+ return /* @__PURE__ */ jsx45(AriaCalendar, { ...props, className: cx("medo-calendar", `medo-calendar--${size}`, className), children: ({ state }) => /* @__PURE__ */ jsx45(CalendarBody, { state, size, months: 1, showWeekNumbers, t }) });
4115
4515
  }
4116
4516
  function RangeCalendar({ size = "md", showWeekNumbers, visibleMonths = "auto", texts, className, ...props }) {
4117
- const t = { ...defaultCalendarTexts, ...texts };
4517
+ const m = useMessages();
4518
+ const t = { ...m.calendar, ...texts };
4118
4519
  const mobile = useMediaQuery(MOBILE_QUERY);
4119
4520
  const months = visibleMonths === "auto" ? mobile ? 1 : 2 : visibleMonths;
4120
- return /* @__PURE__ */ jsx44(AriaRangeCalendar, { ...props, visibleDuration: { months }, className: cx("medo-calendar", "medo-calendar--range", `medo-calendar--${size}`, className), children: ({ state }) => /* @__PURE__ */ jsx44(
4521
+ return /* @__PURE__ */ jsx45(AriaRangeCalendar, { ...props, visibleDuration: { months }, className: cx("medo-calendar", "medo-calendar--range", `medo-calendar--${size}`, className), children: ({ state }) => /* @__PURE__ */ jsx45(
4121
4522
  CalendarBody,
4122
4523
  {
4123
4524
  state: {
@@ -4137,28 +4538,28 @@ function RangeCalendar({ size = "md", showWeekNumbers, visibleMonths = "auto", t
4137
4538
  }
4138
4539
 
4139
4540
  // src/date-time/DateField.tsx
4140
- import { useMemo as useMemo4, useState as useState18 } from "react";
4541
+ import { useMemo as useMemo4, useState as useState19 } from "react";
4141
4542
  import {
4142
4543
  DateField as AriaDateField,
4143
4544
  DateInput,
4144
4545
  DateSegment,
4145
4546
  TimeField as AriaTimeField,
4146
- useLocale as useLocale5
4547
+ useLocale as useLocale6
4147
4548
  } from "react-aria-components";
4148
4549
  import { DateFormatter as DateFormatter2 } from "@internationalized/date";
4149
4550
  import { Clock } from "lucide-react";
4150
- import { jsx as jsx45, jsxs as jsxs44 } from "react/jsx-runtime";
4551
+ import { jsx as jsx46, jsxs as jsxs44 } from "react/jsx-runtime";
4151
4552
  function DateSegments({ size = "md", children }) {
4152
4553
  return /* @__PURE__ */ jsxs44("div", { className: cx("medo-input", `medo-input--${size}`, "medo-date-box"), children: [
4153
- /* @__PURE__ */ jsx45(DateInput, { className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx45(DateSegment, { segment, className: "medo-date-segment" }) }),
4554
+ /* @__PURE__ */ jsx46(DateInput, { className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx46(DateSegment, { segment, className: "medo-date-segment" }) }),
4154
4555
  children
4155
4556
  ] });
4156
4557
  }
4157
4558
  function DateField({ label, description, errorMessage, size = "md", className, ...props }) {
4158
4559
  return /* @__PURE__ */ jsxs44(AriaDateField, { shouldForceLeadingZeros: true, ...props, className: cx("medo-field", "medo-date-field", className), children: [
4159
- label && /* @__PURE__ */ jsx45(FieldLabel, { isRequired: props.isRequired, children: label }),
4160
- /* @__PURE__ */ jsx45(DateSegments, { size }),
4161
- /* @__PURE__ */ jsx45(FieldFooter, { description, errorMessage })
4560
+ label && /* @__PURE__ */ jsx46(FieldLabel, { isRequired: props.isRequired, children: label }),
4561
+ /* @__PURE__ */ jsx46(DateSegments, { size }),
4562
+ /* @__PURE__ */ jsx46(FieldFooter, { description, errorMessage })
4162
4563
  ] });
4163
4564
  }
4164
4565
  function TimeField({
@@ -4167,19 +4568,21 @@ function TimeField({
4167
4568
  errorMessage,
4168
4569
  size = "md",
4169
4570
  slots,
4170
- slotsLabel = "Available times",
4571
+ slotsLabel: slotsLabelProp,
4171
4572
  className,
4172
4573
  defaultValue,
4173
4574
  onChange,
4174
4575
  ...props
4175
4576
  }) {
4176
- const [inner, setInner] = useState18(defaultValue ?? null);
4577
+ const m = useMessages();
4578
+ const slotsLabel = slotsLabelProp ?? m.datePicker.availableTimes;
4579
+ const [inner, setInner] = useState19(defaultValue ?? null);
4177
4580
  const value = props.value !== void 0 ? props.value : inner;
4178
4581
  const change = (v) => {
4179
4582
  setInner(v);
4180
4583
  onChange?.(v);
4181
4584
  };
4182
- const { locale } = useLocale5();
4585
+ const { locale } = useLocale6();
4183
4586
  const format = useMemo4(
4184
4587
  () => new DateFormatter2(locale, { hour: "2-digit", minute: "2-digit", hourCycle: props.hourCycle === 12 ? "h12" : props.hourCycle === 24 ? "h23" : void 0 }),
4185
4588
  [locale, props.hourCycle]
@@ -4187,10 +4590,10 @@ function TimeField({
4187
4590
  const key = (v) => v ? `${v.hour}:${v.minute}` : "";
4188
4591
  const text = (v) => format.format(new Date(2e3, 0, 1, v.hour, v.minute));
4189
4592
  return /* @__PURE__ */ jsxs44(AriaTimeField, { shouldForceLeadingZeros: true, ...props, value, onChange: change, className: cx("medo-field", "medo-date-field", "medo-time-field", className), children: [
4190
- label && /* @__PURE__ */ jsx45(FieldLabel, { isRequired: props.isRequired, children: label }),
4191
- /* @__PURE__ */ jsx45(DateSegments, { size, children: slots && /* @__PURE__ */ jsxs44(PopoverTrigger, { children: [
4192
- /* @__PURE__ */ jsx45(InputAction, { icon: /* @__PURE__ */ jsx45(Clock, {}), "aria-label": slotsLabel, isDisabled: props.isDisabled || props.isReadOnly }),
4193
- /* @__PURE__ */ jsx45(Popover5, { size: "auto", "aria-label": slotsLabel, placement: "bottom end", className: "medo-time-slots", children: (close) => /* @__PURE__ */ jsx45(
4593
+ label && /* @__PURE__ */ jsx46(FieldLabel, { isRequired: props.isRequired, children: label }),
4594
+ /* @__PURE__ */ jsx46(DateSegments, { size, children: slots && /* @__PURE__ */ jsxs44(PopoverTrigger, { children: [
4595
+ /* @__PURE__ */ jsx46(InputAction, { icon: /* @__PURE__ */ jsx46(Clock, {}), "aria-label": slotsLabel, isDisabled: props.isDisabled || props.isReadOnly }),
4596
+ /* @__PURE__ */ jsx46(Popover5, { size: "auto", "aria-label": slotsLabel, placement: "bottom end", className: "medo-time-slots", children: (close) => /* @__PURE__ */ jsx46(
4194
4597
  ListBox,
4195
4598
  {
4196
4599
  "aria-label": slotsLabel,
@@ -4198,22 +4601,22 @@ function TimeField({
4198
4601
  autoFocus: true,
4199
4602
  selectionMode: "single",
4200
4603
  selectedKeys: value ? [key(value)] : [],
4201
- disabledKeys: slots.filter((s) => s.isDisabled).map((s) => key(s.value)),
4604
+ disabledKeys: slots.filter((s2) => s2.isDisabled).map((s2) => key(s2.value)),
4202
4605
  onSelectionChange: (keys) => {
4203
- const slot = slots.find((s) => keys !== "all" && keys.has(key(s.value)));
4606
+ const slot = slots.find((s2) => keys !== "all" && keys.has(key(s2.value)));
4204
4607
  if (slot) change(slot.value);
4205
4608
  close();
4206
4609
  },
4207
- children: slots.map((s) => /* @__PURE__ */ jsx45(Option, { id: key(s.value), textValue: text(s.value), description: s.isDisabled ? s.reason : void 0, children: text(s.value) }, key(s.value)))
4610
+ children: slots.map((s2) => /* @__PURE__ */ jsx46(Option, { id: key(s2.value), textValue: text(s2.value), description: s2.isDisabled ? s2.reason : void 0, children: text(s2.value) }, key(s2.value)))
4208
4611
  }
4209
4612
  ) })
4210
4613
  ] }) }),
4211
- /* @__PURE__ */ jsx45(FieldFooter, { description, errorMessage })
4614
+ /* @__PURE__ */ jsx46(FieldFooter, { description, errorMessage })
4212
4615
  ] });
4213
4616
  }
4214
4617
 
4215
4618
  // src/date-time/DatePicker.tsx
4216
- import { useContext as useContext17, useMemo as useMemo5 } from "react";
4619
+ import { useContext as useContext18, useMemo as useMemo5 } from "react";
4217
4620
  import {
4218
4621
  DateInput as DateInput2,
4219
4622
  DatePicker as AriaDatePicker,
@@ -4224,23 +4627,27 @@ import {
4224
4627
  Dialog as AriaDialog5,
4225
4628
  Group as Group2,
4226
4629
  Popover as AriaPopover2,
4227
- useLocale as useLocale6
4630
+ useLocale as useLocale7
4228
4631
  } from "react-aria-components";
4229
4632
  import { DateFormatter as DateFormatter3, endOfMonth, getLocalTimeZone as getLocalTimeZone2, startOfMonth, today as today2 } from "@internationalized/date";
4230
4633
  import { Calendar as CalendarIcon } from "lucide-react";
4231
- import { jsx as jsx46, jsxs as jsxs45 } from "react/jsx-runtime";
4232
- var defaultDatePickerTexts = {
4233
- openCalendar: "Open calendar",
4234
- done: "Done",
4235
- time: "Time",
4236
- presets: "Periods",
4237
- beforeMin: (date) => `Choose a date from ${date} on.`,
4238
- afterMax: (date) => `Choose a date until ${date}.`,
4239
- unavailable: "This day is not available. Choose another day.",
4240
- reversed: "The end date must be after the start date."
4241
- };
4242
- function useMessages(t, minValue, maxValue) {
4243
- const { locale } = useLocale6();
4634
+ import { jsx as jsx47, jsxs as jsxs45 } from "react/jsx-runtime";
4635
+ function pickerTexts(m) {
4636
+ const d = m.datePicker;
4637
+ return {
4638
+ openCalendar: d.openCalendar,
4639
+ done: m.common.done,
4640
+ time: d.time,
4641
+ presets: d.presets,
4642
+ beforeMin: d.beforeMin,
4643
+ afterMax: d.afterMax,
4644
+ unavailable: d.unavailable,
4645
+ reversed: d.reversed
4646
+ };
4647
+ }
4648
+ var defaultDatePickerTexts = pickerTexts(en);
4649
+ function useValidationMessages(t, minValue, maxValue) {
4650
+ const { locale } = useLocale7();
4244
4651
  const format = useMemo5(() => new DateFormatter3(locale, { day: "2-digit", month: "2-digit", year: "numeric", timeZone: getLocalTimeZone2() }), [locale]);
4245
4652
  const show = (d) => format.format(d.toDate(getLocalTimeZone2()));
4246
4653
  return ({ validationDetails: v, validationErrors }) => {
@@ -4253,22 +4660,22 @@ function useMessages(t, minValue, maxValue) {
4253
4660
  }
4254
4661
  function PickerOverlay({ title, sheet, t, children }) {
4255
4662
  if (sheet) {
4256
- return /* @__PURE__ */ jsx46(
4663
+ return /* @__PURE__ */ jsx47(
4257
4664
  BottomSheet,
4258
4665
  {
4259
4666
  title,
4260
4667
  className: "medo-date-sheet",
4261
- footer: (close) => /* @__PURE__ */ jsx46(Button, { variant: "primary", size: "lg", onPress: close, children: t.done }),
4262
- children: /* @__PURE__ */ jsx46("div", { className: "medo-date-panel", children })
4668
+ footer: (close) => /* @__PURE__ */ jsx47(Button, { variant: "primary", size: "lg", onPress: close, children: t.done }),
4669
+ children: /* @__PURE__ */ jsx47("div", { className: "medo-date-panel", children })
4263
4670
  }
4264
4671
  );
4265
4672
  }
4266
- return /* @__PURE__ */ jsx46(AriaPopover2, { placement: "bottom start", offset: 8, containerPadding: 16, className: "medo-popover medo-popover--auto medo-date-popover", children: /* @__PURE__ */ jsx46(AriaDialog5, { "aria-label": title, className: "medo-popover__dialog", children: /* @__PURE__ */ jsx46("div", { className: "medo-popover__body medo-date-panel", children }) }) });
4673
+ return /* @__PURE__ */ jsx47(AriaPopover2, { placement: "bottom start", offset: 8, containerPadding: 16, className: "medo-popover medo-popover--auto medo-date-popover", children: /* @__PURE__ */ jsx47(AriaDialog5, { "aria-label": title, className: "medo-popover__dialog", children: /* @__PURE__ */ jsx47("div", { className: "medo-popover__body medo-date-panel", children }) }) });
4267
4674
  }
4268
4675
  function PanelTime({ label, size }) {
4269
- const state = useContext17(DatePickerStateContext);
4676
+ const state = useContext18(DatePickerStateContext);
4270
4677
  if (!state) return null;
4271
- return /* @__PURE__ */ jsx46("div", { className: "medo-date-panel__time", children: /* @__PURE__ */ jsx46(TimeField, { label, size, value: state.timeValue, onChange: (v) => v && state.setTimeValue(v) }) });
4678
+ return /* @__PURE__ */ jsx47("div", { className: "medo-date-panel__time", children: /* @__PURE__ */ jsx47(TimeField, { label, size, value: state.timeValue, onChange: (v) => v && state.setTimeValue(v) }) });
4272
4679
  }
4273
4680
  var textOf = (label, ariaLabel) => typeof label === "string" ? label : ariaLabel ?? "";
4274
4681
  function DatePicker({
@@ -4282,10 +4689,11 @@ function DatePicker({
4282
4689
  className,
4283
4690
  ...props
4284
4691
  }) {
4285
- const t = { ...defaultCalendarTexts, ...defaultDatePickerTexts, ...texts };
4692
+ const m = useMessages();
4693
+ const t = { ...m.calendar, ...pickerTexts(m), ...texts };
4286
4694
  const mobile = useMediaQuery(MOBILE_QUERY);
4287
4695
  const sheet = overlay === "sheet" || overlay === "auto" && mobile;
4288
- const messages = useMessages(t, props.minValue, props.maxValue);
4696
+ const messages = useValidationMessages(t, props.minValue, props.maxValue);
4289
4697
  const hasTime = !!props.granularity && props.granularity !== "day";
4290
4698
  return /* @__PURE__ */ jsxs45(
4291
4699
  AriaDatePicker,
@@ -4294,39 +4702,40 @@ function DatePicker({
4294
4702
  ...props,
4295
4703
  className: cx("medo-field", "medo-date-field", "medo-date-picker", hasTime && "medo-date-picker--time", className),
4296
4704
  children: [
4297
- label && /* @__PURE__ */ jsx46(FieldLabel, { isRequired: props.isRequired, children: label }),
4705
+ label && /* @__PURE__ */ jsx47(FieldLabel, { isRequired: props.isRequired, children: label }),
4298
4706
  /* @__PURE__ */ jsxs45(Group2, { className: cx("medo-input", `medo-input--${size}`, "medo-date-box"), children: [
4299
- /* @__PURE__ */ jsx46(DateInput2, { className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx46(DateSegment2, { segment, className: "medo-date-segment" }) }),
4300
- /* @__PURE__ */ jsx46(InputAction, { icon: /* @__PURE__ */ jsx46(CalendarIcon, {}), "aria-label": t.openCalendar })
4707
+ /* @__PURE__ */ jsx47(DateInput2, { className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx47(DateSegment2, { segment, className: "medo-date-segment" }) }),
4708
+ /* @__PURE__ */ jsx47(InputAction, { icon: /* @__PURE__ */ jsx47(CalendarIcon, {}), "aria-label": t.openCalendar })
4301
4709
  ] }),
4302
- /* @__PURE__ */ jsx46(FieldFooter, { description, errorMessage: errorMessage ?? messages }),
4710
+ /* @__PURE__ */ jsx47(FieldFooter, { description, errorMessage: errorMessage ?? messages }),
4303
4711
  /* @__PURE__ */ jsxs45(PickerOverlay, { title: textOf(label, props["aria-label"]), sheet, t, children: [
4304
- /* @__PURE__ */ jsx46(Calendar, { size: sheet ? "lg" : "md", showWeekNumbers, texts: t }),
4305
- hasTime && /* @__PURE__ */ jsx46(PanelTime, { label: t.time, size: sheet ? "lg" : "md" })
4712
+ /* @__PURE__ */ jsx47(Calendar, { size: sheet ? "lg" : "md", showWeekNumbers, texts: t }),
4713
+ hasTime && /* @__PURE__ */ jsx47(PanelTime, { label: t.time, size: sheet ? "lg" : "md" })
4306
4714
  ] })
4307
4715
  ]
4308
4716
  }
4309
4717
  );
4310
4718
  }
4311
- function defaultDatePresets(labels = {}) {
4719
+ function defaultDatePresets(labels = {}, messages = en) {
4720
+ const d = messages.datePicker;
4312
4721
  const now2 = today2(getLocalTimeZone2());
4313
4722
  const lastMonth = now2.subtract({ months: 1 });
4314
4723
  return [
4315
- { label: labels.today ?? "Today", value: { start: now2, end: now2 } },
4316
- { label: labels.yesterday ?? "Yesterday", value: { start: now2.subtract({ days: 1 }), end: now2.subtract({ days: 1 }) } },
4317
- { label: labels.last7 ?? "Last 7 days", value: { start: now2.subtract({ days: 6 }), end: now2 } },
4318
- { label: labels.last14 ?? "Last 14 days", value: { start: now2.subtract({ days: 13 }), end: now2 } },
4319
- { label: labels.last30 ?? "Last 30 days", value: { start: now2.subtract({ days: 29 }), end: now2 } },
4320
- { label: labels.thisMonth ?? "This month", value: { start: startOfMonth(now2), end: now2 } },
4321
- { label: labels.lastMonth ?? "Last month", value: { start: startOfMonth(lastMonth), end: endOfMonth(lastMonth) } }
4724
+ { label: labels.today ?? d.today, value: { start: now2, end: now2 } },
4725
+ { label: labels.yesterday ?? d.yesterday, value: { start: now2.subtract({ days: 1 }), end: now2.subtract({ days: 1 }) } },
4726
+ { label: labels.last7 ?? d.last7Days, value: { start: now2.subtract({ days: 6 }), end: now2 } },
4727
+ { label: labels.last14 ?? d.last14Days, value: { start: now2.subtract({ days: 13 }), end: now2 } },
4728
+ { label: labels.last30 ?? d.last30Days, value: { start: now2.subtract({ days: 29 }), end: now2 } },
4729
+ { label: labels.thisMonth ?? d.thisMonth, value: { start: startOfMonth(now2), end: now2 } },
4730
+ { label: labels.lastMonth ?? d.lastMonth, value: { start: startOfMonth(lastMonth), end: endOfMonth(lastMonth) } }
4322
4731
  ];
4323
4732
  }
4324
4733
  function Presets({ presets, label, size }) {
4325
- const state = useContext17(DateRangePickerStateContext);
4734
+ const state = useContext18(DateRangePickerStateContext);
4326
4735
  if (!state) return null;
4327
4736
  const same = (a, b) => !!a && !!b && a.compare(b) === 0;
4328
4737
  const active = presets.findIndex((p) => same(state.value?.start, p.value.start) && same(state.value?.end, p.value.end));
4329
- return /* @__PURE__ */ jsx46(
4738
+ return /* @__PURE__ */ jsx47(
4330
4739
  ListBox,
4331
4740
  {
4332
4741
  "aria-label": label,
@@ -4340,7 +4749,7 @@ function Presets({ presets, label, size }) {
4340
4749
  state.close();
4341
4750
  },
4342
4751
  className: "medo-date-panel__presets",
4343
- children: presets.map((p, i) => /* @__PURE__ */ jsx46(Option, { id: String(i), children: p.label }, i))
4752
+ children: presets.map((p, i) => /* @__PURE__ */ jsx47(Option, { id: String(i), children: p.label }, i))
4344
4753
  }
4345
4754
  );
4346
4755
  }
@@ -4356,23 +4765,24 @@ function DateRangePicker({
4356
4765
  className,
4357
4766
  ...props
4358
4767
  }) {
4359
- const t = { ...defaultCalendarTexts, ...defaultDatePickerTexts, ...texts };
4768
+ const m = useMessages();
4769
+ const t = { ...m.calendar, ...pickerTexts(m), ...texts };
4360
4770
  const mobile = useMediaQuery(MOBILE_QUERY);
4361
4771
  const sheet = overlay === "sheet" || overlay === "auto" && mobile;
4362
- const messages = useMessages(t, props.minValue, props.maxValue);
4363
- const list = presets === true ? defaultDatePresets() : presets || void 0;
4772
+ const messages = useValidationMessages(t, props.minValue, props.maxValue);
4773
+ const list = presets === true ? defaultDatePresets({}, m) : presets || void 0;
4364
4774
  return /* @__PURE__ */ jsxs45(AriaDateRangePicker, { shouldForceLeadingZeros: true, ...props, className: cx("medo-field", "medo-date-field", "medo-date-picker", "medo-date-picker--range", className), children: [
4365
- label && /* @__PURE__ */ jsx46(FieldLabel, { isRequired: props.isRequired, children: label }),
4775
+ label && /* @__PURE__ */ jsx47(FieldLabel, { isRequired: props.isRequired, children: label }),
4366
4776
  /* @__PURE__ */ jsxs45(Group2, { className: cx("medo-input", `medo-input--${size}`, "medo-date-box"), children: [
4367
- /* @__PURE__ */ jsx46(DateInput2, { slot: "start", className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx46(DateSegment2, { segment, className: "medo-date-segment" }) }),
4368
- /* @__PURE__ */ jsx46("span", { className: "medo-date-box__dash", "aria-hidden": "true", children: "\u2013" }),
4369
- /* @__PURE__ */ jsx46(DateInput2, { slot: "end", className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx46(DateSegment2, { segment, className: "medo-date-segment" }) }),
4370
- /* @__PURE__ */ jsx46(InputAction, { icon: /* @__PURE__ */ jsx46(CalendarIcon, {}), "aria-label": t.openCalendar })
4777
+ /* @__PURE__ */ jsx47(DateInput2, { slot: "start", className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx47(DateSegment2, { segment, className: "medo-date-segment" }) }),
4778
+ /* @__PURE__ */ jsx47("span", { className: "medo-date-box__dash", "aria-hidden": "true", children: "\u2013" }),
4779
+ /* @__PURE__ */ jsx47(DateInput2, { slot: "end", className: "medo-date-input", children: (segment) => /* @__PURE__ */ jsx47(DateSegment2, { segment, className: "medo-date-segment" }) }),
4780
+ /* @__PURE__ */ jsx47(InputAction, { icon: /* @__PURE__ */ jsx47(CalendarIcon, {}), "aria-label": t.openCalendar })
4371
4781
  ] }),
4372
- /* @__PURE__ */ jsx46(FieldFooter, { description, errorMessage: errorMessage ?? messages }),
4373
- /* @__PURE__ */ jsx46(PickerOverlay, { title: textOf(label, props["aria-label"]), sheet, t, children: /* @__PURE__ */ jsxs45("div", { className: cx("medo-date-panel__range", !!list && "medo-date-panel__range--presets"), children: [
4374
- list && /* @__PURE__ */ jsx46(Presets, { presets: list, label: t.presets, size: sheet ? "lg" : "md" }),
4375
- /* @__PURE__ */ jsx46(RangeCalendar, { size: sheet ? "lg" : "md", visibleMonths: sheet ? 1 : 2, showWeekNumbers, texts: t })
4782
+ /* @__PURE__ */ jsx47(FieldFooter, { description, errorMessage: errorMessage ?? messages }),
4783
+ /* @__PURE__ */ jsx47(PickerOverlay, { title: textOf(label, props["aria-label"]), sheet, t, children: /* @__PURE__ */ jsxs45("div", { className: cx("medo-date-panel__range", !!list && "medo-date-panel__range--presets"), children: [
4784
+ list && /* @__PURE__ */ jsx47(Presets, { presets: list, label: t.presets, size: sheet ? "lg" : "md" }),
4785
+ /* @__PURE__ */ jsx47(RangeCalendar, { size: sheet ? "lg" : "md", visibleMonths: sheet ? 1 : 2, showWeekNumbers, texts: t })
4376
4786
  ] }) })
4377
4787
  ] });
4378
4788
  }
@@ -4395,11 +4805,11 @@ import {
4395
4805
  } from "@internationalized/date";
4396
4806
 
4397
4807
  // src/media/Image.tsx
4398
- import { useEffect as useEffect16, useLayoutEffect as useLayoutEffect8, useRef as useRef17, useState as useState19 } from "react";
4808
+ import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect8, useRef as useRef18, useState as useState20 } from "react";
4399
4809
  import { ImageOff, Play } from "lucide-react";
4400
- import { jsx as jsx47, jsxs as jsxs46 } from "react/jsx-runtime";
4810
+ import { jsx as jsx48, jsxs as jsxs46 } from "react/jsx-runtime";
4401
4811
  function MediaPlayButton({ size = "md", className }) {
4402
- return /* @__PURE__ */ jsx47("span", { className: cx("medo-media-play", `medo-media-play--${size}`, className), "aria-hidden": "true", children: /* @__PURE__ */ jsx47(Play, {}) });
4812
+ return /* @__PURE__ */ jsx48("span", { className: cx("medo-media-play", `medo-media-play--${size}`, className), "aria-hidden": "true", children: /* @__PURE__ */ jsx48(Play, {}) });
4403
4813
  }
4404
4814
  function Image({
4405
4815
  src,
@@ -4419,10 +4829,10 @@ function Image({
4419
4829
  onError,
4420
4830
  ...props
4421
4831
  }) {
4422
- const ref = useRef17(null);
4423
- const [state, setState] = useState19("loading");
4832
+ const ref = useRef18(null);
4833
+ const [state, setState] = useState20("loading");
4424
4834
  useLayoutEffect8(() => setState("loading"), [src]);
4425
- useEffect16(() => {
4835
+ useEffect17(() => {
4426
4836
  const img = ref.current;
4427
4837
  if (img?.complete && src) setState(img.naturalWidth > 0 ? "loaded" : "error");
4428
4838
  }, [src]);
@@ -4436,9 +4846,9 @@ function Image({
4436
4846
  "data-state": state,
4437
4847
  style: { aspectRatio: aspect, ...style },
4438
4848
  children: [
4439
- state === "loading" && (placeholder ? /* @__PURE__ */ jsx47("img", { className: "medo-image__preview", src: placeholder, alt: "", "aria-hidden": "true" }) : /* @__PURE__ */ jsx47(Skeleton, { shape: "rect", className: "medo-image__skeleton" })),
4440
- state === "error" && /* @__PURE__ */ jsx47("span", { className: "medo-image__error", role: alt ? "img" : void 0, "aria-label": alt || void 0, "aria-hidden": alt ? void 0 : true, children: /* @__PURE__ */ jsx47(ImageOff, { "aria-hidden": "true" }) }),
4441
- /* @__PURE__ */ jsx47(
4849
+ state === "loading" && (placeholder ? /* @__PURE__ */ jsx48("img", { className: "medo-image__preview", src: placeholder, alt: "", "aria-hidden": "true" }) : /* @__PURE__ */ jsx48(Skeleton, { shape: "rect", className: "medo-image__skeleton" })),
4850
+ state === "error" && /* @__PURE__ */ jsx48("span", { className: "medo-image__error", role: alt ? "img" : void 0, "aria-label": alt || void 0, "aria-hidden": alt ? void 0 : true, children: /* @__PURE__ */ jsx48(ImageOff, { "aria-hidden": "true" }) }),
4851
+ /* @__PURE__ */ jsx48(
4442
4852
  "img",
4443
4853
  {
4444
4854
  ...props,
@@ -4461,11 +4871,11 @@ function Image({
4461
4871
  }
4462
4872
  ),
4463
4873
  state === "loaded" && overlay && /* @__PURE__ */ jsxs46("div", { className: cx("medo-image__overlay", `medo-image__overlay--${overlay.position ?? "bottom"}`), children: [
4464
- /* @__PURE__ */ jsx47("span", { className: "medo-image__title", children: overlay.title }),
4465
- overlay.meta && /* @__PURE__ */ jsx47("span", { className: "medo-image__meta", children: overlay.meta })
4874
+ /* @__PURE__ */ jsx48("span", { className: "medo-image__title", children: overlay.title }),
4875
+ overlay.meta && /* @__PURE__ */ jsx48("span", { className: "medo-image__meta", children: overlay.meta })
4466
4876
  ] }),
4467
- state === "loaded" && badge && /* @__PURE__ */ jsx47("span", { className: "medo-image__badge", children: badge }),
4468
- state === "loaded" && play && /* @__PURE__ */ jsx47(MediaPlayButton, { size: play, className: "medo-image__play" })
4877
+ state === "loaded" && badge && /* @__PURE__ */ jsx48("span", { className: "medo-image__badge", children: badge }),
4878
+ state === "loaded" && play && /* @__PURE__ */ jsx48(MediaPlayButton, { size: play, className: "medo-image__play" })
4469
4879
  ]
4470
4880
  }
4471
4881
  );
@@ -4474,46 +4884,29 @@ function Figure({ children, caption, credit, className }) {
4474
4884
  return /* @__PURE__ */ jsxs46("figure", { className: cx("medo-figure", className), children: [
4475
4885
  children,
4476
4886
  (caption || credit) && /* @__PURE__ */ jsxs46("figcaption", { className: "medo-figure__caption", children: [
4477
- caption && /* @__PURE__ */ jsx47("span", { children: caption }),
4478
- credit && /* @__PURE__ */ jsx47("span", { className: "medo-figure__credit", children: credit })
4887
+ caption && /* @__PURE__ */ jsx48("span", { children: caption }),
4888
+ credit && /* @__PURE__ */ jsx48("span", { className: "medo-figure__credit", children: credit })
4479
4889
  ] })
4480
4890
  ] });
4481
4891
  }
4482
4892
 
4483
4893
  // src/media/EmbedConsent.tsx
4484
- import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect9, useRef as useRef18, useState as useState20 } from "react";
4894
+ import { useEffect as useEffect18, useLayoutEffect as useLayoutEffect9, useRef as useRef19, useState as useState21 } from "react";
4485
4895
  import { Globe as Globe2, MapPin, Play as Play2 } from "lucide-react";
4486
- import { jsx as jsx48, jsxs as jsxs47 } from "react/jsx-runtime";
4487
- function defaultEmbedTexts(type, provider, company) {
4896
+ import { jsx as jsx49, jsxs as jsxs47 } from "react/jsx-runtime";
4897
+ function defaultEmbedTexts(type, provider, company, messages = en) {
4488
4898
  const to = company ?? provider;
4489
- if (type === "video")
4490
- return {
4491
- title: "Load external video",
4492
- body: `This video is provided by ${provider ?? "a third party"}. Loading it sends data such as your IP address to ${to ?? "the provider"}.`,
4493
- bodyCompact: `Loading this video sends data to ${provider && company && provider !== company ? `${provider} (${company})` : to ?? "a third party"}.`,
4494
- load: "Load video",
4495
- remember: provider ? `Always load ${provider} videos` : "Always load videos from this provider",
4496
- privacy: "Privacy policy"
4497
- };
4498
- if (type === "map")
4499
- return {
4500
- title: "Load map",
4501
- body: `This map is provided by ${provider ?? "a third party"}. Loading it sends data such as your IP address to ${to ?? "the provider"}.`,
4502
- bodyCompact: `Loading this map sends data to ${to ?? "a third party"}.`,
4503
- load: "Load map",
4504
- remember: provider ? `Always load ${provider}` : "Always load maps from this provider",
4505
- privacy: "Privacy policy"
4506
- };
4899
+ const e = messages.embed[type];
4507
4900
  return {
4508
- title: "Load external content",
4509
- body: `This content is provided by ${provider ?? "a third party"}. Loading it sends data such as your IP address to ${to ?? "the provider"}.`,
4510
- bodyCompact: `Loading this content sends data to ${to ?? "a third party"}.`,
4511
- load: "Load content",
4512
- remember: provider ? `Always load content from ${provider}` : "Always load content from this provider",
4513
- privacy: "Privacy policy"
4901
+ title: e.title,
4902
+ body: e.body(provider, to),
4903
+ bodyCompact: e.bodyCompact(provider, company, to),
4904
+ load: e.load,
4905
+ remember: e.remember(provider),
4906
+ privacy: messages.embed.privacy
4514
4907
  };
4515
4908
  }
4516
- var icons2 = { video: /* @__PURE__ */ jsx48(Play2, {}), map: /* @__PURE__ */ jsx48(MapPin, {}), generic: /* @__PURE__ */ jsx48(Globe2, {}) };
4909
+ var icons2 = { video: /* @__PURE__ */ jsx49(Play2, {}), map: /* @__PURE__ */ jsx49(MapPin, {}), generic: /* @__PURE__ */ jsx49(Globe2, {}) };
4517
4910
  function EmbedConsent({
4518
4911
  type = "generic",
4519
4912
  provider,
@@ -4528,12 +4921,13 @@ function EmbedConsent({
4528
4921
  texts,
4529
4922
  className
4530
4923
  }) {
4531
- const t = { ...defaultEmbedTexts(type, provider, company), ...texts };
4532
- const ref = useRef18(null);
4533
- const frame = useRef18(null);
4534
- const [clicked, setClicked] = useState20(false);
4535
- const [remember, setRemember] = useState20(false);
4536
- const [compact, setCompact] = useState20(false);
4924
+ const m = useMessages();
4925
+ const t = { ...defaultEmbedTexts(type, provider, company, m), ...texts };
4926
+ const ref = useRef19(null);
4927
+ const frame = useRef19(null);
4928
+ const [clicked, setClicked] = useState21(false);
4929
+ const [remember, setRemember] = useState21(false);
4930
+ const [compact, setCompact] = useState21(false);
4537
4931
  const loaded = isConsented || clicked;
4538
4932
  useLayoutEffect9(() => {
4539
4933
  const el = ref.current;
@@ -4542,12 +4936,12 @@ function EmbedConsent({
4542
4936
  ro.observe(el);
4543
4937
  return () => ro.disconnect();
4544
4938
  }, [loaded]);
4545
- useEffect17(() => {
4939
+ useEffect18(() => {
4546
4940
  if (clicked) frame.current?.focus();
4547
4941
  }, [clicked]);
4548
4942
  const style = { aspectRatio: ratio.replace(":", " / ") };
4549
4943
  if (loaded) {
4550
- return /* @__PURE__ */ jsx48("div", { className: cx("medo-embed", "medo-embed--loaded", className), style, children: /* @__PURE__ */ jsx48(
4944
+ return /* @__PURE__ */ jsx49("div", { className: cx("medo-embed", "medo-embed--loaded", className), style, children: /* @__PURE__ */ jsx49(
4551
4945
  "iframe",
4552
4946
  {
4553
4947
  ref: frame,
@@ -4562,13 +4956,13 @@ function EmbedConsent({
4562
4956
  ) });
4563
4957
  }
4564
4958
  return /* @__PURE__ */ jsxs47("div", { ref, role: "region", "aria-label": title, className: cx("medo-embed", compact && "medo-embed--compact", className), style, children: [
4565
- !compact && /* @__PURE__ */ jsx48(IconTile, { size: "sm", tone: "raised", children: icons2[type] }),
4959
+ !compact && /* @__PURE__ */ jsx49(IconTile, { size: "sm", tone: "raised", children: icons2[type] }),
4566
4960
  /* @__PURE__ */ jsxs47("div", { className: "medo-embed__content", children: [
4567
- /* @__PURE__ */ jsx48("p", { className: "medo-embed__title", children: t.title }),
4568
- /* @__PURE__ */ jsx48("p", { className: "medo-embed__body", children: compact ? t.bodyCompact : t.body })
4961
+ /* @__PURE__ */ jsx49("p", { className: "medo-embed__title", children: t.title }),
4962
+ /* @__PURE__ */ jsx49("p", { className: "medo-embed__body", children: compact ? t.bodyCompact : t.body })
4569
4963
  ] }),
4570
4964
  /* @__PURE__ */ jsxs47("div", { className: "medo-embed__actions", children: [
4571
- /* @__PURE__ */ jsx48(
4965
+ /* @__PURE__ */ jsx49(
4572
4966
  Button,
4573
4967
  {
4574
4968
  size: compact ? "sm" : "md",
@@ -4579,9 +4973,9 @@ function EmbedConsent({
4579
4973
  children: t.load
4580
4974
  }
4581
4975
  ),
4582
- /* @__PURE__ */ jsx48(Link, { variant: "standalone", size: compact ? "sm" : "md", href: privacyHref, children: t.privacy })
4976
+ /* @__PURE__ */ jsx49(Link, { variant: "standalone", size: compact ? "sm" : "md", href: privacyHref, children: t.privacy })
4583
4977
  ] }),
4584
- !compact && /* @__PURE__ */ jsx48(Checkbox, { isSelected: remember, onChange: setRemember, children: t.remember })
4978
+ !compact && /* @__PURE__ */ jsx49(Checkbox, { isSelected: remember, onChange: setRemember, children: t.remember })
4585
4979
  ] });
4586
4980
  }
4587
4981
  export {
@@ -4648,6 +5042,7 @@ export {
4648
5042
  MenuItem,
4649
5043
  MenuSection,
4650
5044
  MenuTrigger,
5045
+ MessagesProvider,
4651
5046
  NavGroup,
4652
5047
  NavItem,
4653
5048
  NavList,
@@ -4700,11 +5095,13 @@ export {
4700
5095
  TooltipTrigger,
4701
5096
  UploadField,
4702
5097
  ZonedDateTime,
5098
+ de as deMessages,
4703
5099
  defaultCalendarTexts,
4704
5100
  defaultDatePickerTexts,
4705
5101
  defaultDatePresets,
4706
5102
  defaultEmbedTexts,
4707
5103
  defaultUploadTexts,
5104
+ en as enMessages,
4708
5105
  formatBytes,
4709
5106
  getLocalTimeZone3 as getLocalTimeZone,
4710
5107
  initialsOf,
@@ -4716,6 +5113,7 @@ export {
4716
5113
  parseTime,
4717
5114
  parseZonedDateTime,
4718
5115
  toast,
4719
- today3 as today
5116
+ today3 as today,
5117
+ useMessages
4720
5118
  };
4721
5119
  //# sourceMappingURL=index.js.map