@salesql/sql_components_vue3 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/constants/events.d.ts +20 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +40 -6
  5. package/dist/index.es.js +2258 -613
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/sql_components_vue3.css +1 -1
  8. package/dist/ui/DsAlert/DsAlert.vue.d.ts +15 -2
  9. package/dist/ui/DsAvatar/DsAvatar.types.d.ts +6 -0
  10. package/dist/ui/DsAvatar/DsAvatar.vue.d.ts +47 -2
  11. package/dist/ui/DsButton/DsButton.types.d.ts +6 -1
  12. package/dist/ui/DsButton/DsButton.vue.d.ts +11 -5
  13. package/dist/ui/DsCell/DsCell.types.d.ts +19 -0
  14. package/dist/ui/DsCell/DsCell.vue.d.ts +71 -0
  15. package/dist/ui/DsCell/index.d.ts +2 -0
  16. package/dist/ui/DsCheckbox/DsCheckbox.types.d.ts +2 -0
  17. package/dist/ui/DsCheckbox/DsCheckbox.vue.d.ts +10 -1
  18. package/dist/ui/DsContactValue/DsContactValue.types.d.ts +4 -0
  19. package/dist/ui/DsContactValue/DsContactValue.vue.d.ts +18 -0
  20. package/dist/ui/DsCustomTag/DsCustomTag.types.d.ts +9 -0
  21. package/dist/ui/DsCustomTag/DsCustomTag.vue.d.ts +29 -0
  22. package/dist/ui/DsCustomTag/index.d.ts +2 -0
  23. package/dist/ui/DsDataCard/DsDataCard.types.d.ts +2 -0
  24. package/dist/ui/DsDataCard/DsDataCard.vue.d.ts +58 -1
  25. package/dist/ui/DsEmptyState/DsEmptyState.types.d.ts +12 -0
  26. package/dist/ui/DsEmptyState/DsEmptyState.vue.d.ts +53 -0
  27. package/dist/ui/DsEmptyState/index.d.ts +2 -0
  28. package/dist/ui/DsInput/DsInput.vue.d.ts +36 -2
  29. package/dist/ui/DsItemSelectorButton/DsItemSelectorButton.types.d.ts +20 -0
  30. package/dist/ui/DsItemSelectorButton/DsItemSelectorButton.vue.d.ts +50 -0
  31. package/dist/ui/DsItemSelectorButton/index.d.ts +2 -0
  32. package/dist/ui/DsMenuItem/DsMenuItem.types.d.ts +6 -0
  33. package/dist/ui/DsMenuItem/DsMenuItem.vue.d.ts +42 -0
  34. package/dist/ui/DsMenuItem/index.d.ts +2 -0
  35. package/dist/ui/DsModal/DsModal.types.d.ts +10 -0
  36. package/dist/ui/DsModal/DsModal.vue.d.ts +42 -3
  37. package/dist/ui/DsNotification/DsNotification.types.d.ts +8 -0
  38. package/dist/ui/DsNotification/DsNotification.vue.d.ts +22 -2
  39. package/dist/ui/DsPaginator/DsPaginator.types.d.ts +12 -0
  40. package/dist/ui/DsPaginator/DsPaginator.vue.d.ts +101 -0
  41. package/dist/ui/DsPaginator/index.d.ts +2 -0
  42. package/dist/ui/DsPill/DsPill.types.d.ts +11 -0
  43. package/dist/ui/DsPill/DsPill.vue.d.ts +46 -0
  44. package/dist/ui/DsPill/index.d.ts +2 -0
  45. package/dist/ui/DsPillWithBorder/DsPillWithBorder.types.d.ts +2 -0
  46. package/dist/ui/DsPillWithBorder/DsPillWithBorder.vue.d.ts +18 -0
  47. package/dist/ui/DsPillWithBorder/index.d.ts +2 -0
  48. package/dist/ui/DsRadio/DsRadio.types.d.ts +7 -0
  49. package/dist/ui/DsRadio/DsRadio.vue.d.ts +55 -0
  50. package/dist/ui/DsRadio/index.d.ts +2 -0
  51. package/dist/ui/DsRow/DsRow.types.d.ts +6 -0
  52. package/dist/ui/DsRow/DsRow.vue.d.ts +37 -0
  53. package/dist/ui/DsRow/index.d.ts +2 -0
  54. package/dist/ui/DsSegmentedProgressBar/DsSegmentedProgressBar.types.d.ts +5 -0
  55. package/dist/ui/DsSegmentedProgressBar/DsSegmentedProgressBar.vue.d.ts +62 -0
  56. package/dist/ui/DsSegmentedProgressBar/index.d.ts +2 -0
  57. package/dist/ui/DsSelect/DsSelect.types.d.ts +33 -0
  58. package/dist/ui/DsSelect/DsSelect.vue.d.ts +126 -0
  59. package/dist/ui/DsSelect/index.d.ts +2 -0
  60. package/dist/ui/DsSpinner/DsSpinner.types.d.ts +6 -0
  61. package/dist/ui/DsSpinner/DsSpinner.vue.d.ts +4 -4
  62. package/dist/ui/DsSwitch/DsSwitch.types.d.ts +6 -0
  63. package/dist/ui/DsSwitch/DsSwitch.vue.d.ts +30 -0
  64. package/dist/ui/DsSwitch/index.d.ts +2 -0
  65. package/dist/ui/DsTable/DsTable.types.d.ts +11 -0
  66. package/dist/ui/DsTable/DsTable.vue.d.ts +112 -10
  67. package/dist/ui/DsTag/DsTag.types.d.ts +1 -0
  68. package/dist/ui/DsTag/DsTag.vue.d.ts +6 -0
  69. package/dist/ui/DsTextarea/DsTextarea.types.d.ts +8 -0
  70. package/dist/ui/DsTextarea/DsTextarea.vue.d.ts +14 -3
  71. package/dist/ui/DsTooltip/DsTooltip.types.d.ts +7 -0
  72. package/dist/ui/DsTooltip/DsTooltip.vue.d.ts +64 -0
  73. package/dist/ui/DsTooltip/index.d.ts +2 -0
  74. package/dist/ui/DsWizardStepper/DsWizardStepper.types.d.ts +13 -0
  75. package/dist/ui/DsWizardStepper/DsWizardStepper.vue.d.ts +58 -0
  76. package/dist/ui/DsWizardStepper/index.d.ts +2 -0
  77. package/package.json +1 -1
package/dist/index.es.js CHANGED
@@ -1,53 +1,79 @@
1
- import { defineComponent as k, openBlock as t, createElementBlock as a, normalizeStyle as w, normalizeClass as v, toDisplayString as y, createCommentVNode as r, computed as S, createBlock as D, unref as g, renderSlot as I, createElementVNode as s, Fragment as B, renderList as M, createTextVNode as A, useModel as W, useSlots as le, ref as N, withDirectives as q, vModelDynamic as ce, mergeModels as O, vModelText as ue, onMounted as fe, watch as ie, vModelCheckbox as ye, Teleport as ne, nextTick as ve, onBeforeUnmount as oe, withModifiers as se, createVNode as de, withCtx as be } from "vue";
2
- const Y = {
1
+ import { defineComponent as x, computed as g, openBlock as a, createElementBlock as l, normalizeStyle as F, normalizeClass as $, createBlock as G, unref as _, createCommentVNode as m, createElementVNode as s, renderSlot as A, toDisplayString as S, withModifiers as ve, useModel as de, ref as U, onMounted as Qe, watch as te, withDirectives as Be, vModelCheckbox as st, createTextVNode as H, mergeModels as Q, onBeforeUnmount as be, nextTick as ue, createVNode as j, Fragment as z, renderList as Y, useSlots as Ee, vModelDynamic as ot, useAttrs as dt, mergeProps as he, vModelText as rt, Transition as Le, withCtx as ie, Teleport as Je, useId as xe, withKeys as ct, reactive as ut, resolveDynamicComponent as ft } from "vue";
2
+ const ge = {
3
3
  DARK: "dark",
4
4
  // slate ring — for light surfaces (default)
5
5
  LIGHT: "light",
6
6
  // white ring — for dark surfaces / solid buttons
7
7
  ACCENT: "accent"
8
8
  // accent ring
9
- }, me = ["aria-label", "aria-hidden"], ge = {
10
- key: 0,
11
- class: "ds-spinner__sr-only"
12
- }, he = /* @__PURE__ */ k({
9
+ }, Ce = {
10
+ SMALL: "small",
11
+ // 20px
12
+ MEDIUM: "medium",
13
+ // 32px
14
+ LARGE: "large"
15
+ // 48px
16
+ }, bt = ["aria-label"], vt = /* @__PURE__ */ x({
13
17
  __name: "DsSpinner",
14
18
  props: {
15
- size: { type: Number, default: 24 },
19
+ // Diameter in px, or a named size ("small" 20 / "medium" 32 / "large" 48).
20
+ // Default (24) is unchanged and isn't one of the named steps.
21
+ size: { type: [Number, String], default: 24 },
16
22
  tone: {
17
23
  type: String,
18
- default: Y.DARK
24
+ default: ge.DARK
19
25
  },
20
- // Optional accessible text; without it the spinner is aria-hidden.
21
- label: { type: String, default: "" }
26
+ // Accessible name (DS default "Loading"); the consuming app can override for
27
+ // i18n. role="status" + aria-label are always present, never opt-in.
28
+ label: { type: String, default: "Loading" }
22
29
  },
23
30
  setup(e) {
24
- return (n, o) => (t(), a("span", {
25
- class: v(["ds-spinner", `ds-spinner--${e.tone}`]),
31
+ const n = {
32
+ [Ce.SMALL]: 20,
33
+ [Ce.MEDIUM]: 32,
34
+ [Ce.LARGE]: 48
35
+ }, t = e, o = g(
36
+ () => {
37
+ var i;
38
+ return typeof t.size == "string" ? (i = n[t.size]) != null ? i : 24 : t.size;
39
+ }
40
+ );
41
+ return (i, c) => (a(), l("span", {
42
+ class: $(["ds-spinner", `ds-spinner--${e.tone}`]),
26
43
  role: "status",
27
- style: w({ width: `${e.size}px`, height: `${e.size}px` }),
28
- "aria-label": e.label || void 0,
29
- "aria-hidden": e.label ? void 0 : "true"
30
- }, [
31
- e.label ? (t(), a("span", ge, y(e.label), 1)) : r("", !0)
32
- ], 14, me));
44
+ style: F({ width: `${o.value}px`, height: `${o.value}px` }),
45
+ "aria-label": e.label || void 0
46
+ }, null, 14, bt));
33
47
  }
34
- }), $ = (e, n) => {
35
- const o = e.__vccOpts || e;
36
- for (const [l, i] of n)
37
- o[l] = i;
38
- return o;
39
- }, Se = /* @__PURE__ */ $(he, [["__scopeId", "data-v-190a8af4"]]), Z = "click", C = "close", V = "focus", U = "blur", F = "copy", z = "correct", _ = "incorrect", j = "sort", Q = "edit", J = {
48
+ }), M = (e, n) => {
49
+ const t = e.__vccOpts || e;
50
+ for (const [o, i] of n)
51
+ t[o] = i;
52
+ return t;
53
+ }, fe = /* @__PURE__ */ M(vt, [["__scopeId", "data-v-aaf2f048"]]), Z = "click", X = "close", Se = "focus", ke = "blur", Me = "change", Oe = "field-blur", pe = "copy", $e = "correct", Te = "incorrect", Pe = "sort", Fe = "edit", ze = "select-all", Ve = "page-change", Ue = "page-size-change", _e = "search", Ge = "select", De = "step", He = "final-step", We = "navigate", Ae = {
54
+ DEFAULT: "default",
55
+ // white surface, dark text (the default value; == tertiary)
40
56
  PRIMARY: "primary",
41
- // solid accent fill, white text
57
+ // solid accent fill, white text — the main CTA
42
58
  SECONDARY: "secondary",
43
59
  // slate surface fill, dark text
44
60
  TERTIARY: "tertiary",
45
- // transparent ghost, dark text
61
+ // white surface, dark text (low-emphasis row action)
46
62
  QUATERNARY: "quaternary",
47
- // accent border + accent text, light fill
48
- SPECIAL: "special"
49
- // accent text only, no fill/border (link-style)
50
- }, ee = {
63
+ // accent text + accent-mid border on white (former "special")
64
+ QUINARY: "quinary",
65
+ // accent text on white, no border (link-style) (former "special2")
66
+ SENARY: "senary",
67
+ // accent text on accent-tint; hover fills solid accent (former "special3")
68
+ DOTTED: "dotted",
69
+ // transparent, dashed border, 24px radius — "add" affordance
70
+ DANGER: "danger",
71
+ // destructive/delete — error text on error-tint (DS tint style)
72
+ // Legacy: solid-red fill (white text) kept for back-compat. The DS treats
73
+ // `warning` as a deprecated alias of `danger` (tint), but app consumers already
74
+ // ship this solid look — kept unchanged to avoid a visual regression. Prefer `danger`.
75
+ WARNING: "warning"
76
+ }, Ke = {
51
77
  SMALL: "small",
52
78
  // 24px
53
79
  MEDIUM: "medium",
@@ -56,62 +82,72 @@ const Y = {
56
82
  // 36px
57
83
  XLARGE: "xlarge"
58
84
  // 48px
59
- }, ke = {
85
+ }, yt = {
60
86
  BUTTON: "button",
61
87
  SUBMIT: "submit",
62
88
  RESET: "reset"
63
- }, $e = ["type", "disabled", "autofocus", "aria-busy", "aria-disabled", "aria-label"], Te = {
64
- key: 1,
89
+ }, mt = ["type", "disabled", "autofocus", "aria-busy", "aria-disabled", "aria-pressed", "aria-label"], ht = ["aria-hidden"], gt = {
90
+ key: 0,
65
91
  class: "ds-button__icon ds-button__icon--leading"
66
- }, Ie = {
92
+ }, St = {
67
93
  class: "material-icons",
68
94
  "aria-hidden": "true"
69
- }, Ce = {
70
- key: 2,
95
+ }, kt = {
96
+ key: 1,
71
97
  class: "ds-button__label"
72
- }, Ee = {
73
- key: 3,
98
+ }, pt = {
99
+ key: 2,
74
100
  class: "ds-button__icon ds-button__icon--trailing"
75
- }, Le = {
101
+ }, $t = {
76
102
  class: "material-icons",
77
103
  "aria-hidden": "true"
78
- }, De = /* @__PURE__ */ k({
104
+ }, Tt = /* @__PURE__ */ x({
79
105
  __name: "DsButton",
80
106
  props: {
81
- variant: { type: String, default: J.PRIMARY },
82
- size: { type: String, default: ee.MEDIUM },
107
+ variant: { type: String, default: Ae.DEFAULT },
108
+ size: { type: String, default: Ke.MEDIUM },
83
109
  nativeType: {
84
110
  type: String,
85
- default: ke.BUTTON
111
+ default: yt.BUTTON
86
112
  },
87
113
  // Material Icon names (rendered via <i class="material-icons">); a leading/
88
- // trailing slot overrides. Icon-only buttons need ariaLabel.
114
+ // trailing slot overrides. Icon-only buttons (circle/square) need ariaLabel.
89
115
  leftIcon: { type: String, default: "" },
90
116
  rightIcon: { type: String, default: "" },
91
117
  ariaLabel: { type: String, default: "" },
92
118
  disabled: Boolean,
93
119
  loading: Boolean,
120
+ // Round icon-only button (width === height, fully circular).
94
121
  circle: Boolean,
95
- dashed: Boolean,
122
+ // Flat 4px-radius icon-only button (the DS `*-square` sizes): symmetric padding
123
+ // per size, height === width.
124
+ square: Boolean,
125
+ // Zero the square padding for a tight, edge-to-edge glyph (DS `small-square-no-padding`).
126
+ // Only takes effect together with `square`.
127
+ noPadding: Boolean,
128
+ // Toggle state: accent outline + fill; sets aria-pressed (DS `selected`).
129
+ selected: Boolean,
96
130
  autofocus: Boolean
97
131
  },
98
132
  emits: [Z],
99
133
  setup(e, { emit: n }) {
100
- const o = e, l = n, i = S(() => o.size === ee.SMALL ? 14 : 20), d = S(
101
- () => o.variant === J.PRIMARY ? Y.LIGHT : Y.DARK
134
+ const t = e, o = n, i = g(() => t.size === Ke.SMALL ? 14 : 20), c = g(
135
+ () => t.variant === Ae.PRIMARY || t.variant === Ae.WARNING ? ge.LIGHT : ge.DARK
102
136
  );
103
- function c(u) {
104
- o.disabled || o.loading || l(Z, u);
137
+ function k(f) {
138
+ t.disabled || t.loading || o(Z, f);
105
139
  }
106
- return (u, b) => (t(), a("button", {
107
- class: v(["ds-button", [
140
+ return (f, y) => (a(), l("button", {
141
+ class: $(["ds-button", [
108
142
  `ds-button--${e.variant}`,
109
143
  `ds-button--${e.size}`,
110
144
  {
111
145
  "is-disabled": e.disabled || e.loading,
112
146
  "is-loading": e.loading,
113
147
  "is-circle": e.circle,
114
- "is-dashed": e.dashed
148
+ "is-square": e.square,
149
+ "is-no-padding": e.noPadding,
150
+ "is-selected": e.selected
115
151
  }
116
152
  ]]),
117
153
  type: e.nativeType,
@@ -119,33 +155,41 @@ const Y = {
119
155
  autofocus: e.autofocus,
120
156
  "aria-busy": e.loading || void 0,
121
157
  "aria-disabled": e.disabled || e.loading || void 0,
158
+ "aria-pressed": e.selected || void 0,
122
159
  "aria-label": e.ariaLabel || void 0,
123
- onClick: c
160
+ onClick: k
124
161
  }, [
125
- e.loading ? (t(), D(g(Se), {
162
+ e.loading ? (a(), G(_(fe), {
126
163
  key: 0,
127
164
  class: "ds-button__spinner",
128
165
  size: i.value,
129
- tone: d.value
130
- }, null, 8, ["size", "tone"])) : r("", !0),
131
- !e.loading && (e.leftIcon || u.$slots.leading) ? (t(), a("span", Te, [
132
- I(u.$slots, "leading", {}, () => [
133
- s("i", Ie, y(e.leftIcon), 1)
134
- ], !0)
135
- ])) : r("", !0),
136
- !e.loading && u.$slots.default ? (t(), a("span", Ce, [
137
- I(u.$slots, "default", {}, void 0, !0)
138
- ])) : r("", !0),
139
- !e.loading && (e.rightIcon || u.$slots.trailing) ? (t(), a("span", Ee, [
140
- I(u.$slots, "trailing", {}, () => [
141
- s("i", Le, y(e.rightIcon), 1)
142
- ], !0)
143
- ])) : r("", !0)
144
- ], 10, $e));
166
+ tone: c.value
167
+ }, null, 8, ["size", "tone"])) : m("", !0),
168
+ s("span", {
169
+ class: "ds-button__content",
170
+ "aria-hidden": e.loading || void 0
171
+ }, [
172
+ e.leftIcon || f.$slots.leading ? (a(), l("span", gt, [
173
+ A(f.$slots, "leading", {}, () => [
174
+ s("i", St, S(e.leftIcon), 1)
175
+ ], !0)
176
+ ])) : m("", !0),
177
+ f.$slots.default && !e.circle && !e.square ? (a(), l("span", kt, [
178
+ A(f.$slots, "default", {}, void 0, !0)
179
+ ])) : m("", !0),
180
+ e.rightIcon || f.$slots.trailing ? (a(), l("span", pt, [
181
+ A(f.$slots, "trailing", {}, () => [
182
+ s("i", $t, S(e.rightIcon), 1)
183
+ ], !0)
184
+ ])) : m("", !0)
185
+ ], 8, ht)
186
+ ], 10, mt));
145
187
  }
146
- }), K = /* @__PURE__ */ $(De, [["__scopeId", "data-v-662e5512"]]), we = {
188
+ }), oe = /* @__PURE__ */ M(Tt, [["__scopeId", "data-v-61354b19"]]), Et = {
147
189
  DEFAULT: "default",
148
190
  // white bg, slate-tint border, muted text
191
+ GREY: "grey",
192
+ // alias of `default` — the DS app passes tone="grey" (ApiApp.jsx)
149
193
  SUCCESS: "success",
150
194
  // e.g. Verified
151
195
  INFO: "info",
@@ -154,17 +198,26 @@ const Y = {
154
198
  // e.g. Pending
155
199
  ERROR: "error"
156
200
  // e.g. Bounced
157
- }, Ne = ["aria-label"], Re = /* @__PURE__ */ k({
201
+ }, Lt = { class: "ds-tag__label" }, wt = ["aria-label"], It = /* @__PURE__ */ x({
158
202
  __name: "DsTag",
159
203
  props: {
160
204
  tone: {
161
205
  type: String,
162
- default: we.DEFAULT
206
+ default: Et.DEFAULT
163
207
  },
164
208
  // Semicircular sides (DS `rounded`): radius-round vs the default radius-control.
165
209
  rounded: Boolean,
166
210
  // Show a × close control that emits `close`.
167
211
  closable: Boolean,
212
+ // Clickable affordance (DS: presence of `onClick` toggles cursor: pointer).
213
+ // Vue can't cheaply detect an attached native @click listener, so this is an
214
+ // explicit opt-in; it only sets cursor styling and doesn't touch the native
215
+ // @click fallthrough behavior.
216
+ clickable: Boolean,
217
+ // Opt-in single-line truncation for long labels (default off). The consuming
218
+ // app sets the ceiling via the `--ds-tag-max-width` CSS custom property; the
219
+ // label then clips with an ellipsis while the close control stays intact.
220
+ truncate: Boolean,
168
221
  // Accessible name for the × control (the app owns the wording / i18n).
169
222
  closeLabel: {
170
223
  type: String,
@@ -172,26 +225,31 @@ const Y = {
172
225
  }
173
226
  },
174
227
  setup(e, { emit: n }) {
175
- const o = n;
176
- return (l, i) => (t(), a("span", {
177
- class: v(["ds-tag", [`ds-tag--${e.tone}`, { "is-rounded": e.rounded }]])
228
+ const t = n;
229
+ return (o, i) => (a(), l("span", {
230
+ class: $(["ds-tag", [
231
+ `ds-tag--${e.tone}`,
232
+ { "is-rounded": e.rounded, "is-clickable": e.clickable, "is-truncate": e.truncate }
233
+ ]])
178
234
  }, [
179
- I(l.$slots, "default", {}, void 0, !0),
180
- e.closable ? (t(), a("button", {
235
+ s("span", Lt, [
236
+ A(o.$slots, "default", {}, void 0, !0)
237
+ ]),
238
+ e.closable ? (a(), l("button", {
181
239
  key: 0,
182
240
  type: "button",
183
241
  class: "ds-tag__close",
184
242
  "aria-label": e.closeLabel || void 0,
185
- onClick: i[0] || (i[0] = (d) => o(g(C)))
243
+ onClick: i[0] || (i[0] = ve((c) => t(_(X)), ["stop"]))
186
244
  }, [...i[1] || (i[1] = [
187
245
  s("i", {
188
246
  class: "material-icons",
189
247
  "aria-hidden": "true"
190
248
  }, "close", -1)
191
- ])], 8, Ne)) : r("", !0)
249
+ ])], 8, wt)) : m("", !0)
192
250
  ], 2));
193
251
  }
194
- }), ta = /* @__PURE__ */ $(Re, [["__scopeId", "data-v-4507fdca"]]), H = {
252
+ }), xi = /* @__PURE__ */ M(It, [["__scopeId", "data-v-0540d9b3"]]), Re = {
195
253
  ACCENT: "accent",
196
254
  // e.g. Work (purple)
197
255
  GREY: "grey",
@@ -204,82 +262,193 @@ const Y = {
204
262
  // coral
205
263
  WARNING: "warning"
206
264
  // orange
207
- }, Be = /* @__PURE__ */ k({
265
+ }, Ct = /* @__PURE__ */ x({
208
266
  __name: "DsBadge",
209
267
  props: {
210
268
  tone: {
211
269
  type: String,
212
- default: H.ACCENT
270
+ default: Re.ACCENT
213
271
  }
214
272
  },
215
273
  setup(e) {
216
- return (n, o) => (t(), a("span", {
217
- class: v(["ds-badge", `ds-badge--${e.tone}`])
274
+ return (n, t) => (a(), l("span", {
275
+ class: $(["ds-badge", `ds-badge--${e.tone}`])
218
276
  }, [
219
- I(n.$slots, "default", {}, void 0, !0)
277
+ A(n.$slots, "default", {}, void 0, !0)
220
278
  ], 2));
221
279
  }
222
- }), Ae = /* @__PURE__ */ $(Be, [["__scopeId", "data-v-f10a17a0"]]), Oe = ["src", "alt"], xe = ["aria-label"], Me = /* @__PURE__ */ k({
280
+ }), _t = /* @__PURE__ */ M(Ct, [["__scopeId", "data-v-f10a17a0"]]), Dt = ["src", "alt"], At = ["aria-label"], Nt = /* @__PURE__ */ x({
223
281
  __name: "DsAvatar",
224
282
  props: {
225
283
  image: { type: String, default: "" },
226
284
  firstName: { type: String, default: "" },
227
285
  lastName: { type: String, default: "" },
286
+ // Explicit initials (DS `letters`) — overrides the computed firstName+lastName
287
+ // initials when non-empty. Passed through as-is (no uppercase transform),
288
+ // matching the DS: only the firstName+lastName path uppercases.
289
+ letters: { type: String, default: "" },
228
290
  uid: { type: String, default: "" },
229
291
  size: { type: Number, default: 40 },
292
+ // Explicit width/height (DS parity) — override `size` per-axis when present.
293
+ width: { type: Number, default: void 0 },
294
+ height: { type: Number, default: void 0 },
295
+ // Initials font-size in px — overrides the computed ~40%-of-box value when present.
296
+ textSize: { type: Number, default: void 0 },
297
+ // Initials font-weight — overrides the default token weight (900) when present.
298
+ fontWeight: { type: [Number, String], default: void 0 },
230
299
  circular: Boolean,
231
- // Accessible label (defaults to "firstName lastName").
232
- alt: { type: String, default: "" }
300
+ // Accessible label. Omitted → falls back to the computed name/letters. An explicit
301
+ // value wins including `alt=""` for a deliberately decorative image (default is
302
+ // `undefined`, so "" is distinguishable from "not provided").
303
+ alt: { type: String, default: void 0 }
233
304
  },
234
305
  setup(e) {
235
- const n = e, o = S(
236
- () => n.firstName && n.lastName ? (n.firstName.charAt(0) + n.lastName.charAt(0)).toUpperCase() : ""
237
- ), l = S(() => n.alt || `${n.firstName} ${n.lastName}`.trim()), i = S(() => ({ width: `${n.size}px`, height: `${n.size}px` })), d = S(() => {
238
- const c = n.uid || n.firstName + n.lastName;
239
- let u = 0;
240
- for (let f = 0; f < c.length; f++)
241
- u = c.charCodeAt(f) + ((u << 5) - u), u = u & u;
242
- const b = [0, 0, 0];
243
- for (let f = 0; f < 3; f++) b[f] = u >> f * 8 & 255;
244
- const m = b[0] >= 200 && b[1] >= 200 && b[2] >= 200;
245
- return { bg: `rgb(${b[0]}, ${b[1]}, ${b[2]})`, fg: m ? "#323f4b" : "#fff" };
306
+ const n = e, t = g(() => n.letters ? n.letters : n.firstName && n.lastName ? (n.firstName.charAt(0) + n.lastName.charAt(0)).toUpperCase() : ""), o = g(() => `${n.firstName} ${n.lastName}`.trim() || n.letters), i = g(() => {
307
+ var d;
308
+ return (d = n.alt) != null ? d : o.value;
309
+ }), c = g(() => {
310
+ var d;
311
+ return (d = n.width) != null ? d : n.size;
312
+ }), k = g(() => {
313
+ var d;
314
+ return (d = n.height) != null ? d : n.size;
315
+ }), f = g(() => ({ width: `${c.value}px`, height: `${k.value}px` })), y = g(
316
+ () => {
317
+ var d;
318
+ return (d = n.textSize) != null ? d : Math.round(Math.min(c.value, k.value) * 0.4);
319
+ }
320
+ ), r = g(() => {
321
+ const d = n.uid || n.firstName + n.lastName || n.letters;
322
+ let b = 0;
323
+ for (let p = 0; p < d.length; p++)
324
+ b = d.charCodeAt(p) + ((b << 5) - b), b = b & b;
325
+ const h = [0, 0, 0];
326
+ for (let p = 0; p < 3; p++) h[p] = b >> p * 8 & 255;
327
+ const T = h[0] >= 200 && h[1] >= 200 && h[2] >= 200;
328
+ return { bg: `rgb(${h[0]}, ${h[1]}, ${h[2]})`, fg: T ? "#323f4b" : "#fff" };
246
329
  });
247
- return (c, u) => e.image ? (t(), a("img", {
330
+ return (d, b) => e.image ? (a(), l("img", {
248
331
  key: 0,
249
- class: v(["ds-avatar", { "is-circular": e.circular }]),
332
+ class: $(["ds-avatar", { "is-circular": e.circular }]),
250
333
  src: e.image,
251
- alt: e.alt,
252
- style: w(i.value)
253
- }, null, 14, Oe)) : o.value ? (t(), a("div", {
334
+ alt: i.value,
335
+ style: F(f.value)
336
+ }, null, 14, Dt)) : t.value ? (a(), l("div", {
254
337
  key: 1,
255
- class: v(["ds-avatar ds-avatar--initials", { "is-circular": e.circular }]),
338
+ class: $(["ds-avatar ds-avatar--initials", { "is-circular": e.circular }]),
256
339
  role: "img",
257
- "aria-label": l.value || void 0,
258
- style: w([
259
- i.value,
260
- { background: d.value.bg, color: d.value.fg, fontSize: `${Math.round(e.size * 0.4)}px` }
340
+ "aria-label": i.value || void 0,
341
+ style: F([
342
+ f.value,
343
+ {
344
+ background: r.value.bg,
345
+ color: r.value.fg,
346
+ fontSize: `${y.value}px`,
347
+ fontWeight: e.fontWeight
348
+ }
261
349
  ])
262
- }, y(o.value), 15, xe)) : (t(), a("div", {
350
+ }, S(t.value), 15, At)) : (a(), l("div", {
263
351
  key: 2,
264
- class: v(["ds-avatar ds-avatar--placeholder", { "is-circular": e.circular }]),
265
- style: w(i.value),
352
+ class: $(["ds-avatar ds-avatar--placeholder", { "is-circular": e.circular }]),
353
+ style: F(f.value),
266
354
  "aria-hidden": "true"
267
355
  }, null, 6));
268
356
  }
269
- }), aa = /* @__PURE__ */ $(Me, [["__scopeId", "data-v-e965ed47"]]), te = {
357
+ }), Mi = /* @__PURE__ */ M(Nt, [["__scopeId", "data-v-4faae4da"]]), Rt = ["disabled", "name", "aria-label"], Bt = {
358
+ key: 0,
359
+ class: "ds-checkbox__mark",
360
+ viewBox: "0 0 16 16",
361
+ fill: "none",
362
+ stroke: "currentColor",
363
+ "stroke-width": "2.5"
364
+ }, xt = {
365
+ key: 1,
366
+ class: "ds-checkbox__mark",
367
+ viewBox: "0 0 16 16",
368
+ fill: "none",
369
+ stroke: "currentColor",
370
+ "stroke-width": "2.5"
371
+ }, Mt = {
372
+ key: 0,
373
+ class: "ds-checkbox__label"
374
+ }, Ot = /* @__PURE__ */ x({
375
+ __name: "DsCheckbox",
376
+ props: /* @__PURE__ */ Q({
377
+ indeterminate: Boolean,
378
+ disabled: Boolean,
379
+ name: { type: String, default: "" },
380
+ // Label text (DS `label` prop); a default slot overrides it.
381
+ label: { type: String, default: "" },
382
+ // Accessible name when there is no visible label (e.g. a select-all in a table).
383
+ ariaLabel: { type: String, default: "" }
384
+ }, {
385
+ modelValue: { type: Boolean, default: !1 },
386
+ modelModifiers: {}
387
+ }),
388
+ emits: ["update:modelValue"],
389
+ setup(e) {
390
+ const n = de(e, "modelValue"), t = e, o = U(null);
391
+ function i() {
392
+ o.value && (o.value.indeterminate = t.indeterminate);
393
+ }
394
+ return Qe(i), te(() => t.indeterminate, i), (c, k) => (a(), l("label", {
395
+ class: $(["ds-checkbox", { "is-disabled": e.disabled }])
396
+ }, [
397
+ Be(s("input", {
398
+ ref_key: "inputRef",
399
+ ref: o,
400
+ "onUpdate:modelValue": k[0] || (k[0] = (f) => n.value = f),
401
+ type: "checkbox",
402
+ class: "ds-checkbox__native",
403
+ disabled: e.disabled,
404
+ name: e.name || void 0,
405
+ "aria-label": e.ariaLabel || void 0
406
+ }, null, 8, Rt), [
407
+ [st, n.value]
408
+ ]),
409
+ s("span", {
410
+ class: $(["ds-checkbox__box", { "is-active": n.value || e.indeterminate }]),
411
+ "aria-hidden": "true"
412
+ }, [
413
+ e.indeterminate ? (a(), l("svg", Bt, [...k[1] || (k[1] = [
414
+ s("line", {
415
+ x1: "4",
416
+ y1: "8",
417
+ x2: "12",
418
+ y2: "8"
419
+ }, null, -1)
420
+ ])])) : n.value ? (a(), l("svg", xt, [...k[2] || (k[2] = [
421
+ s("path", { d: "M3.5 8.5l3 3 6-6" }, null, -1)
422
+ ])])) : m("", !0)
423
+ ], 2),
424
+ c.$slots.default || e.label ? (a(), l("span", Mt, [
425
+ A(c.$slots, "default", {}, () => [
426
+ H(S(e.label), 1)
427
+ ], !0)
428
+ ])) : m("", !0)
429
+ ], 2));
430
+ }
431
+ }), et = /* @__PURE__ */ M(Ot, [["__scopeId", "data-v-2da3772e"]]), Ye = {
270
432
  LEFT: "left",
271
433
  CENTER: "center",
272
434
  RIGHT: "right"
273
- }, Ve = { class: "ds-table" }, Ue = { class: "ds-table__wrapper" }, Fe = { class: "ds-table__table" }, ze = { key: 0 }, _e = ["colspan"], Pe = /* @__PURE__ */ k({
435
+ }, ee = {
436
+ LEFT: "left",
437
+ RIGHT: "right"
438
+ }, Pt = ["aria-busy"], Ft = { class: "ds-table__table" }, zt = { class: "ds-table__head" }, Vt = {
439
+ key: 0,
440
+ class: "ds-table__select-all"
441
+ }, Ut = { key: 0 }, Gt = ["colspan"], Ht = ["aria-busy"], Wt = { key: 0 }, Kt = ["colspan"], Yt = { key: 1 }, qt = ["colspan"], jt = ["title"], Xt = /* @__PURE__ */ x({
274
442
  __name: "DsTable",
275
443
  props: {
444
+ // --- Declarative API (default): the table builds itself from columns + rows. ---
276
445
  columns: {
277
446
  type: Array,
278
- required: !0
447
+ default: () => []
279
448
  },
280
449
  rows: {
281
450
  type: Array,
282
- required: !0
451
+ default: () => []
283
452
  },
284
453
  emptyMessage: {
285
454
  type: String,
@@ -289,59 +458,266 @@ const Y = {
289
458
  highlightRowId: {
290
459
  type: [String, Number],
291
460
  default: null
292
- }
461
+ },
462
+ // Optional fixed row height (number → px, or any CSS length). Rows are
463
+ // content-driven by default; when set, this pins the height AND truncates
464
+ // overflowing cell text with an ellipsis.
465
+ rowHeight: {
466
+ type: [String, Number],
467
+ default: null
468
+ },
469
+ // --- Compound API (opt-in): compose DsTableRow + DsTableCell in the default slot. ---
470
+ // When true, the table renders a shell (headers + a sticky thead) and the body
471
+ // comes from the default slot instead of `rows`. Coexists with the declarative API.
472
+ compound: { type: Boolean, default: !1 },
473
+ // Header labels for the compound shell. Plain strings, or the DsTableHeader
474
+ // object form when a header column needs to be pinned (mirror its `width` on
475
+ // the matching DsCell so the sticky columns line up).
476
+ headers: { type: Array, default: () => [] },
477
+ // Render a leading select-all checkbox column (compound mode).
478
+ selectable: { type: Boolean, default: !1 },
479
+ allSelected: { type: Boolean, default: !1 },
480
+ someSelected: { type: Boolean, default: !1 },
481
+ // Accessible name for the select-all checkbox (no visible text in a 52px column).
482
+ selectAllLabel: { type: String, default: "" },
483
+ // Fixed height enabling the sticky-header scroll (compound mode).
484
+ height: {
485
+ type: [String, Number],
486
+ default: null
487
+ },
488
+ // --- Loading state (both APIs) ---
489
+ // When true, the body is a single centered spinner row spanning every column,
490
+ // shown INSTEAD of the empty state or the rows/slot (loading wins over both).
491
+ loading: { type: Boolean, default: !1 },
492
+ // Accessible name for the loading spinner (the app owns i18n); when omitted it
493
+ // falls back to DsSpinner's own default. Overridable per row via the #loading slot.
494
+ loadingLabel: { type: String, default: "" }
293
495
  },
294
- setup(e) {
295
- return (n, o) => (t(), a("div", Ve, [
296
- s("div", Ue, [
297
- s("table", Fe, [
496
+ emits: [ze],
497
+ setup(e, { emit: n }) {
498
+ const t = e, o = n, i = g(
499
+ () => Math.max(1, t.headers.length + (t.selectable ? 1 : 0))
500
+ ), c = g(
501
+ () => t.rowHeight == null ? void 0 : {
502
+ "--ds-table-row-height": typeof t.rowHeight == "number" ? `${t.rowHeight}px` : t.rowHeight
503
+ }
504
+ ), k = g(
505
+ () => t.height == null ? void 0 : { height: typeof t.height == "number" ? `${t.height}px` : t.height }
506
+ );
507
+ function f(v) {
508
+ o(ze, v);
509
+ }
510
+ function y(v) {
511
+ if (!v) return 0;
512
+ const D = /^(\d+(?:\.\d+)?)px$/.exec(v.trim());
513
+ return D ? parseFloat(D[1]) : 0;
514
+ }
515
+ const r = g(() => {
516
+ const v = {};
517
+ let D = 0;
518
+ for (const I of t.columns)
519
+ I.pinned === ee.LEFT && (v[I.key] = { position: "sticky", left: `${D}px` }, D += y(I.width));
520
+ let w = 0;
521
+ for (let I = t.columns.length - 1; I >= 0; I--) {
522
+ const P = t.columns[I];
523
+ P.pinned === ee.RIGHT && (v[P.key] = { position: "sticky", right: `${w}px` }, w += y(P.width));
524
+ }
525
+ return v;
526
+ }), d = g(() => {
527
+ const v = t.columns.filter((I) => I.pinned === ee.LEFT), D = t.columns.filter((I) => I.pinned === ee.RIGHT), w = /* @__PURE__ */ new Set();
528
+ return v.length && w.add(v[v.length - 1].key), D.length && w.add(D[0].key), w;
529
+ });
530
+ function b(v) {
531
+ if (v.pinned)
532
+ return {
533
+ "ds-table__pin": !0,
534
+ [`ds-table__pin--${v.pinned}`]: !0,
535
+ "ds-table__pin--edge": d.value.has(v.key)
536
+ };
537
+ }
538
+ function h(v) {
539
+ const D = r.value[v.key], w = v.width ? { width: v.width } : void 0;
540
+ if (!(!D && !w))
541
+ return { ...w, ...D };
542
+ }
543
+ function T(v) {
544
+ const D = r.value[v.key];
545
+ if (D)
546
+ return v.width ? { ...D, width: v.width } : D;
547
+ }
548
+ const p = g(
549
+ () => t.headers.map((v) => typeof v == "string" ? { label: v } : v)
550
+ ), V = g(() => {
551
+ const v = {}, D = p.value;
552
+ let w = 0;
553
+ D.forEach((P, ne) => {
554
+ P.pinned === ee.LEFT && (v[ne] = { position: "sticky", left: `${w}px` }, w += y(P.width));
555
+ });
556
+ let I = 0;
557
+ for (let P = D.length - 1; P >= 0; P--)
558
+ D[P].pinned === ee.RIGHT && (v[P] = { position: "sticky", right: `${I}px` }, I += y(D[P].width));
559
+ return v;
560
+ }), C = g(() => {
561
+ const v = p.value, D = v.map((P, ne) => ({ h: P, i: ne })).filter(({ h: P }) => P.pinned === ee.LEFT), w = v.map((P, ne) => ({ h: P, i: ne })).filter(({ h: P }) => P.pinned === ee.RIGHT), I = /* @__PURE__ */ new Set();
562
+ return D.length && I.add(D[D.length - 1].i), w.length && I.add(w[0].i), I;
563
+ });
564
+ function E(v, D) {
565
+ if (v.pinned)
566
+ return {
567
+ "ds-table__pin": !0,
568
+ [`ds-table__pin--${v.pinned}`]: !0,
569
+ "ds-table__pin--edge": C.value.has(D)
570
+ };
571
+ }
572
+ function N(v, D) {
573
+ const w = V.value[D], I = v.width ? { width: v.width } : void 0;
574
+ if (!(!w && !I))
575
+ return { ...I, ...w };
576
+ }
577
+ const R = U(null), q = U(!1), J = U(!1);
578
+ let W = null;
579
+ function ae() {
580
+ const v = R.value;
581
+ v && (q.value = v.scrollLeft > 0, J.value = v.scrollLeft + v.clientWidth < v.scrollWidth - 1);
582
+ }
583
+ function re(v) {
584
+ v == null || v.removeEventListener("scroll", ae), W == null || W.disconnect(), W = null;
585
+ }
586
+ return te(
587
+ R,
588
+ (v, D) => {
589
+ re(D != null ? D : null), v && (v.addEventListener("scroll", ae, { passive: !0 }), typeof ResizeObserver != "undefined" && (W = new ResizeObserver(ae), W.observe(v)), ae());
590
+ },
591
+ { immediate: !0 }
592
+ ), be(() => re(R.value)), te(
593
+ () => [t.columns.length, t.rows.length, t.headers.length, t.compound],
594
+ () => ue(ae)
595
+ ), (v, D) => e.compound ? (a(), l("div", {
596
+ key: 0,
597
+ class: "ds-table ds-table--compound",
598
+ "aria-busy": e.loading ? "true" : void 0
599
+ }, [
600
+ s("div", {
601
+ ref_key: "wrapperRef",
602
+ ref: R,
603
+ class: $(["ds-table__wrapper", { "is-scrolled-start": q.value, "is-scrolled-end": J.value }]),
604
+ style: F(k.value)
605
+ }, [
606
+ s("table", Ft, [
607
+ s("thead", zt, [
608
+ s("tr", null, [
609
+ e.selectable ? (a(), l("th", Vt, [
610
+ j(_(et), {
611
+ "model-value": e.allSelected,
612
+ indeterminate: !e.allSelected && e.someSelected,
613
+ "aria-label": e.selectAllLabel || void 0,
614
+ "onUpdate:modelValue": f
615
+ }, null, 8, ["model-value", "indeterminate", "aria-label"])
616
+ ])) : m("", !0),
617
+ (a(!0), l(z, null, Y(p.value, (w, I) => (a(), l("th", {
618
+ key: w.label,
619
+ class: $(E(w, I)),
620
+ style: F(N(w, I))
621
+ }, S(w.label), 7))), 128))
622
+ ])
623
+ ]),
624
+ s("tbody", null, [
625
+ e.loading ? (a(), l("tr", Ut, [
626
+ s("td", {
627
+ class: "ds-table__loading",
628
+ colspan: i.value,
629
+ "data-testid": "ds-table-loading"
630
+ }, [
631
+ A(v.$slots, "loading", {}, () => [
632
+ j(_(fe), {
633
+ label: e.loadingLabel || void 0
634
+ }, null, 8, ["label"])
635
+ ], !0)
636
+ ], 8, Gt)
637
+ ])) : A(v.$slots, "default", { key: 1 }, void 0, !0)
638
+ ])
639
+ ])
640
+ ], 6)
641
+ ], 8, Pt)) : (a(), l("div", {
642
+ key: 1,
643
+ class: "ds-table",
644
+ "aria-busy": e.loading ? "true" : void 0
645
+ }, [
646
+ s("div", {
647
+ ref_key: "wrapperRef",
648
+ ref: R,
649
+ class: $(["ds-table__wrapper", { "is-scrolled-start": q.value, "is-scrolled-end": J.value }])
650
+ }, [
651
+ s("table", {
652
+ class: $(["ds-table__table", { "has-row-height": e.rowHeight != null }]),
653
+ style: F(c.value)
654
+ }, [
298
655
  s("thead", null, [
299
656
  s("tr", null, [
300
- (t(!0), a(B, null, M(e.columns, (l) => {
301
- var i;
302
- return t(), a("th", {
303
- key: l.key,
304
- class: v(`ds-table__th--${(i = l.align) != null ? i : g(te).LEFT}`),
305
- style: w(l.width ? { width: l.width } : void 0)
306
- }, y(l.label), 7);
657
+ (a(!0), l(z, null, Y(e.columns, (w) => {
658
+ var I;
659
+ return a(), l("th", {
660
+ key: w.key,
661
+ class: $([
662
+ `ds-table__th--${(I = w.align) != null ? I : _(Ye).LEFT}`,
663
+ b(w)
664
+ ]),
665
+ style: F(h(w))
666
+ }, S(w.label), 7);
307
667
  }), 128))
308
668
  ])
309
669
  ]),
310
670
  s("tbody", null, [
311
- e.rows.length === 0 ? (t(), a("tr", ze, [
671
+ e.loading ? (a(), l("tr", Wt, [
672
+ s("td", {
673
+ class: "ds-table__loading",
674
+ colspan: Math.max(1, e.columns.length),
675
+ "data-testid": "ds-table-loading"
676
+ }, [
677
+ A(v.$slots, "loading", {}, () => [
678
+ j(_(fe), {
679
+ label: e.loadingLabel || void 0
680
+ }, null, 8, ["label"])
681
+ ], !0)
682
+ ], 8, Kt)
683
+ ])) : e.rows.length === 0 ? (a(), l("tr", Yt, [
312
684
  s("td", {
313
685
  class: "ds-table__empty",
314
- colspan: e.columns.length,
686
+ colspan: Math.max(1, e.columns.length),
315
687
  "data-testid": "ds-table-empty"
316
688
  }, [
317
- I(n.$slots, "empty", {}, () => [
318
- A(y(e.emptyMessage), 1)
689
+ A(v.$slots, "empty", {}, () => [
690
+ H(S(e.emptyMessage), 1)
319
691
  ], !0)
320
- ], 8, _e)
321
- ])) : r("", !0),
322
- (t(!0), a(B, null, M(e.rows, (l) => (t(), a("tr", {
323
- key: l.id,
324
- class: v({ "is-highlighted": l.id === e.highlightRowId }),
692
+ ], 8, qt)
693
+ ])) : (a(!0), l(z, { key: 2 }, Y(e.rows, (w) => (a(), l("tr", {
694
+ key: w.id,
695
+ class: $({ "is-highlighted": w.id === e.highlightRowId }),
325
696
  "data-testid": "ds-table-row"
326
697
  }, [
327
- (t(!0), a(B, null, M(e.columns, (i) => {
328
- var d;
329
- return t(), a("td", {
330
- key: i.key,
331
- class: v(`ds-table__td--${(d = i.align) != null ? d : g(te).LEFT}`)
698
+ (a(!0), l(z, null, Y(e.columns, (I) => {
699
+ var P;
700
+ return a(), l("td", {
701
+ key: I.key,
702
+ class: $([
703
+ `ds-table__td--${(P = I.align) != null ? P : _(Ye).LEFT}`,
704
+ b(I)
705
+ ]),
706
+ style: F(T(I)),
707
+ title: e.rowHeight != null && !v.$slots[`cell-${I.key}`] && w[I.key] != null ? String(w[I.key]) : void 0
332
708
  }, [
333
- I(n.$slots, `cell-${i.key}`, { row: l }, () => [
334
- A(y(l[i.key]), 1)
709
+ A(v.$slots, `cell-${I.key}`, { row: w }, () => [
710
+ H(S(w[I.key]), 1)
335
711
  ], !0)
336
- ], 2);
712
+ ], 14, jt);
337
713
  }), 128))
338
714
  ], 2))), 128))
339
715
  ])
340
- ])
341
- ])
342
- ]));
716
+ ], 6)
717
+ ], 2)
718
+ ], 8, Ht));
343
719
  }
344
- }), la = /* @__PURE__ */ $(Pe, [["__scopeId", "data-v-1735ff35"]]), P = {
720
+ }), Oi = /* @__PURE__ */ M(Xt, [["__scopeId", "data-v-7a5bb12f"]]), ce = {
345
721
  TEXT: "text",
346
722
  EMAIL: "email",
347
723
  PASSWORD: "password",
@@ -349,26 +725,30 @@ const Y = {
349
725
  NUMBER: "number",
350
726
  SEARCH: "search",
351
727
  URL: "url"
352
- }, Ge = {
728
+ }, Zt = {
353
729
  SM: "sm",
354
730
  // 36px
355
731
  MD: "md"
356
732
  // 48px
357
- }, Ye = { class: "ds-input__wrap" }, Ke = ["id", "type", "placeholder", "disabled", "name", "autocomplete", "aria-invalid", "aria-describedby"], He = {
733
+ }, Qt = { class: "ds-input__wrap" }, Jt = {
358
734
  key: 0,
735
+ class: "material-icons ds-input__search-icon",
736
+ "aria-hidden": "true"
737
+ }, ea = ["id", "type", "placeholder", "min", "max", "step", "disabled", "name", "autocomplete", "aria-invalid", "aria-describedby"], ta = {
738
+ key: 1,
359
739
  class: "ds-input__suffix"
360
- }, We = {
740
+ }, aa = {
361
741
  key: 0,
362
742
  class: "material-icons ds-input__error-icon",
363
743
  "aria-hidden": "true"
364
- }, qe = ["aria-label", "aria-pressed"], pe = {
744
+ }, la = ["disabled", "aria-label", "aria-pressed"], ia = {
365
745
  class: "material-icons",
366
746
  "aria-hidden": "true"
367
- }, Xe = ["id"], Ze = /* @__PURE__ */ k({
747
+ }, na = ["id"], sa = /* @__PURE__ */ x({
368
748
  __name: "DsInput",
369
- props: /* @__PURE__ */ O({
370
- type: { type: String, default: P.TEXT },
371
- size: { type: String, default: Ge.SM },
749
+ props: /* @__PURE__ */ Q({
750
+ type: { type: String, default: ce.TEXT },
751
+ size: { type: String, default: Zt.SM },
372
752
  placeholder: { type: String, default: "" },
373
753
  disabled: Boolean,
374
754
  error: Boolean,
@@ -378,82 +758,134 @@ const Y = {
378
758
  id: { type: String, default: "" },
379
759
  autocomplete: { type: String, default: "" },
380
760
  // Accessible name for the password visibility toggle.
381
- toggleLabel: { type: String, default: "" }
761
+ toggleLabel: { type: String, default: "" },
762
+ // Native number-input constraints — only meaningful for type="number", forwarded
763
+ // to the real <input>. String is allowed so `step="any"` is expressible.
764
+ min: { type: [Number, String], default: void 0 },
765
+ max: { type: [Number, String], default: void 0 },
766
+ step: { type: [Number, String], default: void 0 }
382
767
  }, {
383
768
  modelValue: { default: "" },
384
769
  modelModifiers: {}
385
770
  }),
386
- emits: /* @__PURE__ */ O([V, U], ["update:modelValue"]),
387
- setup(e, { emit: n }) {
388
- const o = W(e, "modelValue"), l = e, i = n, d = le(), c = N(!1), u = S(() => l.type === P.PASSWORD), b = S(
389
- () => u.value && c.value ? P.TEXT : l.type
390
- ), m = S(
391
- () => !!d.suffix || l.error && l.showErrorIcon || u.value
771
+ emits: /* @__PURE__ */ Q([Se, ke, Me, Oe], ["update:modelValue"]),
772
+ setup(e, { expose: n, emit: t }) {
773
+ const o = de(e, "modelValue"), i = e, c = t, k = U();
774
+ function f(C) {
775
+ const E = C.relatedTarget, N = C.currentTarget;
776
+ E && (N != null && N.contains(E)) || c(Oe, C);
777
+ }
778
+ const y = Ee(), r = U(!1);
779
+ function d() {
780
+ i.disabled || (r.value = !r.value);
781
+ }
782
+ const b = g(() => i.type === ce.PASSWORD), h = g(() => i.type === ce.SEARCH), T = g(() => b.value ? r.value ? ce.TEXT : ce.PASSWORD : h.value ? ce.TEXT : i.type), p = g(() => b.value && !!i.toggleLabel), V = g(
783
+ () => !!y.suffix || i.error && i.showErrorIcon || p.value
392
784
  );
393
- return (f, h) => (t(), a("div", {
394
- class: v(["ds-input", [`ds-input--${e.size}`, { "is-error": e.error, "is-disabled": e.disabled }]])
785
+ return n({
786
+ focus: () => {
787
+ var C;
788
+ return (C = k.value) == null ? void 0 : C.focus();
789
+ },
790
+ focusAtEnd: async () => {
791
+ await ue();
792
+ const C = k.value;
793
+ if (!C) return;
794
+ C.focus();
795
+ const E = C.value.length;
796
+ try {
797
+ C.setSelectionRange(E, E);
798
+ } catch {
799
+ }
800
+ }
801
+ }), (C, E) => (a(), l("div", {
802
+ class: $(["ds-input", [
803
+ `ds-input--${e.size}`,
804
+ { "is-error": e.error, "is-disabled": e.disabled, "is-search": h.value }
805
+ ]]),
806
+ onFocusout: f
395
807
  }, [
396
- s("div", Ye, [
397
- q(s("input", {
808
+ s("div", Qt, [
809
+ h.value ? (a(), l("i", Jt, "search")) : m("", !0),
810
+ Be(s("input", {
398
811
  id: e.id || void 0,
399
- "onUpdate:modelValue": h[0] || (h[0] = (T) => o.value = T),
400
- class: v(["ds-input__control", { "has-suffix": m.value }]),
401
- type: b.value,
812
+ ref_key: "inputEl",
813
+ ref: k,
814
+ "onUpdate:modelValue": E[0] || (E[0] = (N) => o.value = N),
815
+ class: $(["ds-input__control", { "has-suffix": V.value }]),
816
+ type: T.value,
402
817
  placeholder: e.placeholder,
818
+ min: e.min,
819
+ max: e.max,
820
+ step: e.step,
403
821
  disabled: e.disabled,
404
822
  name: e.name || void 0,
405
823
  autocomplete: e.autocomplete || void 0,
406
824
  "aria-invalid": e.error || void 0,
407
825
  "aria-describedby": e.error && e.errorMessage && e.id ? `${e.id}-error` : void 0,
408
- onFocus: h[1] || (h[1] = (T) => i(g(V), T)),
409
- onBlur: h[2] || (h[2] = (T) => i(g(U), T))
410
- }, null, 42, Ke), [
411
- [ce, o.value]
826
+ onFocus: E[1] || (E[1] = (N) => c(_(Se), N)),
827
+ onBlur: E[2] || (E[2] = (N) => c(_(ke), N)),
828
+ onChange: E[3] || (E[3] = (N) => c(_(Me), N))
829
+ }, null, 42, ea), [
830
+ [ot, o.value]
412
831
  ]),
413
- m.value ? (t(), a("div", He, [
414
- I(f.$slots, "suffix", {}, void 0, !0),
415
- e.error && e.showErrorIcon ? (t(), a("i", We, "warning")) : u.value ? (t(), a("button", {
832
+ V.value ? (a(), l("div", ta, [
833
+ A(C.$slots, "suffix", {}, void 0, !0),
834
+ e.error && e.showErrorIcon ? (a(), l("i", aa, "warning")) : p.value ? (a(), l("button", {
416
835
  key: 1,
417
836
  type: "button",
418
837
  class: "ds-input__toggle",
838
+ disabled: e.disabled,
419
839
  "aria-label": e.toggleLabel || void 0,
420
- "aria-pressed": c.value,
421
- onClick: h[3] || (h[3] = (T) => c.value = !c.value)
840
+ "aria-pressed": r.value,
841
+ onClick: d
422
842
  }, [
423
- s("i", pe, y(c.value ? "visibility" : "visibility_off"), 1)
424
- ], 8, qe)) : r("", !0)
425
- ])) : r("", !0)
843
+ s("i", ia, S(r.value ? "visibility" : "visibility_off"), 1)
844
+ ], 8, la)) : m("", !0)
845
+ ])) : m("", !0)
426
846
  ]),
427
- e.error && e.errorMessage ? (t(), a("p", {
847
+ e.error && e.errorMessage ? (a(), l("p", {
428
848
  key: 0,
429
849
  id: e.id ? `${e.id}-error` : void 0,
430
850
  class: "ds-input__error"
431
- }, y(e.errorMessage), 9, Xe)) : r("", !0)
432
- ], 2));
851
+ }, S(e.errorMessage), 9, na)) : m("", !0)
852
+ ], 34));
433
853
  }
434
- }), ia = /* @__PURE__ */ $(Ze, [["__scopeId", "data-v-d4b27b55"]]), je = ["id", "placeholder", "rows", "disabled", "name", "aria-invalid", "aria-describedby"], Qe = ["id"], Je = /* @__PURE__ */ k({
854
+ }), Pi = /* @__PURE__ */ M(sa, [["__scopeId", "data-v-a7832472"]]), oa = {
855
+ VERTICAL: "vertical"
856
+ }, da = ["id", "placeholder", "rows", "disabled", "name", "aria-invalid", "aria-describedby"], ra = ["id"], ca = /* @__PURE__ */ x({
857
+ inheritAttrs: !1,
435
858
  __name: "DsTextarea",
436
- props: /* @__PURE__ */ O({
859
+ props: /* @__PURE__ */ Q({
437
860
  placeholder: { type: String, default: "" },
438
861
  rows: { type: Number, default: 4 },
439
862
  disabled: Boolean,
440
863
  error: Boolean,
441
864
  errorMessage: { type: String, default: "" },
442
865
  name: { type: String, default: "" },
443
- id: { type: String, default: "" }
866
+ id: { type: String, default: "" },
867
+ // CSS resize behavior of the control (default vertical, mirrors the DS).
868
+ resize: {
869
+ type: String,
870
+ default: oa.VERTICAL
871
+ }
444
872
  }, {
445
873
  modelValue: { default: "" },
446
874
  modelModifiers: {}
447
875
  }),
448
- emits: /* @__PURE__ */ O([V, U], ["update:modelValue"]),
876
+ emits: /* @__PURE__ */ Q([Se, ke], ["update:modelValue"]),
449
877
  setup(e, { emit: n }) {
450
- const o = W(e, "modelValue"), l = n;
451
- return (i, d) => (t(), a("div", {
452
- class: v(["ds-textarea", { "is-error": e.error, "is-disabled": e.disabled }])
453
- }, [
454
- q(s("textarea", {
878
+ const t = de(e, "modelValue"), o = n, i = dt(), c = (y) => y === "class" || y === "style" || y.startsWith("data-"), k = g(
879
+ () => Object.fromEntries(Object.entries(i).filter(([y]) => c(y)))
880
+ ), f = g(
881
+ () => Object.fromEntries(Object.entries(i).filter(([y]) => !c(y)))
882
+ );
883
+ return (y, r) => (a(), l("div", he({
884
+ class: ["ds-textarea", [`ds-textarea--resize-${e.resize}`, { "is-error": e.error, "is-disabled": e.disabled }]]
885
+ }, k.value), [
886
+ Be(s("textarea", he(f.value, {
455
887
  id: e.id || void 0,
456
- "onUpdate:modelValue": d[0] || (d[0] = (c) => o.value = c),
888
+ "onUpdate:modelValue": r[0] || (r[0] = (d) => t.value = d),
457
889
  class: "ds-textarea__control",
458
890
  placeholder: e.placeholder,
459
891
  rows: e.rows,
@@ -461,339 +893,459 @@ const Y = {
461
893
  name: e.name || void 0,
462
894
  "aria-invalid": e.error || void 0,
463
895
  "aria-describedby": e.error && e.errorMessage && e.id ? `${e.id}-error` : void 0,
464
- onFocus: d[1] || (d[1] = (c) => l(g(V), c)),
465
- onBlur: d[2] || (d[2] = (c) => l(g(U), c))
466
- }, null, 40, je), [
467
- [ue, o.value]
896
+ onFocus: r[1] || (r[1] = (d) => o(_(Se), d)),
897
+ onBlur: r[2] || (r[2] = (d) => o(_(ke), d))
898
+ }), null, 16, da), [
899
+ [rt, t.value]
468
900
  ]),
469
- e.error && e.errorMessage ? (t(), a("p", {
901
+ e.error && e.errorMessage ? (a(), l("p", {
470
902
  key: 0,
471
903
  id: e.id ? `${e.id}-error` : void 0,
472
904
  class: "ds-textarea__error"
473
- }, y(e.errorMessage), 9, Qe)) : r("", !0)
474
- ], 2));
475
- }
476
- }), na = /* @__PURE__ */ $(Je, [["__scopeId", "data-v-cfa74e3d"]]), et = ["disabled", "name"], tt = {
477
- key: 0,
478
- class: "ds-checkbox__mark",
479
- viewBox: "0 0 16 16",
480
- fill: "none",
481
- stroke: "currentColor",
482
- "stroke-width": "2.5"
483
- }, at = {
484
- key: 1,
485
- class: "ds-checkbox__mark",
486
- viewBox: "0 0 16 16",
487
- fill: "none",
488
- stroke: "currentColor",
489
- "stroke-width": "2.5"
490
- }, lt = {
491
- key: 0,
492
- class: "ds-checkbox__label"
493
- }, it = /* @__PURE__ */ k({
494
- __name: "DsCheckbox",
495
- props: /* @__PURE__ */ O({
496
- indeterminate: Boolean,
497
- disabled: Boolean,
498
- name: { type: String, default: "" },
499
- // Label text (DS `label` prop); a default slot overrides it.
500
- label: { type: String, default: "" }
501
- }, {
502
- modelValue: { type: Boolean, default: !1 },
503
- modelModifiers: {}
504
- }),
505
- emits: ["update:modelValue"],
506
- setup(e) {
507
- const n = W(e, "modelValue"), o = e, l = N(null);
508
- function i() {
509
- l.value && (l.value.indeterminate = o.indeterminate);
510
- }
511
- return fe(i), ie(() => o.indeterminate, i), (d, c) => (t(), a("label", {
512
- class: v(["ds-checkbox", { "is-disabled": e.disabled }])
513
- }, [
514
- q(s("input", {
515
- ref_key: "inputRef",
516
- ref: l,
517
- "onUpdate:modelValue": c[0] || (c[0] = (u) => n.value = u),
518
- type: "checkbox",
519
- class: "ds-checkbox__native",
520
- disabled: e.disabled,
521
- name: e.name || void 0
522
- }, null, 8, et), [
523
- [ye, n.value]
524
- ]),
525
- s("span", {
526
- class: v(["ds-checkbox__box", { "is-active": n.value || e.indeterminate }]),
527
- "aria-hidden": "true"
528
- }, [
529
- e.indeterminate ? (t(), a("svg", tt, [...c[1] || (c[1] = [
530
- s("line", {
531
- x1: "4",
532
- y1: "8",
533
- x2: "12",
534
- y2: "8"
535
- }, null, -1)
536
- ])])) : n.value ? (t(), a("svg", at, [...c[2] || (c[2] = [
537
- s("path", { d: "M3.5 8.5l3 3 6-6" }, null, -1)
538
- ])])) : r("", !0)
539
- ], 2),
540
- d.$slots.default || e.label ? (t(), a("span", lt, [
541
- I(d.$slots, "default", {}, () => [
542
- A(y(e.label), 1)
543
- ], !0)
544
- ])) : r("", !0)
545
- ], 2));
905
+ }, S(e.errorMessage), 9, ra)) : m("", !0)
906
+ ], 16));
546
907
  }
547
- }), oa = /* @__PURE__ */ $(it, [["__scopeId", "data-v-0c1a3c0a"]]), nt = {
908
+ }), Fi = /* @__PURE__ */ M(ca, [["__scopeId", "data-v-745c01de"]]), ua = {
548
909
  SUCCESS: "success",
549
910
  INFO: "info",
550
911
  WARNING: "warning",
551
912
  ERROR: "error"
552
- }, ot = {
913
+ }, fa = {
553
914
  LIGHT: "light",
554
915
  // tinted: family tint bg + mid border + shadow text
555
916
  DARK: "dark"
556
917
  // solid: family shadow bg + white text
557
- }, st = {
918
+ }, ba = {
558
919
  success: "check_circle",
559
920
  info: "info",
560
921
  warning: "warning",
561
922
  error: "error"
562
- }, dt = {
923
+ }, va = {
563
924
  key: 0,
564
925
  class: "material-icons ds-alert__icon",
565
926
  "aria-hidden": "true"
566
- }, rt = { class: "ds-alert__content" }, ct = {
927
+ }, ya = { class: "ds-alert__content" }, ma = {
567
928
  key: 1,
568
929
  class: "ds-alert__body"
569
- }, ut = ["aria-label"], ft = /* @__PURE__ */ k({
930
+ }, ha = ["aria-label"], ga = /* @__PURE__ */ x({
570
931
  __name: "DsAlert",
571
- props: {
572
- type: { type: String, default: nt.INFO },
573
- effect: { type: String, default: ot.LIGHT },
932
+ props: /* @__PURE__ */ Q({
933
+ type: { type: String, default: ua.INFO },
934
+ effect: { type: String, default: fa.LIGHT },
574
935
  title: { type: String, default: "" },
575
936
  description: { type: String, default: "" },
576
937
  showIcon: Boolean,
577
938
  closable: Boolean,
578
939
  center: Boolean,
940
+ // Bold the title even without a body (DS: fontWeight = body || boldTitle ? 700 : 400).
941
+ boldTitle: Boolean,
579
942
  closeLabel: { type: String, default: "" }
580
- },
581
- emits: [C],
943
+ }, {
944
+ visible: { type: Boolean, default: !0 },
945
+ visibleModifiers: {}
946
+ }),
947
+ emits: /* @__PURE__ */ Q([X], ["update:visible"]),
582
948
  setup(e, { emit: n }) {
583
- const o = e, l = n, i = le(), d = N(!0), c = S(() => st[o.type]), u = S(() => !!i.default || o.description.length > 0);
584
- function b() {
585
- d.value = !1, l(C);
949
+ const t = e, o = n, i = de(e, "visible"), c = Ee(), k = g(() => ba[t.type]), f = g(() => !!c.default || t.description.length > 0), y = g(() => !!c.title || t.title.length > 0);
950
+ function r() {
951
+ i.value = !1, o(X);
586
952
  }
587
- return (m, f) => d.value ? (t(), a("div", {
588
- key: 0,
589
- class: v(["ds-alert", [`ds-alert--${e.type}`, `ds-alert--${e.effect}`, { "is-center": e.center }]]),
590
- role: "alert"
591
- }, [
592
- e.showIcon ? (t(), a("i", dt, y(c.value), 1)) : r("", !0),
593
- s("div", rt, [
594
- e.title ? (t(), a("div", {
953
+ return (d, b) => (a(), G(Le, { name: "ds-alert-fade" }, {
954
+ default: ie(() => [
955
+ i.value ? (a(), l("div", {
595
956
  key: 0,
596
- class: v(["ds-alert__title", { "has-body": u.value }])
597
- }, y(e.title), 3)) : r("", !0),
598
- u.value ? (t(), a("div", ct, [
599
- I(m.$slots, "default", {}, () => [
600
- A(y(e.description), 1)
601
- ], !0)
602
- ])) : r("", !0)
957
+ class: $(["ds-alert", [`ds-alert--${e.type}`, `ds-alert--${e.effect}`, { "is-center": e.center }]]),
958
+ role: "alert"
959
+ }, [
960
+ e.showIcon ? (a(), l("i", va, S(k.value), 1)) : m("", !0),
961
+ s("div", ya, [
962
+ y.value ? (a(), l("div", {
963
+ key: 0,
964
+ class: $(["ds-alert__title", { "has-body": f.value, "is-bold": f.value || e.boldTitle }])
965
+ }, [
966
+ A(d.$slots, "title", {}, () => [
967
+ H(S(e.title), 1)
968
+ ], !0)
969
+ ], 2)) : m("", !0),
970
+ f.value ? (a(), l("div", ma, [
971
+ A(d.$slots, "default", {}, () => [
972
+ H(S(e.description), 1)
973
+ ], !0)
974
+ ])) : m("", !0)
975
+ ]),
976
+ e.closable ? (a(), l("button", {
977
+ key: 1,
978
+ type: "button",
979
+ class: "ds-alert__close",
980
+ "aria-label": e.closeLabel || void 0,
981
+ onClick: r
982
+ }, [...b[0] || (b[0] = [
983
+ s("i", {
984
+ class: "material-icons",
985
+ "aria-hidden": "true"
986
+ }, "close", -1)
987
+ ])], 8, ha)) : m("", !0)
988
+ ], 2)) : m("", !0)
603
989
  ]),
604
- e.closable ? (t(), a("button", {
605
- key: 1,
606
- type: "button",
607
- class: "ds-alert__close",
608
- "aria-label": e.closeLabel || void 0,
609
- onClick: b
610
- }, [...f[0] || (f[0] = [
611
- s("i", {
612
- class: "material-icons",
613
- "aria-hidden": "true"
614
- }, "close", -1)
615
- ])], 8, ut)) : r("", !0)
616
- ], 2)) : r("", !0);
990
+ _: 3
991
+ }));
617
992
  }
618
- }), sa = /* @__PURE__ */ $(ft, [["__scopeId", "data-v-58ce7b87"]]), yt = {
993
+ }), zi = /* @__PURE__ */ M(ga, [["__scopeId", "data-v-9ced26d6"]]), Sa = {
994
+ SUCCESS: "success",
619
995
  INFO: "info",
620
996
  WARNING: "warning",
621
997
  ERROR: "error"
622
- }, vt = {
998
+ }, ka = {
623
999
  TOP_LEFT: "top-left",
624
1000
  TOP_RIGHT: "top-right",
625
1001
  BOTTOM_LEFT: "bottom-left",
626
1002
  BOTTOM_RIGHT: "bottom-right"
627
- }, bt = {
1003
+ }, pa = {
1004
+ success: "check_circle",
628
1005
  info: "mode_edit",
629
1006
  warning: "warning",
630
- error: "warning"
631
- }, mt = {
1007
+ error: "error"
1008
+ }, qe = {
1009
+ BLANK: "_blank",
1010
+ SELF: "_self",
1011
+ PARENT: "_parent",
1012
+ TOP: "_top"
1013
+ }, $a = {
632
1014
  class: "material-icons ds-notification__icon",
633
1015
  "aria-hidden": "true"
634
- }, gt = { class: "ds-notification__content" }, ht = {
1016
+ }, Ta = { class: "ds-notification__content" }, Ea = {
635
1017
  key: 0,
636
1018
  class: "ds-notification__title"
637
- }, St = {
1019
+ }, La = {
638
1020
  key: 1,
639
1021
  class: "ds-notification__desc"
640
- }, kt = ["href"], $t = ["aria-label"], Tt = /* @__PURE__ */ k({
1022
+ }, wa = ["href", "target", "rel"], Ia = ["aria-label"], Ca = /* @__PURE__ */ x({
641
1023
  __name: "DsNotification",
642
1024
  props: {
643
- type: { type: String, default: yt.INFO },
1025
+ type: { type: String, default: Sa.INFO },
644
1026
  position: {
645
1027
  type: String,
646
- default: vt.BOTTOM_LEFT
1028
+ default: ka.BOTTOM_LEFT
647
1029
  },
648
1030
  title: { type: String, default: "" },
649
1031
  description: { type: String, default: "" },
650
1032
  linkTitle: { type: String, default: "" },
651
1033
  link: { type: String, default: "" },
1034
+ // `target` del <a> del link. Default `_blank` para no romper el comportamiento
1035
+ // histórico. Con `_blank` se emite `rel="noopener noreferrer"` (seguridad). Para
1036
+ // navegación in-app (SPA) escuchá `navigate` y enrutá con el router de la app.
1037
+ linkTarget: {
1038
+ type: String,
1039
+ default: qe.BLANK
1040
+ },
652
1041
  showClose: { type: Boolean, default: !0 },
653
- closeLabel: { type: String, default: "" }
1042
+ // Accessible name for the icon-only close button — provide it whenever
1043
+ // `showClose` is on, or the button has no name for screen readers (as with any
1044
+ // icon-only control, cf. DsButton circle/square requiring `ariaLabel`). The
1045
+ // library never hardcodes copy; the consuming app owns i18n.
1046
+ closeLabel: { type: String, default: "" },
1047
+ // Auto-dismiss delay in ms (DS default 3500). 0 disables it. The timer pauses
1048
+ // while the pointer is over the card and resumes with the remaining time.
1049
+ duration: { type: Number, default: 3500 }
654
1050
  },
655
- emits: [C],
1051
+ emits: [X, We],
656
1052
  setup(e, { emit: n }) {
657
- const o = e, l = n, i = N(!0), d = S(() => bt[o.type]);
658
- function c() {
659
- i.value = !1, l(C);
1053
+ const t = e, o = n, i = U(!0), c = g(() => pa[t.type]), k = g(
1054
+ () => t.linkTarget === qe.BLANK ? "noopener noreferrer" : void 0
1055
+ );
1056
+ let f, y = 0, r = t.duration;
1057
+ function d() {
1058
+ f && (clearTimeout(f), f = void 0);
660
1059
  }
661
- return (u, b) => (t(), D(ne, { to: "body" }, [
662
- i.value ? (t(), a("div", {
663
- key: 0,
664
- class: v(["ds-notification", `ds-notification--${e.position}`])
665
- }, [
666
- s("div", {
667
- class: v(["ds-notification__card", `ds-notification__card--${e.type}`]),
668
- role: "alert"
669
- }, [
670
- s("i", mt, y(d.value), 1),
671
- s("div", gt, [
672
- e.title ? (t(), a("span", ht, y(e.title), 1)) : r("", !0),
673
- e.description ? (t(), a("p", St, y(e.description), 1)) : r("", !0),
674
- e.linkTitle ? (t(), a("a", {
675
- key: 2,
676
- class: "ds-notification__link",
677
- href: e.link || void 0,
678
- target: "_blank",
679
- rel: "noreferrer"
680
- }, y(e.linkTitle), 9, kt)) : r("", !0)
681
- ]),
682
- e.showClose ? (t(), a("button", {
1060
+ function b(C) {
1061
+ d(), !(t.duration <= 0 || !i.value) && (y = Date.now(), f = setTimeout(p, C));
1062
+ }
1063
+ function h() {
1064
+ f && (r -= Date.now() - y, d());
1065
+ }
1066
+ function T() {
1067
+ b(r > 0 ? r : t.duration);
1068
+ }
1069
+ function p() {
1070
+ d(), i.value = !1, o(X);
1071
+ }
1072
+ function V(C) {
1073
+ o(We, C);
1074
+ }
1075
+ return Qe(() => b(t.duration)), be(d), (C, E) => (a(), G(Je, { to: "body" }, [
1076
+ j(Le, {
1077
+ name: "ds-notification",
1078
+ appear: ""
1079
+ }, {
1080
+ default: ie(() => [
1081
+ i.value ? (a(), l("div", {
683
1082
  key: 0,
684
- type: "button",
685
- class: "ds-notification__close",
686
- "aria-label": e.closeLabel || void 0,
687
- onClick: c
688
- }, [...b[0] || (b[0] = [
689
- s("i", {
690
- class: "material-icons",
691
- "aria-hidden": "true"
692
- }, "close", -1)
693
- ])], 8, $t)) : r("", !0)
694
- ], 2)
695
- ], 2)) : r("", !0)
1083
+ class: $(["ds-notification", `ds-notification--${e.position}`])
1084
+ }, [
1085
+ s("div", {
1086
+ class: $(["ds-notification__card", `ds-notification__card--${e.type}`]),
1087
+ role: "alert",
1088
+ onMouseenter: h,
1089
+ onMouseleave: T
1090
+ }, [
1091
+ s("i", $a, S(c.value), 1),
1092
+ s("div", Ta, [
1093
+ e.title ? (a(), l("span", Ea, S(e.title), 1)) : m("", !0),
1094
+ e.description ? (a(), l("p", La, S(e.description), 1)) : m("", !0),
1095
+ e.linkTitle ? (a(), l("a", {
1096
+ key: 2,
1097
+ class: "ds-notification__link",
1098
+ href: e.link || void 0,
1099
+ target: e.linkTarget,
1100
+ rel: k.value,
1101
+ onClick: V
1102
+ }, S(e.linkTitle), 9, wa)) : m("", !0)
1103
+ ]),
1104
+ e.showClose ? (a(), l("button", {
1105
+ key: 0,
1106
+ type: "button",
1107
+ class: "ds-notification__close",
1108
+ "aria-label": e.closeLabel || void 0,
1109
+ onClick: p
1110
+ }, [...E[0] || (E[0] = [
1111
+ s("i", {
1112
+ class: "material-icons",
1113
+ "aria-hidden": "true"
1114
+ }, "close", -1)
1115
+ ])], 8, Ia)) : m("", !0)
1116
+ ], 34)
1117
+ ], 2)) : m("", !0)
1118
+ ]),
1119
+ _: 1
1120
+ })
696
1121
  ]));
697
1122
  }
698
- }), da = /* @__PURE__ */ $(Tt, [["__scopeId", "data-v-287d5c06"]]), It = ["aria-label"], Ct = {
1123
+ }), Vi = /* @__PURE__ */ M(Ca, [["__scopeId", "data-v-f1d76da5"]]), _a = ["aria-modal", "aria-labelledby", "aria-label"], Da = {
699
1124
  key: 0,
700
1125
  class: "ds-modal__header"
701
- }, Et = { class: "ds-modal__title" }, Lt = { class: "ds-modal__body" }, Dt = {
1126
+ }, Aa = ["id"], Na = { class: "ds-modal__body" }, Ra = {
702
1127
  key: 1,
703
1128
  class: "ds-modal__footer"
704
- }, wt = /* @__PURE__ */ k({
1129
+ }, Ba = /* @__PURE__ */ x({
705
1130
  __name: "DsModal",
706
1131
  props: {
707
1132
  open: Boolean,
708
1133
  title: { type: String, default: "" },
709
1134
  showClose: { type: Boolean, default: !0 },
710
1135
  width: { type: String, default: "440px" },
1136
+ // Explicit dialog height (any CSS length). Unset = content height.
1137
+ height: { type: String, default: "" },
1138
+ // Top offset of the dialog inside the fixed backdrop.
1139
+ top: { type: String, default: "15vh" },
1140
+ // Center the body text.
1141
+ center: Boolean,
1142
+ // false = render in-flow (no backdrop / portal / scroll-lock) for specimen cards.
1143
+ fixed: { type: Boolean, default: !0 },
711
1144
  closeOnBackdrop: { type: Boolean, default: !0 },
712
- closeLabel: { type: String, default: "" }
1145
+ // Symmetric with closeOnBackdrop: a non-dismissable flow (closeOnBackdrop=false)
1146
+ // can also opt out of Escape-to-close. Default true (Escape closes).
1147
+ closeOnEscape: { type: Boolean, default: !0 },
1148
+ // Accessible name for the icon-only close button; English default (app owns i18n),
1149
+ // matching DsDataCard so the control is never unnamed.
1150
+ closeLabel: { type: String, default: "Close" }
713
1151
  },
714
- emits: [C],
1152
+ emits: [X],
715
1153
  setup(e, { emit: n }) {
716
- const o = e, l = n, i = N(null);
717
- let d = null;
718
- function c() {
719
- o.closeOnBackdrop && l(C);
1154
+ const t = e, o = n, i = U(null);
1155
+ let c = null;
1156
+ const k = xe(), f = g(() => ({
1157
+ width: t.width,
1158
+ ...t.height ? { height: t.height } : {}
1159
+ }));
1160
+ function y() {
1161
+ t.fixed && t.closeOnBackdrop && o(X);
720
1162
  }
721
- function u() {
1163
+ function r() {
722
1164
  return i.value ? Array.from(i.value.querySelectorAll('a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(
723
- (f) => f.offsetParent !== null
1165
+ (p) => p.offsetParent !== null
724
1166
  ) : [];
725
1167
  }
726
- function b(m) {
727
- var x;
728
- if (m.key === "Escape") {
729
- l(C);
1168
+ function d(T) {
1169
+ var E;
1170
+ if (T.key === "Escape") {
1171
+ t.closeOnEscape && o(X);
730
1172
  return;
731
1173
  }
732
- if (m.key !== "Tab") return;
733
- const f = u();
734
- if (f.length === 0) {
735
- m.preventDefault(), (x = i.value) == null || x.focus();
1174
+ if (T.key !== "Tab") return;
1175
+ const p = r();
1176
+ if (p.length === 0) {
1177
+ T.preventDefault(), (E = i.value) == null || E.focus();
736
1178
  return;
737
1179
  }
738
- const h = f[0], T = f[f.length - 1];
739
- m.shiftKey && document.activeElement === h ? (m.preventDefault(), T.focus()) : !m.shiftKey && document.activeElement === T && (m.preventDefault(), h.focus());
740
- }
741
- return ie(
742
- () => o.open,
743
- (m) => {
744
- var f;
745
- typeof document != "undefined" && (m ? (d = document.activeElement, document.addEventListener("keydown", b), document.body.style.overflow = "hidden", ve(() => {
746
- var h, T;
747
- return (T = (h = u()[0]) != null ? h : i.value) == null ? void 0 : T.focus();
748
- })) : (document.removeEventListener("keydown", b), document.body.style.overflow = "", (f = d == null ? void 0 : d.focus) == null || f.call(d)));
1180
+ const V = p[0], C = p[p.length - 1];
1181
+ T.shiftKey && document.activeElement === V ? (T.preventDefault(), C.focus()) : !T.shiftKey && document.activeElement === C && (T.preventDefault(), V.focus());
1182
+ }
1183
+ function b() {
1184
+ c = document.activeElement, document.addEventListener("keydown", d), document.body.style.overflow = "hidden", ue(() => {
1185
+ var T, p;
1186
+ return (p = (T = r()[0]) != null ? T : i.value) == null ? void 0 : p.focus();
1187
+ });
1188
+ }
1189
+ function h(T = !0) {
1190
+ var p;
1191
+ document.removeEventListener("keydown", d), document.body.style.overflow = "", T && ((p = c == null ? void 0 : c.focus) == null || p.call(c));
1192
+ }
1193
+ return te(
1194
+ () => t.open && t.fixed,
1195
+ (T, p) => {
1196
+ typeof document != "undefined" && (T ? b() : p && h());
749
1197
  },
750
1198
  { immediate: !0 }
751
- ), oe(() => {
752
- typeof document != "undefined" && (document.removeEventListener("keydown", b), document.body.style.overflow = "");
753
- }), (m, f) => (t(), D(ne, { to: "body" }, [
754
- e.open ? (t(), a("div", {
755
- key: 0,
756
- class: "ds-modal",
757
- onClick: c
758
- }, [
759
- s("div", {
760
- ref_key: "dialogRef",
761
- ref: i,
762
- class: "ds-modal__dialog",
763
- role: "dialog",
764
- "aria-modal": "true",
765
- "aria-label": e.title || "dialog",
766
- tabindex: "-1",
767
- style: w({ width: e.width }),
768
- onClick: f[1] || (f[1] = se(() => {
769
- }, ["stop"]))
770
- }, [
771
- e.title || e.showClose ? (t(), a("div", Ct, [
772
- s("span", Et, y(e.title), 1),
773
- e.showClose ? (t(), D(g(K), {
774
- key: 0,
775
- variant: "tertiary",
776
- circle: "",
777
- "left-icon": "close",
778
- "aria-label": e.closeLabel || void 0,
779
- onClick: f[0] || (f[0] = (h) => l(g(C)))
780
- }, null, 8, ["aria-label"])) : r("", !0)
781
- ])) : r("", !0),
782
- s("div", Lt, [
783
- I(m.$slots, "default", {}, void 0, !0)
784
- ]),
785
- m.$slots.footer ? (t(), a("div", Dt, [
786
- I(m.$slots, "footer", {}, void 0, !0)
787
- ])) : r("", !0)
788
- ], 12, It)
789
- ])) : r("", !0)
790
- ]));
1199
+ ), be(() => {
1200
+ typeof document != "undefined" && h(!1);
1201
+ }), (T, p) => (a(), G(Je, {
1202
+ to: "body",
1203
+ disabled: !e.fixed
1204
+ }, [
1205
+ j(Le, { name: "ds-modal" }, {
1206
+ default: ie(() => [
1207
+ e.open ? (a(), l("div", {
1208
+ key: 0,
1209
+ class: $(["ds-modal", { "is-fixed": e.fixed }]),
1210
+ style: F(e.fixed ? { paddingTop: e.top } : void 0),
1211
+ onClick: y
1212
+ }, [
1213
+ s("div", {
1214
+ ref_key: "dialogRef",
1215
+ ref: i,
1216
+ class: $(["ds-modal__dialog", { "is-center": e.center }]),
1217
+ role: "dialog",
1218
+ "aria-modal": e.fixed ? "true" : "false",
1219
+ "aria-labelledby": e.title ? _(k) : void 0,
1220
+ "aria-label": e.title ? void 0 : "dialog",
1221
+ tabindex: "-1",
1222
+ style: F(f.value),
1223
+ onClick: p[1] || (p[1] = ve(() => {
1224
+ }, ["stop"]))
1225
+ }, [
1226
+ e.title || e.showClose ? (a(), l("div", Da, [
1227
+ s("span", {
1228
+ id: _(k),
1229
+ class: "ds-modal__title"
1230
+ }, S(e.title), 9, Aa),
1231
+ e.showClose ? (a(), G(_(oe), {
1232
+ key: 0,
1233
+ variant: "tertiary",
1234
+ circle: "",
1235
+ "left-icon": "close",
1236
+ "aria-label": e.closeLabel || void 0,
1237
+ onClick: p[0] || (p[0] = (V) => o(_(X)))
1238
+ }, null, 8, ["aria-label"])) : m("", !0)
1239
+ ])) : m("", !0),
1240
+ s("div", Na, [
1241
+ A(T.$slots, "default", {}, void 0, !0)
1242
+ ]),
1243
+ T.$slots.footer ? (a(), l("div", Ra, [
1244
+ A(T.$slots, "footer", {}, void 0, !0)
1245
+ ])) : m("", !0)
1246
+ ], 14, _a)
1247
+ ], 6)) : m("", !0)
1248
+ ]),
1249
+ _: 3
1250
+ })
1251
+ ], 8, ["disabled"]));
791
1252
  }
792
- }), ra = /* @__PURE__ */ $(wt, [["__scopeId", "data-v-6eecaabb"]]), G = {
1253
+ }), Ui = /* @__PURE__ */ M(Ba, [["__scopeId", "data-v-a759ae72"]]), xa = {
1254
+ TOP: "top",
1255
+ BOTTOM: "bottom",
1256
+ LEFT: "left",
1257
+ RIGHT: "right"
1258
+ }, Ma = ["id"], Oa = /* @__PURE__ */ x({
1259
+ __name: "DsTooltip",
1260
+ props: {
1261
+ // Bubble text. Rich content can be provided via the #content slot instead.
1262
+ content: { type: String, default: "" },
1263
+ placement: {
1264
+ type: String,
1265
+ default: xa.TOP
1266
+ },
1267
+ // Hover delay before showing, ms. Focus always shows immediately (no delay).
1268
+ delay: { type: Number, default: 300 },
1269
+ // Wrap a full-width/block trigger (DsInput/DsTextarea) — the wrapper becomes
1270
+ // `display: block` instead of the default inline-flex, so it doesn't squash the control.
1271
+ block: { type: Boolean, default: !1 },
1272
+ // Force the tooltip off regardless of content/slot. Lets a consumer show it only
1273
+ // under a condition (e.g. only-if-truncated) without emptying the content prop —
1274
+ // the #content slot is always truthy, so it's the only way to suppress that path.
1275
+ disabled: { type: Boolean, default: !1 }
1276
+ },
1277
+ setup(e) {
1278
+ const n = e, t = Ee(), o = xe(), i = U(!1), c = g(() => !n.disabled && (n.content.length > 0 || !!t.content));
1279
+ te(
1280
+ () => n.disabled,
1281
+ (R) => {
1282
+ R && N();
1283
+ }
1284
+ );
1285
+ let k = !1, f = !1, y = null, r = null, d = null;
1286
+ function b() {
1287
+ y !== null && (clearTimeout(y), y = null);
1288
+ }
1289
+ function h(R) {
1290
+ R && (r && r !== R && T(), r !== R && (r = R, d = R.getAttribute("aria-describedby"), R.setAttribute(
1291
+ "aria-describedby",
1292
+ d ? `${d} ${o}` : o
1293
+ )));
1294
+ }
1295
+ function T() {
1296
+ r && (d !== null ? r.setAttribute("aria-describedby", d) : r.removeAttribute("aria-describedby"), r = null, d = null);
1297
+ }
1298
+ function p() {
1299
+ c.value && (k = !0, b(), y = setTimeout(() => {
1300
+ i.value = !0;
1301
+ }, n.delay));
1302
+ }
1303
+ function V() {
1304
+ k = !1, b(), f || N();
1305
+ }
1306
+ function C(R) {
1307
+ c.value && (f = !0, b(), i.value = !0, h(R.target));
1308
+ }
1309
+ function E(R) {
1310
+ const q = R.relatedTarget, J = R.currentTarget;
1311
+ q && (J != null && J.contains(q)) || (f = !1, k || N());
1312
+ }
1313
+ function N() {
1314
+ b(), i.value = !1, T();
1315
+ }
1316
+ return be(() => {
1317
+ b(), T();
1318
+ }), (R, q) => (a(), l("div", {
1319
+ class: $(["ds-tooltip", { "ds-tooltip--block": e.block }]),
1320
+ onMouseenter: p,
1321
+ onMouseleave: V,
1322
+ onFocusin: C,
1323
+ onFocusout: E,
1324
+ onKeydown: ct(N, ["esc"])
1325
+ }, [
1326
+ A(R.$slots, "default", {}, void 0, !0),
1327
+ j(Le, { name: "ds-tooltip-fade" }, {
1328
+ default: ie(() => [
1329
+ i.value ? (a(), l("div", {
1330
+ key: 0,
1331
+ id: _(o),
1332
+ class: $(["ds-tooltip__bubble", `ds-tooltip__bubble--${e.placement}`]),
1333
+ role: "tooltip"
1334
+ }, [
1335
+ A(R.$slots, "content", {}, () => [
1336
+ H(S(e.content), 1)
1337
+ ], !0)
1338
+ ], 10, Ma)) : m("", !0)
1339
+ ]),
1340
+ _: 3
1341
+ })
1342
+ ], 34));
1343
+ }
1344
+ }), Gi = /* @__PURE__ */ M(Oa, [["__scopeId", "data-v-26c35ba5"]]), Ne = {
793
1345
  VERIFIED: "verified",
794
1346
  UNVERIFIED: "unverified",
795
1347
  NEW: "new"
796
- }, Nt = ["aria-label", "title"], Rt = /* @__PURE__ */ k({
1348
+ }, Pa = ["aria-label", "title"], Fa = /* @__PURE__ */ x({
797
1349
  __name: "DsVerificationIcon",
798
1350
  props: {
799
1351
  // true = verified · false = not verified · null/undefined = newly found.
@@ -818,38 +1370,38 @@ const Y = {
818
1370
  }
819
1371
  },
820
1372
  setup(e) {
821
- const n = e, o = S(() => n.verified === null || n.verified === void 0 ? {
822
- state: G.NEW,
1373
+ const n = e, t = g(() => n.verified === null || n.verified === void 0 ? {
1374
+ state: Ne.NEW,
823
1375
  icon: "new_releases",
824
1376
  label: "Newly found"
825
1377
  } : n.verified ? {
826
- state: G.VERIFIED,
1378
+ state: Ne.VERIFIED,
827
1379
  icon: "verified",
828
1380
  label: "Verified"
829
1381
  } : {
830
- state: G.UNVERIFIED,
1382
+ state: Ne.UNVERIFIED,
831
1383
  icon: n.isContactData ? "dangerous" : "error",
832
1384
  label: "Not verified"
833
1385
  });
834
- return (l, i) => (t(), a("i", {
835
- class: v(["material-icons ds-verification-icon", [
836
- `ds-verification-icon--${o.value.state}`,
1386
+ return (o, i) => (a(), l("i", {
1387
+ class: $(["material-icons ds-verification-icon", [
1388
+ `ds-verification-icon--${t.value.state}`,
837
1389
  { "ds-verification-icon--email": e.isContactData }
838
1390
  ]]),
839
- style: w({ fontSize: `${e.size}px` }),
1391
+ style: F({ fontSize: `${e.size}px` }),
840
1392
  role: "img",
841
- "aria-label": e.label || o.value.label,
842
- title: e.label || o.value.label
1393
+ "aria-label": e.label || t.value.label,
1394
+ title: e.label || t.value.label
843
1395
  }, [
844
- I(l.$slots, "default", {}, () => [
845
- A(y(o.value.icon), 1)
1396
+ A(o.$slots, "default", {}, () => [
1397
+ H(S(t.value.icon), 1)
846
1398
  ], !0)
847
- ], 14, Nt));
1399
+ ], 14, Pa));
848
1400
  }
849
- }), Bt = /* @__PURE__ */ $(Rt, [["__scopeId", "data-v-0fd84040"]]), At = ["title"], Ot = { class: "ds-contact-value__marquee" }, xt = { class: "ds-contact-value__actions" }, Mt = ["aria-label", "title"], Vt = {
1401
+ }), za = /* @__PURE__ */ M(Fa, [["__scopeId", "data-v-0fd84040"]]), Va = ["title"], Ua = { class: "ds-contact-value__marquee" }, Ga = { class: "ds-contact-value__actions" }, Ha = ["role", "aria-label", "aria-hidden"], Wa = ["aria-label", "title"], Ka = {
850
1402
  class: "material-icons",
851
1403
  "aria-hidden": "true"
852
- }, Ut = ["aria-label", "aria-pressed", "title"], Ft = ["aria-label", "aria-pressed", "title"], zt = /* @__PURE__ */ k({
1404
+ }, Ya = ["aria-label", "aria-pressed", "title"], qa = ["aria-label", "aria-pressed", "title"], ja = /* @__PURE__ */ x({
853
1405
  __name: "DsContactValue",
854
1406
  props: {
855
1407
  value: { type: String, required: !0 },
@@ -859,117 +1411,150 @@ const Y = {
859
1411
  isContactData: { type: Boolean, default: !1 },
860
1412
  showRate: { type: Boolean, default: !1 },
861
1413
  correct: { type: Boolean, default: null },
1414
+ // Locks the value: on hover a static lock glyph shows instead of copy/rate.
1415
+ hideValue: { type: Boolean, default: !1 },
862
1416
  // User-facing labels (the app owns i18n); English DS defaults.
863
1417
  copyLabel: { type: String, default: "Copy" },
864
1418
  copiedLabel: { type: String, default: "Copied!" },
865
1419
  correctLabel: { type: String, default: "Correct" },
866
- incorrectLabel: { type: String, default: "Incorrect" }
1420
+ incorrectLabel: { type: String, default: "Incorrect" },
1421
+ // Accessible name for the lock glyph (empty → decorative/aria-hidden).
1422
+ hideValueLabel: { type: String, default: "" }
867
1423
  },
868
- emits: [F, z, _],
1424
+ emits: [pe, $e, Te],
869
1425
  setup(e, { emit: n }) {
870
- const o = e, l = n, i = N(!1);
871
- let d;
872
- function c() {
873
- typeof navigator != "undefined" && navigator.clipboard && navigator.clipboard.writeText(o.value).catch(() => {
874
- }), i.value = !0, clearTimeout(d), d = setTimeout(() => {
1426
+ const t = e, o = n, i = U(!1);
1427
+ let c;
1428
+ function k() {
1429
+ typeof navigator != "undefined" && navigator.clipboard && navigator.clipboard.writeText(t.value).catch(() => {
1430
+ }), i.value = !0, clearTimeout(c), c = setTimeout(() => {
875
1431
  i.value = !1;
876
- }, 1200), l(F, o.value);
1432
+ }, 1200), o(pe, t.value);
877
1433
  }
878
- function u() {
879
- l(z);
1434
+ function f() {
1435
+ o($e);
880
1436
  }
881
- function b() {
882
- l(_);
1437
+ function y() {
1438
+ o(Te);
883
1439
  }
884
- return oe(() => clearTimeout(d)), (m, f) => (t(), a("div", {
885
- class: v(["ds-contact-value", { "ds-contact-value--main": e.main }])
1440
+ return be(() => clearTimeout(c)), (r, d) => (a(), l("div", {
1441
+ class: $(["ds-contact-value", { "ds-contact-value--main": e.main }])
886
1442
  }, [
887
- de(g(Bt), {
1443
+ j(_(za), {
888
1444
  verified: e.verified,
889
1445
  "is-contact-data": e.isContactData
890
1446
  }, null, 8, ["verified", "is-contact-data"]),
891
1447
  s("span", {
892
1448
  class: "ds-contact-value__value",
893
1449
  title: e.value
894
- }, y(e.value), 9, At),
895
- s("span", Ot, [
896
- e.valueType ? (t(), D(g(Ae), {
1450
+ }, S(e.value), 9, Va),
1451
+ s("span", Ua, [
1452
+ e.valueType ? (a(), G(_(_t), {
897
1453
  key: 0,
898
1454
  class: "ds-contact-value__badge",
899
- tone: e.main ? g(H).ACCENT : g(H).GREY,
900
- "aria-hidden": "true"
1455
+ tone: e.main ? _(Re).ACCENT : _(Re).GREY,
1456
+ title: e.valueType
901
1457
  }, {
902
- default: be(() => [
903
- A(y(e.valueType), 1)
1458
+ default: ie(() => [
1459
+ H(S(e.valueType), 1)
904
1460
  ]),
905
1461
  _: 1
906
- }, 8, ["tone"])) : r("", !0),
907
- s("span", xt, [
908
- s("button", {
909
- type: "button",
910
- class: v(["ds-contact-value__action", { "is-copied": i.value }]),
911
- "aria-label": i.value ? e.copiedLabel : e.copyLabel,
912
- title: i.value ? e.copiedLabel : e.copyLabel,
913
- onClick: c
914
- }, [
915
- s("i", Vt, y(i.value ? "check" : "content_copy"), 1)
916
- ], 10, Mt),
917
- e.showRate ? (t(), a(B, { key: 0 }, [
918
- s("button", {
919
- type: "button",
920
- class: v(["ds-contact-value__action", { "is-active": e.correct === !0 }]),
921
- "aria-label": e.correctLabel,
922
- "aria-pressed": e.correct === !0,
923
- title: e.correctLabel,
924
- onClick: u
925
- }, [
926
- s("i", {
927
- class: v(e.correct === !0 ? "material-icons" : "material-icons-outlined"),
928
- "aria-hidden": "true"
929
- }, "thumb_up", 2)
930
- ], 10, Ut),
1462
+ }, 8, ["tone", "title"])) : m("", !0),
1463
+ s("span", Ga, [
1464
+ e.hideValue ? (a(), l("i", {
1465
+ key: 0,
1466
+ class: "material-icons ds-contact-value__lock",
1467
+ role: e.hideValueLabel ? "img" : void 0,
1468
+ "aria-label": e.hideValueLabel || void 0,
1469
+ "aria-hidden": e.hideValueLabel ? void 0 : "true"
1470
+ }, "lock", 8, Ha)) : (a(), l(z, { key: 1 }, [
931
1471
  s("button", {
932
1472
  type: "button",
933
- class: v(["ds-contact-value__action", { "is-active": e.correct === !1 }]),
934
- "aria-label": e.incorrectLabel,
935
- "aria-pressed": e.correct === !1,
936
- title: e.incorrectLabel,
937
- onClick: b
1473
+ class: $(["ds-contact-value__action", { "is-copied": i.value }]),
1474
+ "aria-label": i.value ? e.copiedLabel : e.copyLabel,
1475
+ title: i.value ? e.copiedLabel : e.copyLabel,
1476
+ onClick: k
938
1477
  }, [
939
- s("i", {
940
- class: v(e.correct === !1 ? "material-icons" : "material-icons-outlined"),
941
- "aria-hidden": "true"
942
- }, "thumb_down", 2)
943
- ], 10, Ft)
944
- ], 64)) : r("", !0)
1478
+ s("i", Ka, S(i.value ? "check" : "content_copy"), 1)
1479
+ ], 10, Wa),
1480
+ e.showRate ? (a(), l(z, { key: 0 }, [
1481
+ s("button", {
1482
+ type: "button",
1483
+ class: "ds-contact-value__action",
1484
+ "aria-label": e.correctLabel,
1485
+ "aria-pressed": e.correct === !0,
1486
+ title: e.correctLabel,
1487
+ onClick: f
1488
+ }, [
1489
+ s("i", {
1490
+ class: $(e.correct === !0 ? "material-icons" : "material-icons-outlined"),
1491
+ "aria-hidden": "true"
1492
+ }, "thumb_up", 2)
1493
+ ], 8, Ya),
1494
+ s("button", {
1495
+ type: "button",
1496
+ class: "ds-contact-value__action",
1497
+ "aria-label": e.incorrectLabel,
1498
+ "aria-pressed": e.correct === !1,
1499
+ title: e.incorrectLabel,
1500
+ onClick: y
1501
+ }, [
1502
+ s("i", {
1503
+ class: $(e.correct === !1 ? "material-icons" : "material-icons-outlined"),
1504
+ "aria-hidden": "true"
1505
+ }, "thumb_down", 2)
1506
+ ], 8, qa)
1507
+ ], 64)) : m("", !0)
1508
+ ], 64))
945
1509
  ])
946
1510
  ])
947
1511
  ], 2));
948
1512
  }
949
- }), ae = /* @__PURE__ */ $(zt, [["__scopeId", "data-v-014e772b"]]), _t = ["aria-label"], Pt = { class: "ds-data-card__heading" }, Gt = {
1513
+ }), je = /* @__PURE__ */ M(ja, [["__scopeId", "data-v-4f2d5d85"]]), Xa = ["aria-label", "aria-busy"], Za = { class: "ds-data-card__heading" }, Qa = {
950
1514
  class: "material-icons ds-data-card__icon",
951
1515
  "aria-hidden": "true"
952
- }, Yt = { class: "ds-data-card__title" }, Kt = ["aria-label"], Ht = {
1516
+ }, Ja = { class: "ds-data-card__title" }, el = ["aria-label"], tl = {
953
1517
  key: 0,
954
1518
  class: "ds-data-card__body"
955
- }, Wt = {
1519
+ }, al = {
956
1520
  key: 0,
1521
+ class: "ds-data-card__loading"
1522
+ }, ll = {
1523
+ key: 1,
1524
+ class: "ds-data-card__locked"
1525
+ }, il = { class: "ds-data-card__state-text" }, nl = { class: "ds-data-card__state-title" }, sl = {
1526
+ key: 2,
957
1527
  class: "ds-data-card__empty"
958
- }, qt = {
959
- class: "material-icons-outlined ds-data-card__empty-icon",
1528
+ }, ol = { class: "ds-data-card__state-badge" }, dl = {
1529
+ class: "material-icons ds-data-card__state-icon",
960
1530
  "aria-hidden": "true"
961
- }, pt = { key: 0 }, Xt = {
1531
+ }, rl = { class: "ds-data-card__state-text" }, cl = { class: "ds-data-card__state-title" }, ul = {
1532
+ key: 0,
1533
+ class: "ds-data-card__state-subtitle"
1534
+ }, fl = { key: 0 }, bl = {
962
1535
  key: 0,
963
1536
  class: "ds-data-card__section"
964
- }, Zt = { key: 1 }, jt = {
1537
+ }, vl = { key: 1 }, yl = {
965
1538
  key: 0,
966
1539
  class: "ds-data-card__section"
967
- }, Qt = { class: "ds-data-card__more" }, Jt = /* @__PURE__ */ k({
1540
+ }, ml = { class: "ds-data-card__more" }, hl = /* @__PURE__ */ x({
968
1541
  __name: "DsDataCard",
969
1542
  props: {
970
1543
  title: { type: String, required: !0 },
971
1544
  // Material Icon name for the header (e.g. "email", "call").
972
1545
  icon: { type: String, default: "email" },
1546
+ // Loading state: swaps the body for a centered spinner (wins over empty/data).
1547
+ // Override the spinner (e.g. an i18n'd label) via the #loading slot.
1548
+ loading: { type: Boolean, default: !1 },
1549
+ // Accessible name for the loading spinner (the app owns i18n); when omitted it
1550
+ // falls back to DsSpinner's own default. Overridable via the #loading slot.
1551
+ loadingLabel: { type: String, default: "" },
1552
+ // Locked/upsell state: the data is gated (plan/permission), so the body shows a
1553
+ // banner instead of the content (wins over empty/data; loading still wins over
1554
+ // it). Presentational only — the app decides when to gate and supplies the CTA
1555
+ // via the #locked slot. Additive/opt-in. NB: the header actions still render
1556
+ // while locked — turn them off yourself (showSort / showEdit) when gating.
1557
+ locked: { type: Boolean, default: !1 },
973
1558
  mostLikely: { type: Object, default: null },
974
1559
  more: { type: Array, default: () => [] },
975
1560
  collapsible: { type: Boolean, default: !1 },
@@ -981,164 +1566,1224 @@ const Y = {
981
1566
  // User-facing labels (the app owns i18n); English DS defaults.
982
1567
  editLabel: { type: String, default: "Edit" },
983
1568
  emptyLabel: { type: String, default: "No data found" },
1569
+ // Optional muted line under the empty title (DS DsDataCard `emptySubtitle`),
1570
+ // e.g. "We couldn't find any phone numbers for this contact."
1571
+ emptySubtitle: { type: String, default: "" },
1572
+ // Fallback text for the locked banner when no #locked slot is provided.
1573
+ lockedLabel: { type: String, default: "Locked" },
984
1574
  mostLikelyLabel: { type: String, default: "MOST LIKELY" },
985
1575
  moreLabel: { type: String, default: "MORE" },
986
1576
  sortLabel: { type: String, default: "Sort" },
987
1577
  toggleLabel: { type: String, default: "Toggle" },
988
1578
  closeLabel: { type: String, default: "Close" }
989
1579
  },
990
- emits: [F, j, Q, C, z, _],
1580
+ emits: [pe, Pe, Fe, X, $e, Te],
991
1581
  setup(e, { emit: n }) {
992
- const o = e, l = n, i = N(!1), d = S(() => o.more.length + (o.mostLikely ? 1 : 0)), c = S(() => d.value > 3), u = S(() => d.value === 0), b = S(() => o.collapsible && i.value);
993
- function m() {
1582
+ const t = e, o = n, i = U(!1), c = g(() => t.more.length + (t.mostLikely ? 1 : 0)), k = g(() => c.value > 3), f = g(() => c.value === 0), y = g(() => t.collapsible && i.value);
1583
+ function r() {
994
1584
  i.value = !i.value;
995
1585
  }
996
- function f(R) {
997
- l(F, R);
1586
+ function d(C) {
1587
+ o(pe, C);
1588
+ }
1589
+ function b() {
1590
+ o(Pe);
998
1591
  }
999
1592
  function h() {
1000
- l(j);
1593
+ o(Fe);
1001
1594
  }
1002
1595
  function T() {
1003
- l(Q);
1596
+ o(X);
1004
1597
  }
1005
- function x() {
1006
- l(C);
1598
+ function p(C) {
1599
+ o($e, C);
1007
1600
  }
1008
- function p(R) {
1009
- l(z, R);
1601
+ function V(C) {
1602
+ o(Te, C);
1010
1603
  }
1011
- function X(R) {
1012
- l(_, R);
1013
- }
1014
- return (R, E) => (t(), a("section", {
1604
+ return (C, E) => (a(), l("section", {
1015
1605
  class: "ds-data-card",
1016
- "aria-label": e.title
1606
+ "aria-label": e.title,
1607
+ "aria-busy": e.loading ? "true" : void 0
1017
1608
  }, [
1018
1609
  s("div", {
1019
- class: v(["ds-data-card__header", { "is-collapsed": b.value, "is-collapsible": e.collapsible }]),
1020
- onClick: E[1] || (E[1] = (L) => e.collapsible && m())
1610
+ class: $(["ds-data-card__header", { "is-collapsed": y.value, "is-collapsible": e.collapsible }]),
1611
+ onClick: E[1] || (E[1] = (N) => e.collapsible && r())
1021
1612
  }, [
1022
- s("div", Pt, [
1023
- s("i", Gt, y(e.icon), 1),
1024
- s("span", Yt, y(e.title), 1)
1613
+ s("div", Za, [
1614
+ s("i", Qa, S(e.icon), 1),
1615
+ s("span", Ja, S(e.title), 1)
1025
1616
  ]),
1026
1617
  s("div", {
1027
1618
  class: "ds-data-card__actions",
1028
- onClick: E[0] || (E[0] = se(() => {
1619
+ onClick: E[0] || (E[0] = ve(() => {
1029
1620
  }, ["stop"]))
1030
1621
  }, [
1031
- !b.value && e.showEdit ? (t(), a("button", {
1622
+ !y.value && e.showEdit ? (a(), l("button", {
1032
1623
  key: 0,
1033
1624
  type: "button",
1034
1625
  class: "ds-data-card__edit",
1035
- onClick: T
1036
- }, y(e.editLabel), 1)) : r("", !0),
1037
- !b.value && e.showSort ? (t(), D(g(K), {
1626
+ onClick: h
1627
+ }, S(e.editLabel), 1)) : m("", !0),
1628
+ !y.value && e.showSort ? (a(), G(_(oe), {
1038
1629
  key: 1,
1039
1630
  variant: "tertiary",
1040
1631
  size: "medium",
1041
1632
  circle: "",
1042
1633
  "left-icon": "swap_vert",
1043
1634
  "aria-label": e.sortLabel,
1044
- onClick: h
1045
- }, null, 8, ["aria-label"])) : r("", !0),
1046
- e.collapsible ? (t(), D(g(K), {
1635
+ onClick: b
1636
+ }, null, 8, ["aria-label"])) : m("", !0),
1637
+ e.collapsible ? (a(), G(_(oe), {
1047
1638
  key: 2,
1048
1639
  variant: "tertiary",
1049
1640
  size: "medium",
1050
1641
  circle: "",
1051
1642
  "left-icon": i.value ? "keyboard_arrow_down" : "keyboard_arrow_up",
1052
1643
  "aria-label": e.toggleLabel,
1053
- onClick: m
1054
- }, null, 8, ["left-icon", "aria-label"])) : r("", !0),
1055
- e.showClose ? (t(), a("button", {
1644
+ onClick: r
1645
+ }, null, 8, ["left-icon", "aria-label"])) : m("", !0),
1646
+ e.showClose ? (a(), l("button", {
1056
1647
  key: 3,
1057
1648
  type: "button",
1058
1649
  class: "ds-data-card__close",
1059
1650
  "aria-label": e.closeLabel,
1060
- onClick: x
1651
+ onClick: T
1061
1652
  }, [...E[4] || (E[4] = [
1062
1653
  s("i", {
1063
1654
  class: "material-icons",
1064
1655
  "aria-hidden": "true"
1065
1656
  }, "close", -1)
1066
- ])], 8, Kt)) : r("", !0)
1657
+ ])], 8, el)) : m("", !0)
1067
1658
  ])
1068
1659
  ], 2),
1069
- b.value ? r("", !0) : (t(), a("div", Ht, [
1070
- u.value ? (t(), a("div", Wt, [
1071
- s("i", qt, y(e.icon), 1),
1072
- s("span", null, y(e.emptyLabel), 1)
1073
- ])) : (t(), a(B, { key: 1 }, [
1074
- e.mostLikely ? (t(), a("div", pt, [
1075
- c.value ? (t(), a("div", Xt, y(e.mostLikelyLabel), 1)) : r("", !0),
1076
- de(g(ae), {
1660
+ y.value ? m("", !0) : (a(), l("div", tl, [
1661
+ e.loading ? (a(), l("div", al, [
1662
+ A(C.$slots, "loading", {}, () => [
1663
+ j(_(fe), {
1664
+ label: e.loadingLabel || void 0
1665
+ }, null, 8, ["label"])
1666
+ ], !0)
1667
+ ])) : e.locked ? (a(), l("div", ll, [
1668
+ A(C.$slots, "locked", {}, () => [
1669
+ E[5] || (E[5] = s("span", { class: "ds-data-card__state-badge ds-data-card__state-badge--accent" }, [
1670
+ s("i", {
1671
+ class: "material-icons ds-data-card__state-icon",
1672
+ "aria-hidden": "true"
1673
+ }, "lock")
1674
+ ], -1)),
1675
+ s("div", il, [
1676
+ s("span", nl, S(e.lockedLabel), 1)
1677
+ ])
1678
+ ], !0)
1679
+ ])) : f.value ? (a(), l("div", sl, [
1680
+ s("span", ol, [
1681
+ s("i", dl, S(e.icon), 1)
1682
+ ]),
1683
+ s("div", rl, [
1684
+ s("span", cl, S(e.emptyLabel), 1),
1685
+ e.emptySubtitle ? (a(), l("span", ul, S(e.emptySubtitle), 1)) : m("", !0)
1686
+ ])
1687
+ ])) : (a(), l(z, { key: 3 }, [
1688
+ e.mostLikely ? (a(), l("div", fl, [
1689
+ k.value ? (a(), l("div", bl, S(e.mostLikelyLabel), 1)) : m("", !0),
1690
+ j(_(je), {
1077
1691
  value: e.mostLikely.value,
1078
1692
  "value-type": e.mostLikely.type,
1079
1693
  verified: e.mostLikely.verified,
1080
1694
  correct: e.mostLikely.correct,
1695
+ "hide-value": e.mostLikely.hideValue,
1081
1696
  main: "",
1082
1697
  "is-contact-data": e.isContactData,
1083
1698
  "show-rate": e.showRate,
1084
- onCopy: f,
1085
- onCorrect: E[2] || (E[2] = (L) => p(e.mostLikely)),
1086
- onIncorrect: E[3] || (E[3] = (L) => X(e.mostLikely))
1087
- }, null, 8, ["value", "value-type", "verified", "correct", "is-contact-data", "show-rate"])
1088
- ])) : r("", !0),
1089
- e.more.length > 0 ? (t(), a("div", Zt, [
1090
- c.value ? (t(), a("div", jt, y(e.moreLabel), 1)) : r("", !0),
1091
- s("div", Qt, [
1092
- (t(!0), a(B, null, M(e.more, (L) => (t(), D(g(ae), {
1093
- key: L.value,
1094
- value: L.value,
1095
- "value-type": L.type,
1096
- verified: L.verified,
1097
- correct: L.correct,
1699
+ onCopy: d,
1700
+ onCorrect: E[2] || (E[2] = (N) => p(e.mostLikely)),
1701
+ onIncorrect: E[3] || (E[3] = (N) => V(e.mostLikely))
1702
+ }, null, 8, ["value", "value-type", "verified", "correct", "hide-value", "is-contact-data", "show-rate"])
1703
+ ])) : m("", !0),
1704
+ e.more.length > 0 ? (a(), l("div", vl, [
1705
+ k.value ? (a(), l("div", yl, S(e.moreLabel), 1)) : m("", !0),
1706
+ s("div", ml, [
1707
+ (a(!0), l(z, null, Y(e.more, (N) => (a(), G(_(je), {
1708
+ key: N.value,
1709
+ value: N.value,
1710
+ "value-type": N.type,
1711
+ verified: N.verified,
1712
+ correct: N.correct,
1713
+ "hide-value": N.hideValue,
1098
1714
  "is-contact-data": e.isContactData,
1099
1715
  "show-rate": e.showRate,
1100
- onCopy: f,
1101
- onCorrect: (re) => p(L),
1102
- onIncorrect: (re) => X(L)
1103
- }, null, 8, ["value", "value-type", "verified", "correct", "is-contact-data", "show-rate", "onCorrect", "onIncorrect"]))), 128))
1716
+ onCopy: d,
1717
+ onCorrect: (R) => p(N),
1718
+ onIncorrect: (R) => V(N)
1719
+ }, null, 8, ["value", "value-type", "verified", "correct", "hide-value", "is-contact-data", "show-rate", "onCorrect", "onIncorrect"]))), 128))
1104
1720
  ])
1105
- ])) : r("", !0)
1721
+ ])) : m("", !0)
1106
1722
  ], 64))
1107
1723
  ]))
1108
- ], 8, _t));
1724
+ ], 8, Xa));
1725
+ }
1726
+ }), Hi = /* @__PURE__ */ M(hl, [["__scopeId", "data-v-a062c3ae"]]), gl = ["name", "value", "checked", "disabled"], Sl = {
1727
+ key: 0,
1728
+ class: "ds-radio__label"
1729
+ }, kl = /* @__PURE__ */ x({
1730
+ __name: "DsRadio",
1731
+ props: /* @__PURE__ */ Q({
1732
+ disabled: Boolean,
1733
+ // Label text (DS `label` prop); a default slot overrides it.
1734
+ label: { type: String, default: "" },
1735
+ name: { type: String, default: "" },
1736
+ value: { type: String, default: "" }
1737
+ }, {
1738
+ modelValue: { type: Boolean, default: !1 },
1739
+ modelModifiers: {}
1740
+ }),
1741
+ emits: ["update:modelValue"],
1742
+ setup(e) {
1743
+ const n = de(e, "modelValue"), t = e;
1744
+ function o() {
1745
+ t.disabled || (n.value = !0);
1746
+ }
1747
+ return (i, c) => (a(), l("label", {
1748
+ class: $(["ds-radio", { "is-disabled": e.disabled }])
1749
+ }, [
1750
+ s("input", {
1751
+ type: "radio",
1752
+ class: "ds-radio__native",
1753
+ name: e.name || void 0,
1754
+ value: e.value || void 0,
1755
+ checked: n.value,
1756
+ disabled: e.disabled,
1757
+ onChange: o
1758
+ }, null, 40, gl),
1759
+ s("span", {
1760
+ class: $(["ds-radio__dot", { "is-active": n.value }]),
1761
+ "aria-hidden": "true"
1762
+ }, null, 2),
1763
+ i.$slots.default || e.label ? (a(), l("span", Sl, [
1764
+ A(i.$slots, "default", {}, () => [
1765
+ H(S(e.label), 1)
1766
+ ], !0)
1767
+ ])) : m("", !0)
1768
+ ], 2));
1769
+ }
1770
+ }), Wi = /* @__PURE__ */ M(kl, [["__scopeId", "data-v-96b70404"]]), pl = ["aria-checked", "aria-busy", "aria-disabled", "aria-label", "disabled"], $l = {
1771
+ class: "ds-switch__thumb",
1772
+ "aria-hidden": "true"
1773
+ }, Tl = /* @__PURE__ */ x({
1774
+ __name: "DsSwitch",
1775
+ props: /* @__PURE__ */ Q({
1776
+ disabled: Boolean,
1777
+ // Async busy state for a toggle whose commit is pending (e.g. a server round-trip
1778
+ // that may revert). Blocks interaction and shows a spinner in the thumb while it
1779
+ // resolves. Presentational-only: the app owns the optimistic value + revert; the
1780
+ // component just reflects the `loading` and `modelValue` it's handed.
1781
+ loading: Boolean,
1782
+ // Accessible name for the switch (a control with no visible text). See
1783
+ // DsSwitch.types.ts for why this stays optional rather than a required prop.
1784
+ ariaLabel: { type: String, default: "" }
1785
+ }, {
1786
+ modelValue: { type: Boolean, default: !1 },
1787
+ modelModifiers: {}
1788
+ }),
1789
+ emits: ["update:modelValue"],
1790
+ setup(e) {
1791
+ const n = de(e, "modelValue"), t = e;
1792
+ function o() {
1793
+ t.disabled || t.loading || (n.value = !n.value);
1794
+ }
1795
+ return (i, c) => (a(), l("button", {
1796
+ type: "button",
1797
+ role: "switch",
1798
+ class: $(["ds-switch", { "is-disabled": e.disabled, "is-loading": e.loading }]),
1799
+ "aria-checked": n.value,
1800
+ "aria-busy": e.loading || void 0,
1801
+ "aria-disabled": e.disabled || e.loading || void 0,
1802
+ "aria-label": e.ariaLabel || void 0,
1803
+ disabled: e.disabled || e.loading,
1804
+ onClick: o
1805
+ }, [
1806
+ s("span", $l, [
1807
+ e.loading ? (a(), G(_(fe), {
1808
+ key: 0,
1809
+ class: "ds-switch__spinner",
1810
+ size: 12,
1811
+ tone: _(ge).DARK,
1812
+ label: ""
1813
+ }, null, 8, ["tone"])) : m("", !0)
1814
+ ])
1815
+ ], 10, pl));
1816
+ }
1817
+ }), Ki = /* @__PURE__ */ M(Tl, [["__scopeId", "data-v-f8073b3b"]]), El = ["aria-label", "disabled"], Ll = { class: "ds-item-selector-button__label" }, wl = /* @__PURE__ */ x({
1818
+ __name: "DsItemSelectorButton",
1819
+ props: {
1820
+ item: { type: Object, default: null },
1821
+ // Material Icons ligature (e.g. `folder`); omitted entirely when unset.
1822
+ icon: { type: String, default: "" },
1823
+ emptyTitle: { type: String, default: "" },
1824
+ // Accessible name (see .types.ts). Required in the empty state when there's no
1825
+ // `emptyTitle`; the visible text (item.name / emptyTitle) names it otherwise.
1826
+ ariaLabel: { type: String, default: "" },
1827
+ disabled: Boolean
1828
+ },
1829
+ emits: [Z],
1830
+ setup(e, { emit: n }) {
1831
+ const t = e, o = n;
1832
+ function i(c) {
1833
+ t.disabled || o(Z, c);
1834
+ }
1835
+ return (c, k) => {
1836
+ var f;
1837
+ return a(), l("button", {
1838
+ type: "button",
1839
+ class: $(["ds-item-selector-button", { "is-empty": !e.item, "is-disabled": e.disabled }]),
1840
+ "aria-haspopup": "listbox",
1841
+ "aria-label": e.ariaLabel || void 0,
1842
+ disabled: e.disabled,
1843
+ onClick: i
1844
+ }, [
1845
+ s("span", Ll, S(e.item ? e.item.name : e.emptyTitle), 1),
1846
+ e.icon ? (a(), l("i", {
1847
+ key: 0,
1848
+ class: $(["ds-item-selector-button__icon", e.item ? "material-icons" : "material-icons-outlined"]),
1849
+ style: F((f = e.item) != null && f.color ? { color: e.item.color } : void 0),
1850
+ "aria-hidden": "true"
1851
+ }, S(e.icon), 7)) : m("", !0)
1852
+ ], 10, El);
1853
+ };
1854
+ }
1855
+ }), Yi = /* @__PURE__ */ M(wl, [["__scopeId", "data-v-92d8d822"]]), Xe = {
1856
+ DEFAULT: "default",
1857
+ FILTER_SUMMARY: "filterSummary"
1858
+ }, Ze = {
1859
+ AUTO: "auto",
1860
+ // shrink to content — resizes with the selected label (default)
1861
+ SMALL: "small",
1862
+ // 128px
1863
+ MEDIUM: "medium",
1864
+ // 200px
1865
+ LARGE: "large",
1866
+ // 280px
1867
+ FULL: "full"
1868
+ // 100% of the container
1869
+ }, Il = ["disabled", "aria-expanded", "aria-controls", "aria-activedescendant"], Cl = ["title"], _l = ["disabled", "aria-label"], Dl = {
1870
+ key: 1,
1871
+ class: "material-icons ds-select__chevron",
1872
+ "aria-hidden": "true"
1873
+ }, Al = {
1874
+ key: 0,
1875
+ class: "ds-select__popup"
1876
+ }, Nl = {
1877
+ key: 0,
1878
+ class: "ds-select__search"
1879
+ }, Rl = ["aria-activedescendant", "aria-label", "placeholder", "value"], Bl = ["aria-multiselectable", "aria-busy"], xl = {
1880
+ key: 0,
1881
+ class: "ds-select__loading",
1882
+ role: "presentation"
1883
+ }, Ml = ["role", "aria-labelledby"], Ol = ["id"], Pl = ["id", "aria-selected", "onClick", "onMouseenter"], Fl = { class: "ds-select__option-label" }, zl = {
1884
+ key: 0,
1885
+ class: "ds-select__option-sublabel"
1886
+ }, Vl = {
1887
+ key: 0,
1888
+ class: "ds-select__empty",
1889
+ role: "presentation"
1890
+ }, Ul = /* @__PURE__ */ x({
1891
+ __name: "DsSelect",
1892
+ props: /* @__PURE__ */ Q({
1893
+ options: { type: Array, required: !0 },
1894
+ placeholder: { type: String, default: "Select an option" },
1895
+ multiple: Boolean,
1896
+ selectType: { type: String, default: Xe.DEFAULT },
1897
+ showCheckbox: Boolean,
1898
+ // Named step ('small'|'medium'|'large'|'full'|'auto') for a STABLE width, or a
1899
+ // custom width (number → px, or any CSS string). Defaults to 'auto'
1900
+ // (shrink-to-content — the historical behaviour, kept so this stays a
1901
+ // non-breaking, opt-in feature); pass a fixed step for a width that doesn't
1902
+ // resize with the selected label. See DsSelect.types.ts `DS_SELECT_WIDTHS`.
1903
+ width: {
1904
+ type: [Number, String],
1905
+ default: Ze.AUTO
1906
+ },
1907
+ disabled: Boolean,
1908
+ // Opt-in type-to-filter: renders a search input inside the open dropdown.
1909
+ // Off by default, so existing usages keep the plain select-only behaviour.
1910
+ filterable: Boolean,
1911
+ // Remote filtering: skip the built-in local filter and let the app own it by
1912
+ // replacing `options` in response to the `search` event. Prevents a double
1913
+ // filter (local re-filtering of already server-filtered results). No effect
1914
+ // unless `filterable` is also set.
1915
+ remote: Boolean,
1916
+ // Async loading state: while true the listbox shows a spinner + aria-busy
1917
+ // instead of options/empty. A #loading slot overrides the default DsSpinner.
1918
+ loading: Boolean,
1919
+ // Accessible name for the filter search input (a placeholder is not a reliable
1920
+ // accessible name). English default; the app owns i18n.
1921
+ searchLabel: { type: String, default: "Filter options" },
1922
+ // Visible placeholder for the filter search input.
1923
+ searchPlaceholder: { type: String, default: "Search" },
1924
+ // Accessible name for the filterSummary clear (×) control. The app can override
1925
+ // the wording (e.g. localized), but we default to a non-empty fallback so the
1926
+ // icon-only button is never left without an accessible name for screen readers.
1927
+ clearLabel: { type: String, default: "Clear selection" },
1928
+ // Shown when the visible list is empty (no options, or a filtered list with no
1929
+ // matches). English default (the app owns i18n); a #empty slot overrides it.
1930
+ emptyText: { type: String, default: "No options" }
1931
+ }, {
1932
+ modelValue: { default: null },
1933
+ modelModifiers: {}
1934
+ }),
1935
+ emits: /* @__PURE__ */ Q([_e], ["update:modelValue"]),
1936
+ setup(e, { emit: n }) {
1937
+ const t = e, o = n, i = de(e, "modelValue"), c = `ds-select-${xe()}`, k = `${c}-listbox`, f = (u) => `${c}-option-${u}`, y = U(null), r = U(null), d = U(null), b = U(!1), h = U(-1), T = U(""), p = g(() => t.selectType === Xe.FILTER_SUMMARY), V = g(() => t.filterable && !t.remote), C = g(() => {
1938
+ if (!V.value) return t.options;
1939
+ const u = T.value.trim().toLowerCase();
1940
+ return u ? t.options.filter(
1941
+ (L) => L.label.toLowerCase().includes(u) || (L.subLabel ? L.subLabel.toLowerCase().includes(u) : !1)
1942
+ ) : t.options;
1943
+ }), E = g(
1944
+ () => t.loading ? [] : C.value
1945
+ ), N = g(() => {
1946
+ const u = [];
1947
+ return E.value.forEach((L, O) => {
1948
+ const B = L.group, K = u[u.length - 1];
1949
+ B ? (K == null ? void 0 : K.kind) === "group" && K.label === B ? K.items.push({ option: L, index: O }) : u.push({
1950
+ kind: "group",
1951
+ label: B,
1952
+ headerId: `${c}-group-${O}`,
1953
+ key: `g-${O}`,
1954
+ items: [{ option: L, index: O }]
1955
+ }) : (K == null ? void 0 : K.kind) === "plain" ? K.items.push({ option: L, index: O }) : u.push({ kind: "plain", key: `p-${O}`, items: [{ option: L, index: O }] });
1956
+ }), u;
1957
+ }), R = g(() => t.multiple ? Array.isArray(i.value) ? i.value : [] : i.value !== null && i.value !== void 0 ? [i.value] : []), q = g(() => R.value.length > 0), J = g(() => p.value && q.value);
1958
+ function W(u) {
1959
+ return R.value.includes(u);
1960
+ }
1961
+ const ae = ut(/* @__PURE__ */ new Map());
1962
+ te(
1963
+ () => t.options,
1964
+ (u) => u.forEach((L) => ae.set(L.value, L.label)),
1965
+ { immediate: !0, deep: !0 }
1966
+ );
1967
+ function re(u) {
1968
+ var L, O, B;
1969
+ return (B = (O = (L = t.options.find((K) => K.value === u)) == null ? void 0 : L.label) != null ? O : ae.get(u)) != null ? B : String(u);
1970
+ }
1971
+ const v = g(() => p.value ? q.value ? t.multiple ? `${t.placeholder} (${R.value.length})` : re(R.value[0]) : t.placeholder : q.value ? t.multiple ? R.value.map(re).join(", ") : re(R.value[0]) : t.placeholder), D = Object.values(Ze), w = g(
1972
+ () => typeof t.width == "string" && D.includes(t.width) ? `ds-select--w-${t.width}` : null
1973
+ ), I = g(() => {
1974
+ if (!w.value)
1975
+ return { width: typeof t.width == "number" ? `${t.width}px` : t.width };
1976
+ }), P = g(
1977
+ () => b.value && h.value >= 0 ? f(h.value) : void 0
1978
+ );
1979
+ function ne() {
1980
+ if (E.value.length === 0) return -1;
1981
+ const u = E.value.findIndex((L) => W(L.value));
1982
+ return u >= 0 ? u : 0;
1983
+ }
1984
+ function ye() {
1985
+ t.disabled || (b.value = !0, h.value = ne(), t.filterable && ue(() => {
1986
+ var u;
1987
+ return (u = d.value) == null ? void 0 : u.focus();
1988
+ }));
1989
+ }
1990
+ function le(u = !0) {
1991
+ b.value = !1, h.value = -1, T.value && (T.value = "", o(_e, "")), u && ue(() => {
1992
+ var L;
1993
+ return (L = r.value) == null ? void 0 : L.focus();
1994
+ });
1995
+ }
1996
+ function tt() {
1997
+ t.disabled || (b.value ? le() : ye());
1998
+ }
1999
+ function we(u) {
2000
+ if (t.disabled) return;
2001
+ if (t.multiple) {
2002
+ const O = R.value;
2003
+ i.value = O.includes(u) ? O.filter((B) => B !== u) : [...O, u];
2004
+ return;
2005
+ }
2006
+ const L = W(u);
2007
+ i.value = L && t.showCheckbox ? null : u, le();
2008
+ }
2009
+ function at() {
2010
+ t.disabled || (i.value = t.multiple ? [] : null);
2011
+ }
2012
+ function me(u) {
2013
+ const L = E.value.length;
2014
+ L !== 0 && (h.value < 0 ? h.value = u > 0 ? 0 : L - 1 : h.value = (h.value + u + L) % L, ue(() => {
2015
+ var O, B;
2016
+ (B = (O = document.getElementById(f(h.value))) == null ? void 0 : O.scrollIntoView) == null || B.call(O, { block: "nearest" });
2017
+ }));
2018
+ }
2019
+ function lt(u) {
2020
+ if (!t.disabled)
2021
+ switch (u.key) {
2022
+ case "ArrowDown":
2023
+ u.preventDefault(), b.value ? me(1) : ye();
2024
+ break;
2025
+ case "ArrowUp":
2026
+ u.preventDefault(), b.value ? me(-1) : ye();
2027
+ break;
2028
+ case "Home":
2029
+ b.value && (u.preventDefault(), h.value = 0);
2030
+ break;
2031
+ case "End":
2032
+ b.value && (u.preventDefault(), h.value = E.value.length - 1);
2033
+ break;
2034
+ case "Enter":
2035
+ case " ":
2036
+ case "Spacebar":
2037
+ if (u.preventDefault(), !b.value)
2038
+ ye();
2039
+ else if (h.value >= 0) {
2040
+ const L = E.value[h.value];
2041
+ L && we(L.value);
2042
+ }
2043
+ break;
2044
+ case "Escape":
2045
+ b.value && (u.preventDefault(), u.stopPropagation(), le());
2046
+ break;
2047
+ case "Tab":
2048
+ b.value && le(!1);
2049
+ break;
2050
+ }
2051
+ }
2052
+ function it(u) {
2053
+ if (!t.disabled)
2054
+ switch (u.key) {
2055
+ case "ArrowDown":
2056
+ u.preventDefault(), me(1);
2057
+ break;
2058
+ case "ArrowUp":
2059
+ u.preventDefault(), me(-1);
2060
+ break;
2061
+ case "Enter":
2062
+ if (u.preventDefault(), h.value >= 0) {
2063
+ const L = E.value[h.value];
2064
+ L && we(L.value);
2065
+ }
2066
+ break;
2067
+ case "Escape":
2068
+ u.preventDefault(), u.stopPropagation(), le();
2069
+ break;
2070
+ case "Tab":
2071
+ b.value && le(!1);
2072
+ break;
2073
+ }
2074
+ }
2075
+ function nt(u) {
2076
+ T.value = u.target.value, o(_e, T.value);
2077
+ }
2078
+ te(E, (u) => {
2079
+ b.value && (u.length === 0 ? h.value = -1 : (h.value < 0 || h.value >= u.length) && (h.value = 0));
2080
+ });
2081
+ function Ie(u) {
2082
+ y.value && !y.value.contains(u.target) && le(!1);
2083
+ }
2084
+ return te(b, (u) => {
2085
+ typeof document != "undefined" && (u ? document.addEventListener("mousedown", Ie) : document.removeEventListener("mousedown", Ie));
2086
+ }), te(
2087
+ () => t.disabled,
2088
+ (u) => {
2089
+ u && b.value && le(!1);
2090
+ }
2091
+ ), be(() => {
2092
+ typeof document != "undefined" && document.removeEventListener("mousedown", Ie);
2093
+ }), (u, L) => (a(), l("div", {
2094
+ ref_key: "rootRef",
2095
+ ref: y,
2096
+ class: $(["ds-select", [`ds-select--${e.selectType}`, w.value, { "is-open": b.value }]]),
2097
+ style: F(I.value)
2098
+ }, [
2099
+ s("div", {
2100
+ class: $(["ds-select__control", { "is-disabled": e.disabled, "is-filter-selected": J.value }])
2101
+ }, [
2102
+ s("button", {
2103
+ ref_key: "triggerRef",
2104
+ ref: r,
2105
+ type: "button",
2106
+ class: "ds-select__trigger",
2107
+ disabled: e.disabled,
2108
+ "aria-haspopup": "listbox",
2109
+ "aria-expanded": b.value,
2110
+ "aria-controls": b.value ? k : void 0,
2111
+ "aria-activedescendant": e.filterable ? void 0 : P.value,
2112
+ onClick: tt,
2113
+ onKeydown: lt
2114
+ }, [
2115
+ s("span", {
2116
+ class: "ds-select__summary",
2117
+ title: v.value
2118
+ }, S(v.value), 9, Cl)
2119
+ ], 40, Il),
2120
+ p.value && q.value ? (a(), l("button", {
2121
+ key: 0,
2122
+ type: "button",
2123
+ class: "ds-select__clear",
2124
+ disabled: e.disabled,
2125
+ "aria-label": e.clearLabel || void 0,
2126
+ onClick: at
2127
+ }, [...L[1] || (L[1] = [
2128
+ s("i", {
2129
+ class: "material-icons",
2130
+ "aria-hidden": "true"
2131
+ }, "close", -1)
2132
+ ])], 8, _l)) : (a(), l("i", Dl, "keyboard_arrow_down"))
2133
+ ], 2),
2134
+ b.value ? (a(), l("div", Al, [
2135
+ e.filterable ? (a(), l("div", Nl, [
2136
+ L[2] || (L[2] = s("i", {
2137
+ class: "material-icons ds-select__search-icon",
2138
+ "aria-hidden": "true"
2139
+ }, "search", -1)),
2140
+ s("input", {
2141
+ ref_key: "searchRef",
2142
+ ref: d,
2143
+ type: "text",
2144
+ class: "ds-select__search-input",
2145
+ role: "combobox",
2146
+ "aria-expanded": "true",
2147
+ "aria-controls": k,
2148
+ "aria-activedescendant": P.value,
2149
+ "aria-autocomplete": "list",
2150
+ autocomplete: "off",
2151
+ "aria-label": e.searchLabel,
2152
+ placeholder: e.searchPlaceholder,
2153
+ value: T.value,
2154
+ onInput: nt,
2155
+ onKeydown: it
2156
+ }, null, 40, Rl)
2157
+ ])) : m("", !0),
2158
+ s("ul", {
2159
+ id: k,
2160
+ class: "ds-select__listbox",
2161
+ role: "listbox",
2162
+ "aria-multiselectable": e.multiple || void 0,
2163
+ "aria-busy": e.loading || void 0,
2164
+ onMousedown: L[0] || (L[0] = ve(() => {
2165
+ }, ["prevent"]))
2166
+ }, [
2167
+ e.loading ? (a(), l("li", xl, [
2168
+ A(u.$slots, "loading", {}, () => [
2169
+ j(_(fe), { size: "small" })
2170
+ ], !0)
2171
+ ])) : (a(), l(z, { key: 1 }, [
2172
+ (a(!0), l(z, null, Y(N.value, (O) => (a(), l("li", {
2173
+ key: O.key,
2174
+ role: O.kind === "group" ? "group" : "presentation",
2175
+ "aria-labelledby": O.kind === "group" ? O.headerId : void 0,
2176
+ class: $(O.kind === "group" ? "ds-select__group" : "ds-select__run")
2177
+ }, [
2178
+ O.kind === "group" ? (a(), l("span", {
2179
+ key: 0,
2180
+ id: O.headerId,
2181
+ class: "ds-select__group-header"
2182
+ }, S(O.label), 9, Ol)) : m("", !0),
2183
+ (a(!0), l(z, null, Y(O.items, (B) => (a(), l("div", {
2184
+ id: f(B.index),
2185
+ key: B.option.value,
2186
+ class: $(["ds-select__option", {
2187
+ "is-selected": W(B.option.value),
2188
+ "is-active": B.index === h.value,
2189
+ "ds-select__option--checkbox": e.showCheckbox
2190
+ }]),
2191
+ role: "option",
2192
+ "aria-selected": W(B.option.value),
2193
+ onClick: ve((K) => we(B.option.value), ["prevent"]),
2194
+ onMouseenter: (K) => h.value = B.index
2195
+ }, [
2196
+ e.showCheckbox ? (a(), G(_(et), {
2197
+ key: 0,
2198
+ class: "ds-select__option-check",
2199
+ "model-value": W(B.option.value),
2200
+ disabled: "",
2201
+ "aria-hidden": "true"
2202
+ }, null, 8, ["model-value"])) : m("", !0),
2203
+ A(u.$slots, "option", {
2204
+ option: B.option,
2205
+ selected: W(B.option.value),
2206
+ active: B.index === h.value
2207
+ }, () => [
2208
+ B.option.icon ? (a(), l("i", {
2209
+ key: 0,
2210
+ class: "material-icons ds-select__option-icon",
2211
+ style: F(B.option.color ? { color: B.option.color } : void 0),
2212
+ "aria-hidden": "true"
2213
+ }, S(B.option.icon), 5)) : m("", !0),
2214
+ s("span", Fl, [
2215
+ H(S(B.option.label), 1),
2216
+ B.option.subLabel ? (a(), l("span", zl, ", " + S(B.option.subLabel), 1)) : m("", !0)
2217
+ ])
2218
+ ], !0)
2219
+ ], 42, Pl))), 128))
2220
+ ], 10, Ml))), 128)),
2221
+ E.value.length === 0 ? (a(), l("li", Vl, [
2222
+ A(u.$slots, "empty", {}, () => [
2223
+ H(S(e.emptyText), 1)
2224
+ ], !0)
2225
+ ])) : m("", !0)
2226
+ ], 64))
2227
+ ], 40, Bl)
2228
+ ])) : m("", !0)
2229
+ ], 6));
2230
+ }
2231
+ }), qi = /* @__PURE__ */ M(Ul, [["__scopeId", "data-v-47964929"]]), Gl = ["tabindex"], Hl = /* @__PURE__ */ x({
2232
+ __name: "DsRow",
2233
+ props: {
2234
+ selected: { type: Boolean, default: !1 },
2235
+ clickable: { type: Boolean, default: !1 }
2236
+ },
2237
+ emits: [Z],
2238
+ setup(e, { emit: n }) {
2239
+ const t = e, o = n;
2240
+ function i() {
2241
+ t.clickable && o(Z);
2242
+ }
2243
+ function c(k) {
2244
+ t.clickable && (k.key === "Enter" || k.key === " ") && (k.preventDefault(), o(Z));
2245
+ }
2246
+ return (k, f) => (a(), l("tr", {
2247
+ class: $(["ds-row", { "is-selected": e.selected, "is-clickable": e.clickable }]),
2248
+ tabindex: e.clickable ? 0 : void 0,
2249
+ onClick: i,
2250
+ onKeydown: c
2251
+ }, [
2252
+ A(k.$slots, "default", {}, void 0, !0)
2253
+ ], 42, Gl));
2254
+ }
2255
+ }), ji = /* @__PURE__ */ M(Hl, [["__scopeId", "data-v-c2d6c50b"]]), Wl = /* @__PURE__ */ x({
2256
+ __name: "DsCell",
2257
+ props: {
2258
+ first: { type: Boolean, default: !1 },
2259
+ selected: { type: Boolean, default: !1 },
2260
+ width: { type: [String, Number], default: null },
2261
+ // Opt-in single-line ellipsis. Default off preserves the 72px multi-line cell.
2262
+ truncate: { type: Boolean, default: !1 },
2263
+ // Pin to the left/right edge (position: sticky) for horizontal scroll.
2264
+ pinned: { type: String, default: null },
2265
+ // Cumulative offset from the pinned edge when stacking multiple pins per side
2266
+ // (number → px, or any CSS length). Defaults to 0 (single pin per side).
2267
+ pinnedOffset: {
2268
+ type: [String, Number],
2269
+ default: null
2270
+ }
2271
+ },
2272
+ setup(e) {
2273
+ const n = e, t = (i) => typeof i == "number" ? `${i}px` : i, o = g(() => {
2274
+ const i = {};
2275
+ if (n.width != null && (i.width = t(n.width)), n.pinned) {
2276
+ i.position = "sticky";
2277
+ const c = n.pinnedOffset == null ? "0px" : t(n.pinnedOffset);
2278
+ i[n.pinned === ee.LEFT ? "left" : "right"] = c;
2279
+ }
2280
+ return Object.keys(i).length ? i : void 0;
2281
+ });
2282
+ return (i, c) => (a(), l("td", {
2283
+ class: $(["ds-cell", {
2284
+ "is-accent": e.first && e.selected,
2285
+ "is-truncated": e.truncate,
2286
+ "is-selected": e.selected,
2287
+ "is-pinned": !!e.pinned,
2288
+ [`is-pinned--${e.pinned}`]: !!e.pinned
2289
+ }]),
2290
+ style: F(o.value)
2291
+ }, [
2292
+ A(i.$slots, "default", {}, void 0, !0)
2293
+ ], 6));
2294
+ }
2295
+ }), Xi = /* @__PURE__ */ M(Wl, [["__scopeId", "data-v-727b775d"]]), Kl = {
2296
+ SUCCESS: "success",
2297
+ WARNING: "warning",
2298
+ DANGER: "danger",
2299
+ // maps to $error-* tokens, not $danger-*
2300
+ INFO: "info",
2301
+ DRAFT: "draft",
2302
+ // the only solid-fill variant
2303
+ ACCENT: "accent"
2304
+ // maps to $info-* tokens, not $accent-*
2305
+ }, Yl = /* @__PURE__ */ x({
2306
+ __name: "DsCustomTag",
2307
+ props: {
2308
+ type: {
2309
+ type: String,
2310
+ default: Kl.INFO
2311
+ },
2312
+ // Fully rounded (radius-full) sides vs the default radius-control.
2313
+ round: Boolean
2314
+ },
2315
+ setup(e) {
2316
+ return (n, t) => (a(), l("span", {
2317
+ class: $(["ds-custom-tag", [`ds-custom-tag--${e.type}`, { "is-round": e.round }]])
2318
+ }, [
2319
+ A(n.$slots, "default", {}, void 0, !0)
2320
+ ], 2));
2321
+ }
2322
+ }), Zi = /* @__PURE__ */ M(Yl, [["__scopeId", "data-v-c0220631"]]), ql = { class: "ds-pill__text" }, jl = ["aria-label"], Xl = {
2323
+ class: "material-icons",
2324
+ "aria-hidden": "true"
2325
+ }, Zl = /* @__PURE__ */ x({
2326
+ __name: "DsPill",
2327
+ props: {
2328
+ // Material Icons ligature name; when set, renders a trailing icon button.
2329
+ icon: {
2330
+ type: String,
2331
+ default: ""
2332
+ },
2333
+ // Free-form CSS color (e.g. a dynamic tag/folder color); when empty, falls
2334
+ // back to the default token background ($slate-soft).
2335
+ background: {
2336
+ type: String,
2337
+ default: ""
2338
+ },
2339
+ // Accessible name for the trailing icon button (icon-only control).
2340
+ iconLabel: {
2341
+ type: String,
2342
+ default: ""
2343
+ }
2344
+ },
2345
+ emits: [Z],
2346
+ setup(e, { emit: n }) {
2347
+ const t = n;
2348
+ return (o, i) => (a(), l("span", {
2349
+ class: $(["ds-pill", { "ds-pill--has-icon": e.icon }]),
2350
+ style: F(e.background ? { background: e.background } : void 0)
2351
+ }, [
2352
+ s("span", ql, [
2353
+ A(o.$slots, "default", {}, void 0, !0)
2354
+ ]),
2355
+ e.icon ? (a(), l("button", {
2356
+ key: 0,
2357
+ type: "button",
2358
+ class: "ds-pill__icon",
2359
+ "aria-label": e.iconLabel || void 0,
2360
+ onClick: i[0] || (i[0] = (c) => t(_(Z)))
2361
+ }, [
2362
+ s("i", Xl, S(e.icon), 1)
2363
+ ], 8, jl)) : m("", !0)
2364
+ ], 6));
2365
+ }
2366
+ }), Qi = /* @__PURE__ */ M(Zl, [["__scopeId", "data-v-a8d4ddbb"]]), Ql = {
2367
+ key: 0,
2368
+ class: "ds-pill-with-border__icon"
2369
+ }, Jl = { class: "ds-pill-with-border__label" }, ei = /* @__PURE__ */ x({
2370
+ __name: "DsPillWithBorder",
2371
+ emits: [Z],
2372
+ setup(e, { emit: n }) {
2373
+ const t = n;
2374
+ return (o, i) => (a(), l("button", {
2375
+ type: "button",
2376
+ class: "ds-pill-with-border",
2377
+ onClick: i[0] || (i[0] = (c) => t(_(Z)))
2378
+ }, [
2379
+ o.$slots.icon ? (a(), l("span", Ql, [
2380
+ A(o.$slots, "icon", {}, void 0, !0)
2381
+ ])) : m("", !0),
2382
+ s("span", Jl, [
2383
+ A(o.$slots, "default", {}, void 0, !0)
2384
+ ])
2385
+ ]));
2386
+ }
2387
+ }), Ji = /* @__PURE__ */ M(ei, [["__scopeId", "data-v-8db4dcaf"]]), ti = ["aria-label"], ai = ["title"], li = {
2388
+ key: 1,
2389
+ class: "ds-segmented-progress-bar-wrapper"
2390
+ }, ii = ["aria-label"], ni = ["title"], si = {
2391
+ class: "ds-segmented-progress-bar__legend",
2392
+ "aria-hidden": "true"
2393
+ }, oi = { class: "ds-segmented-progress-bar__legend-label" }, di = /* @__PURE__ */ x({
2394
+ inheritAttrs: !1,
2395
+ __name: "DsSegmentedProgressBar",
2396
+ props: {
2397
+ segments: {
2398
+ type: Array,
2399
+ default: () => []
2400
+ },
2401
+ total: { type: Number, default: 100 },
2402
+ height: { type: Number, default: 8 },
2403
+ // Accessible name for the whole track — the DS source has zero ARIA on this
2404
+ // element, so role="img" + this label are the only a11y surface. Left empty
2405
+ // by default: omitted from the DOM until the consumer supplies a meaningful
2406
+ // summary (e.g. "55% verified, 25% risky, 20% invalid").
2407
+ label: { type: String, default: "" },
2408
+ // Opt-in: render a legend (color swatch + name) summarising every segment
2409
+ // below the track. Off by default so the render stays identical. A `#legend`
2410
+ // slot also opts in and replaces the auto legend with custom content.
2411
+ showLegend: { type: Boolean, default: !1 }
2412
+ },
2413
+ setup(e) {
2414
+ const n = e, t = Ee(), o = g(() => n.segments.filter((c) => !!c.name)), i = g(
2415
+ () => !!t.legend || n.showLegend && o.value.length > 0
2416
+ );
2417
+ return (c, k) => i.value ? (a(), l("div", li, [
2418
+ s("div", he(c.$attrs, {
2419
+ class: "ds-segmented-progress-bar",
2420
+ role: "img",
2421
+ "aria-label": e.label || void 0,
2422
+ style: { height: `${e.height}px` }
2423
+ }), [
2424
+ (a(!0), l(z, null, Y(e.segments, (f, y) => {
2425
+ var r;
2426
+ return a(), l("div", {
2427
+ key: `${(r = f.name) != null ? r : ""}-${y}`,
2428
+ class: "ds-segmented-progress-bar__segment",
2429
+ style: F({
2430
+ width: `${e.total > 0 ? f.amount * 100 / e.total : 0}%`,
2431
+ backgroundColor: f.color
2432
+ }),
2433
+ title: f.name || void 0
2434
+ }, null, 12, ni);
2435
+ }), 128))
2436
+ ], 16, ii),
2437
+ A(c.$slots, "legend", {}, () => [
2438
+ s("ul", si, [
2439
+ (a(!0), l(z, null, Y(o.value, (f, y) => (a(), l("li", {
2440
+ key: `${f.name}-${y}`,
2441
+ class: "ds-segmented-progress-bar__legend-item"
2442
+ }, [
2443
+ s("span", {
2444
+ class: "ds-segmented-progress-bar__legend-swatch",
2445
+ style: F({ backgroundColor: f.color })
2446
+ }, null, 4),
2447
+ s("span", oi, S(f.name), 1)
2448
+ ]))), 128))
2449
+ ])
2450
+ ], !0)
2451
+ ])) : (a(), l("div", he({ key: 0 }, c.$attrs, {
2452
+ class: "ds-segmented-progress-bar",
2453
+ role: "img",
2454
+ "aria-label": e.label || void 0,
2455
+ style: { height: `${e.height}px` }
2456
+ }), [
2457
+ (a(!0), l(z, null, Y(e.segments, (f, y) => {
2458
+ var r;
2459
+ return a(), l("div", {
2460
+ key: `${(r = f.name) != null ? r : ""}-${y}`,
2461
+ class: "ds-segmented-progress-bar__segment",
2462
+ style: F({
2463
+ width: `${e.total > 0 ? f.amount * 100 / e.total : 0}%`,
2464
+ backgroundColor: f.color
2465
+ }),
2466
+ title: f.name || void 0
2467
+ }, null, 12, ai);
2468
+ }), 128))
2469
+ ], 16, ti));
2470
+ }
2471
+ }), en = /* @__PURE__ */ M(di, [["__scopeId", "data-v-89dc768c"]]), ri = {
2472
+ key: 0,
2473
+ class: "ds-empty-state__header"
2474
+ }, ci = { class: "ds-empty-state__body" }, ui = ["src"], fi = { class: "ds-empty-state__title" }, bi = {
2475
+ key: 1,
2476
+ class: "ds-empty-state__subtitle"
2477
+ }, vi = /* @__PURE__ */ x({
2478
+ __name: "DsEmptyState",
2479
+ props: {
2480
+ // Illustration URL; decorative (rendered with alt="").
2481
+ image: { type: String, default: "" },
2482
+ title: { type: String, default: "" },
2483
+ subtitle: { type: String, default: "" },
2484
+ // DS `radius-card-lg` corners instead of the default square edge.
2485
+ roundedBorder: { type: Boolean, default: !1 }
2486
+ },
2487
+ setup(e) {
2488
+ return (n, t) => (a(), l("div", {
2489
+ class: $(["ds-empty-state", { "is-rounded": e.roundedBorder }])
2490
+ }, [
2491
+ n.$slots["table-header"] ? (a(), l("div", ri, [
2492
+ A(n.$slots, "table-header", {}, void 0, !0)
2493
+ ])) : m("", !0),
2494
+ s("div", ci, [
2495
+ e.image ? (a(), l("img", {
2496
+ key: 0,
2497
+ src: e.image,
2498
+ alt: "",
2499
+ class: "ds-empty-state__image"
2500
+ }, null, 8, ui)) : m("", !0),
2501
+ s("p", fi, S(e.title), 1),
2502
+ e.subtitle ? (a(), l("p", bi, S(e.subtitle), 1)) : m("", !0),
2503
+ A(n.$slots, "button", {}, void 0, !0)
2504
+ ])
2505
+ ], 2));
2506
+ }
2507
+ }), tn = /* @__PURE__ */ M(vi, [["__scopeId", "data-v-159c48f9"]]), yi = ["aria-label"], mi = {
2508
+ key: 0,
2509
+ class: "ds-paginator__limit-message"
2510
+ }, hi = { class: "ds-paginator__pager" }, gi = {
2511
+ key: 0,
2512
+ class: "ds-paginator__ellipsis",
2513
+ "aria-hidden": "true"
2514
+ }, Si = ["aria-current", "onClick"], ki = ["aria-label", "value"], pi = ["value"], $i = "…l", Ti = "…r", Ei = /* @__PURE__ */ x({
2515
+ __name: "DsPaginator",
2516
+ props: {
2517
+ total: { type: Number, required: !0 },
2518
+ pageSize: { type: Number, default: 25 },
2519
+ currentPage: { type: Number, default: 1 },
2520
+ pageSizes: { type: Array, default: () => [10, 25, 50, 100] },
2521
+ limitMessage: { type: String, default: "" },
2522
+ // Appended to each page-size option label (e.g. consumer passes "/page").
2523
+ pageSizeSuffix: { type: String, default: "" },
2524
+ // aria-labels for the icon-only chevron buttons — DS has none; empty unless
2525
+ // the consumer supplies one (see the a11y note on `.types.ts`).
2526
+ prevLabel: { type: String, default: "" },
2527
+ nextLabel: { type: String, default: "" },
2528
+ paginationLabel: { type: String, default: "" },
2529
+ pageSizeLabel: { type: String, default: "" }
2530
+ },
2531
+ emits: [Ve, Ue],
2532
+ setup(e, { emit: n }) {
2533
+ const t = e, o = n, i = g(() => Math.max(1, Math.ceil(t.total / t.pageSize))), c = g(() => {
2534
+ const y = i.value;
2535
+ if (y <= 7)
2536
+ return Array.from({ length: y }, (T, p) => p + 1);
2537
+ const r = t.currentPage, d = [1];
2538
+ r > 4 && d.push($i);
2539
+ const b = Math.max(2, r - 2), h = Math.min(y - 1, r + 2);
2540
+ for (let T = b; T <= h; T++)
2541
+ d.push(T);
2542
+ return r < y - 3 && d.push(Ti), d.push(y), d;
2543
+ });
2544
+ function k(y) {
2545
+ y < 1 || y > i.value || o(Ve, y);
2546
+ }
2547
+ function f(y) {
2548
+ const r = y.target;
2549
+ o(Ue, Number(r.value));
2550
+ }
2551
+ return (y, r) => (a(), l("nav", {
2552
+ class: "ds-paginator",
2553
+ "aria-label": e.paginationLabel || void 0
2554
+ }, [
2555
+ e.limitMessage ? (a(), l("span", mi, S(e.limitMessage), 1)) : m("", !0),
2556
+ s("div", hi, [
2557
+ j(_(oe), {
2558
+ variant: "tertiary",
2559
+ circle: "",
2560
+ size: "medium",
2561
+ "left-icon": "chevron_left",
2562
+ "aria-label": e.prevLabel || void 0,
2563
+ disabled: e.currentPage <= 1,
2564
+ onClick: r[0] || (r[0] = (d) => k(e.currentPage - 1))
2565
+ }, null, 8, ["aria-label", "disabled"]),
2566
+ (a(!0), l(z, null, Y(c.value, (d) => (a(), l(z, { key: d }, [
2567
+ typeof d == "string" ? (a(), l("span", gi, "…")) : (a(), l("button", {
2568
+ key: 1,
2569
+ type: "button",
2570
+ class: $(["ds-paginator__page", { "is-active": d === e.currentPage }]),
2571
+ "aria-current": d === e.currentPage ? "page" : void 0,
2572
+ onClick: (b) => k(d)
2573
+ }, S(d), 11, Si))
2574
+ ], 64))), 128)),
2575
+ j(_(oe), {
2576
+ variant: "tertiary",
2577
+ circle: "",
2578
+ size: "medium",
2579
+ "left-icon": "chevron_right",
2580
+ "aria-label": e.nextLabel || void 0,
2581
+ disabled: e.currentPage >= i.value,
2582
+ onClick: r[1] || (r[1] = (d) => k(e.currentPage + 1))
2583
+ }, null, 8, ["aria-label", "disabled"])
2584
+ ]),
2585
+ s("select", {
2586
+ class: "ds-paginator__page-size",
2587
+ "aria-label": e.pageSizeLabel || void 0,
2588
+ value: e.pageSize,
2589
+ onChange: f
2590
+ }, [
2591
+ (a(!0), l(z, null, Y(e.pageSizes, (d) => (a(), l("option", {
2592
+ key: d,
2593
+ value: d
2594
+ }, S(d) + S(e.pageSizeSuffix), 9, pi))), 128))
2595
+ ], 40, ki)
2596
+ ], 8, yi));
2597
+ }
2598
+ }), an = /* @__PURE__ */ M(Ei, [["__scopeId", "data-v-a42e7bb4"]]), Li = ["aria-current", "title"], wi = {
2599
+ class: "ds-menu-item__icon material-icons",
2600
+ "aria-hidden": "true"
2601
+ }, Ii = {
2602
+ key: 0,
2603
+ class: "ds-menu-item__label"
2604
+ }, Ci = /* @__PURE__ */ x({
2605
+ __name: "DsMenuItem",
2606
+ props: {
2607
+ // Material Icons ligature name (rendered via <i class="material-icons">).
2608
+ icon: { type: String, required: !0 },
2609
+ // Row label; a default slot overrides it. Hidden (not removed) when collapsed.
2610
+ text: { type: String, default: "" },
2611
+ // Current row: white surface + tint border, aria-current="page".
2612
+ active: Boolean,
2613
+ // Icon-only collapsed rail.
2614
+ collapsed: Boolean
2615
+ },
2616
+ emits: [Ge],
2617
+ setup(e, { emit: n }) {
2618
+ const t = n;
2619
+ function o(i) {
2620
+ t(Ge, i);
2621
+ }
2622
+ return (i, c) => (a(), l("button", {
2623
+ type: "button",
2624
+ class: $(["ds-menu-item", { "is-active": e.active, "is-collapsed": e.collapsed }]),
2625
+ "aria-current": e.active ? "page" : void 0,
2626
+ title: e.text || void 0,
2627
+ onClick: o
2628
+ }, [
2629
+ s("i", wi, S(e.icon), 1),
2630
+ e.text || i.$slots.default ? (a(), l("span", Ii, [
2631
+ A(i.$slots, "default", {}, () => [
2632
+ H(S(e.text), 1)
2633
+ ], !0)
2634
+ ])) : m("", !0)
2635
+ ], 10, Li));
2636
+ }
2637
+ }), ln = /* @__PURE__ */ M(Ci, [["__scopeId", "data-v-0fe17e63"]]), se = {
2638
+ ACTIVE: "active",
2639
+ // current step — accent-tint chip, filled marker
2640
+ COMPLETED: "completed",
2641
+ // done — filled accent marker
2642
+ INCOMPLETE: "incomplete",
2643
+ // visited but unfinished — red "!" chip
2644
+ NEUTRAL: "neutral"
2645
+ // upcoming — outlined marker
2646
+ }, _i = { class: "ds-wizard-stepper" }, Di = { class: "ds-wizard-stepper__steps" }, Ai = {
2647
+ class: "ds-wizard-step__marker",
2648
+ "aria-hidden": "true"
2649
+ }, Ni = { class: "ds-wizard-step__label" }, Ri = /* @__PURE__ */ x({
2650
+ __name: "DsWizardStepper",
2651
+ props: {
2652
+ steps: { type: Array, default: () => [] },
2653
+ // Current step (1-based).
2654
+ value: { type: Number, default: 1 },
2655
+ // Button labels — consumer-owned copy (no hardcoded text in the library).
2656
+ nextLabel: { type: String, default: "" },
2657
+ finalStepLabel: { type: String, default: "" },
2658
+ // Whether the step chips are interactive (advance buttons are always active).
2659
+ clickable: { type: Boolean, default: !0 }
2660
+ },
2661
+ emits: [De, He],
2662
+ setup(e, { emit: n }) {
2663
+ const t = e, o = n, i = g(() => t.value === t.steps.length), c = g(
2664
+ () => t.steps.map((r, d) => {
2665
+ var T;
2666
+ const b = d + 1;
2667
+ let h;
2668
+ return b === t.value ? h = se.ACTIVE : r.completed ? h = se.COMPLETED : r.visited ? h = se.INCOMPLETE : b < t.value ? h = se.COMPLETED : h = se.NEUTRAL, {
2669
+ key: (T = r.key) != null ? T : b,
2670
+ index: b,
2671
+ label: r.label,
2672
+ state: h,
2673
+ current: h === se.ACTIVE,
2674
+ marker: h === se.INCOMPLETE ? "!" : String(b)
2675
+ };
2676
+ })
2677
+ );
2678
+ function k(r) {
2679
+ t.clickable && o(De, r);
2680
+ }
2681
+ function f() {
2682
+ t.value < t.steps.length && o(De, t.value + 1);
2683
+ }
2684
+ function y() {
2685
+ o(He);
2686
+ }
2687
+ return (r, d) => (a(), l("div", _i, [
2688
+ s("ol", Di, [
2689
+ (a(!0), l(z, null, Y(c.value, (b) => (a(), l("li", {
2690
+ key: b.key,
2691
+ class: "ds-wizard-stepper__item"
2692
+ }, [
2693
+ (a(), G(ft(e.clickable ? "button" : "div"), {
2694
+ type: e.clickable ? "button" : void 0,
2695
+ class: $(["ds-wizard-step", [`ds-wizard-step--${b.state}`, { "is-clickable": e.clickable }]]),
2696
+ "aria-current": b.current ? "step" : void 0,
2697
+ onClick: (h) => k(b.index)
2698
+ }, {
2699
+ default: ie(() => [
2700
+ s("span", Ai, S(b.marker), 1),
2701
+ s("span", Ni, S(b.label), 1)
2702
+ ]),
2703
+ _: 2
2704
+ }, 1032, ["type", "class", "aria-current", "onClick"]))
2705
+ ]))), 128))
2706
+ ]),
2707
+ !i.value && e.nextLabel ? (a(), G(_(oe), {
2708
+ key: 0,
2709
+ variant: "primary",
2710
+ size: "large",
2711
+ "right-icon": "keyboard_arrow_right",
2712
+ onClick: f
2713
+ }, {
2714
+ default: ie(() => [
2715
+ H(S(e.nextLabel), 1)
2716
+ ]),
2717
+ _: 1
2718
+ })) : m("", !0),
2719
+ i.value && e.finalStepLabel ? (a(), G(_(oe), {
2720
+ key: 1,
2721
+ variant: "primary",
2722
+ size: "large",
2723
+ onClick: y
2724
+ }, {
2725
+ default: ie(() => [
2726
+ H(S(e.finalStepLabel), 1)
2727
+ ]),
2728
+ _: 1
2729
+ })) : m("", !0)
2730
+ ]));
1109
2731
  }
1110
- }), ca = /* @__PURE__ */ $(Jt, [["__scopeId", "data-v-86467226"]]);
2732
+ }), nn = /* @__PURE__ */ M(Ri, [["__scopeId", "data-v-d6f1e6d7"]]);
1111
2733
  export {
1112
- ot as DS_ALERT_EFFECTS,
1113
- st as DS_ALERT_ICONS,
1114
- nt as DS_ALERT_TYPES,
1115
- H as DS_BADGE_TONES,
1116
- ke as DS_BUTTON_NATIVE_TYPES,
1117
- ee as DS_BUTTON_SIZES,
1118
- J as DS_BUTTON_VARIANTS,
1119
- Ge as DS_INPUT_SIZES,
1120
- P as DS_INPUT_TYPES,
1121
- bt as DS_NOTIFICATION_ICONS,
1122
- vt as DS_NOTIFICATION_POSITIONS,
1123
- yt as DS_NOTIFICATION_TYPES,
1124
- Y as DS_SPINNER_TONES,
1125
- te as DS_TABLE_ALIGN,
1126
- we as DS_TAG_TONES,
1127
- G as DS_VERIFICATION_STATES,
1128
- sa as DsAlert,
1129
- aa as DsAvatar,
1130
- Ae as DsBadge,
1131
- K as DsButton,
1132
- oa as DsCheckbox,
1133
- ae as DsContactValue,
1134
- ca as DsDataCard,
1135
- ia as DsInput,
1136
- ra as DsModal,
1137
- da as DsNotification,
1138
- Se as DsSpinner,
1139
- la as DsTable,
1140
- ta as DsTag,
1141
- na as DsTextarea,
1142
- Bt as DsVerificationIcon
2734
+ fa as DS_ALERT_EFFECTS,
2735
+ ba as DS_ALERT_ICONS,
2736
+ ua as DS_ALERT_TYPES,
2737
+ Re as DS_BADGE_TONES,
2738
+ yt as DS_BUTTON_NATIVE_TYPES,
2739
+ Ke as DS_BUTTON_SIZES,
2740
+ Ae as DS_BUTTON_VARIANTS,
2741
+ Kl as DS_CUSTOM_TAG_TYPES,
2742
+ Zt as DS_INPUT_SIZES,
2743
+ ce as DS_INPUT_TYPES,
2744
+ pa as DS_NOTIFICATION_ICONS,
2745
+ qe as DS_NOTIFICATION_LINK_TARGETS,
2746
+ ka as DS_NOTIFICATION_POSITIONS,
2747
+ Sa as DS_NOTIFICATION_TYPES,
2748
+ Xe as DS_SELECT_TYPES,
2749
+ Ze as DS_SELECT_WIDTHS,
2750
+ Ce as DS_SPINNER_SIZES,
2751
+ ge as DS_SPINNER_TONES,
2752
+ Ye as DS_TABLE_ALIGN,
2753
+ ee as DS_TABLE_PIN,
2754
+ Et as DS_TAG_TONES,
2755
+ xa as DS_TOOLTIP_PLACEMENTS,
2756
+ Ne as DS_VERIFICATION_STATES,
2757
+ se as DS_WIZARD_STEP_STATES,
2758
+ zi as DsAlert,
2759
+ Mi as DsAvatar,
2760
+ _t as DsBadge,
2761
+ oe as DsButton,
2762
+ Xi as DsCell,
2763
+ et as DsCheckbox,
2764
+ je as DsContactValue,
2765
+ Zi as DsCustomTag,
2766
+ Hi as DsDataCard,
2767
+ tn as DsEmptyState,
2768
+ Pi as DsInput,
2769
+ Yi as DsItemSelectorButton,
2770
+ ln as DsMenuItem,
2771
+ Ui as DsModal,
2772
+ Vi as DsNotification,
2773
+ an as DsPaginator,
2774
+ Qi as DsPill,
2775
+ Ji as DsPillWithBorder,
2776
+ Wi as DsRadio,
2777
+ ji as DsRow,
2778
+ en as DsSegmentedProgressBar,
2779
+ qi as DsSelect,
2780
+ fe as DsSpinner,
2781
+ Ki as DsSwitch,
2782
+ Oi as DsTable,
2783
+ xi as DsTag,
2784
+ Fi as DsTextarea,
2785
+ Gi as DsTooltip,
2786
+ za as DsVerificationIcon,
2787
+ nn as DsWizardStepper
1143
2788
  };
1144
2789
  //# sourceMappingURL=index.es.js.map