@salesql/sql_components_vue3 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +37 -1
  2. package/dist/constants/events.d.ts +20 -0
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.ts +40 -6
  6. package/dist/index.es.js +2205 -618
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/sql_components_vue3.css +1 -1
  9. package/dist/ui/DsAlert/DsAlert.vue.d.ts +15 -2
  10. package/dist/ui/DsAvatar/DsAvatar.types.d.ts +6 -0
  11. package/dist/ui/DsAvatar/DsAvatar.vue.d.ts +47 -2
  12. package/dist/ui/DsButton/DsButton.types.d.ts +3 -1
  13. package/dist/ui/DsButton/DsButton.vue.d.ts +3 -0
  14. package/dist/ui/DsCell/DsCell.types.d.ts +19 -0
  15. package/dist/ui/DsCell/DsCell.vue.d.ts +71 -0
  16. package/dist/ui/DsCell/index.d.ts +2 -0
  17. package/dist/ui/DsCheckbox/DsCheckbox.types.d.ts +2 -0
  18. package/dist/ui/DsCheckbox/DsCheckbox.vue.d.ts +10 -1
  19. package/dist/ui/DsContactValue/DsContactValue.types.d.ts +4 -0
  20. package/dist/ui/DsContactValue/DsContactValue.vue.d.ts +18 -0
  21. package/dist/ui/DsCustomTag/DsCustomTag.types.d.ts +9 -0
  22. package/dist/ui/DsCustomTag/DsCustomTag.vue.d.ts +29 -0
  23. package/dist/ui/DsCustomTag/index.d.ts +2 -0
  24. package/dist/ui/DsDataCard/DsDataCard.types.d.ts +2 -0
  25. package/dist/ui/DsDataCard/DsDataCard.vue.d.ts +58 -1
  26. package/dist/ui/DsEmptyState/DsEmptyState.types.d.ts +12 -0
  27. package/dist/ui/DsEmptyState/DsEmptyState.vue.d.ts +53 -0
  28. package/dist/ui/DsEmptyState/index.d.ts +2 -0
  29. package/dist/ui/DsInput/DsInput.vue.d.ts +36 -2
  30. package/dist/ui/DsItemSelectorButton/DsItemSelectorButton.types.d.ts +20 -0
  31. package/dist/ui/DsItemSelectorButton/DsItemSelectorButton.vue.d.ts +50 -0
  32. package/dist/ui/DsItemSelectorButton/index.d.ts +2 -0
  33. package/dist/ui/DsMenuItem/DsMenuItem.types.d.ts +6 -0
  34. package/dist/ui/DsMenuItem/DsMenuItem.vue.d.ts +42 -0
  35. package/dist/ui/DsMenuItem/index.d.ts +2 -0
  36. package/dist/ui/DsModal/DsModal.types.d.ts +10 -0
  37. package/dist/ui/DsModal/DsModal.vue.d.ts +39 -0
  38. package/dist/ui/DsNotification/DsNotification.types.d.ts +7 -0
  39. package/dist/ui/DsNotification/DsNotification.vue.d.ts +14 -3
  40. package/dist/ui/DsPaginator/DsPaginator.types.d.ts +12 -0
  41. package/dist/ui/DsPaginator/DsPaginator.vue.d.ts +101 -0
  42. package/dist/ui/DsPaginator/index.d.ts +2 -0
  43. package/dist/ui/DsPill/DsPill.types.d.ts +11 -0
  44. package/dist/ui/DsPill/DsPill.vue.d.ts +46 -0
  45. package/dist/ui/DsPill/index.d.ts +2 -0
  46. package/dist/ui/DsPillWithBorder/DsPillWithBorder.types.d.ts +2 -0
  47. package/dist/ui/DsPillWithBorder/DsPillWithBorder.vue.d.ts +18 -0
  48. package/dist/ui/DsPillWithBorder/index.d.ts +2 -0
  49. package/dist/ui/DsRadio/DsRadio.types.d.ts +7 -0
  50. package/dist/ui/DsRadio/DsRadio.vue.d.ts +55 -0
  51. package/dist/ui/DsRadio/index.d.ts +2 -0
  52. package/dist/ui/DsRow/DsRow.types.d.ts +6 -0
  53. package/dist/ui/DsRow/DsRow.vue.d.ts +37 -0
  54. package/dist/ui/DsRow/index.d.ts +2 -0
  55. package/dist/ui/DsSegmentedProgressBar/DsSegmentedProgressBar.types.d.ts +5 -0
  56. package/dist/ui/DsSegmentedProgressBar/DsSegmentedProgressBar.vue.d.ts +62 -0
  57. package/dist/ui/DsSegmentedProgressBar/index.d.ts +2 -0
  58. package/dist/ui/DsSelect/DsSelect.types.d.ts +33 -0
  59. package/dist/ui/DsSelect/DsSelect.vue.d.ts +126 -0
  60. package/dist/ui/DsSelect/index.d.ts +2 -0
  61. package/dist/ui/DsSpinner/DsSpinner.types.d.ts +6 -0
  62. package/dist/ui/DsSpinner/DsSpinner.vue.d.ts +4 -4
  63. package/dist/ui/DsSwitch/DsSwitch.types.d.ts +6 -0
  64. package/dist/ui/DsSwitch/DsSwitch.vue.d.ts +30 -0
  65. package/dist/ui/DsSwitch/index.d.ts +2 -0
  66. package/dist/ui/DsTable/DsTable.types.d.ts +11 -0
  67. package/dist/ui/DsTable/DsTable.vue.d.ts +103 -10
  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/llms-full.txt +1350 -0
  78. package/llms.txt +40 -0
  79. package/package.json +6 -3
package/dist/index.es.js CHANGED
@@ -1,37 +1,56 @@
1
- import { defineComponent as $, openBlock as t, createElementBlock as a, normalizeStyle as L, normalizeClass as m, computed as h, createBlock as D, unref as S, createCommentVNode as u, renderSlot as I, createElementVNode as d, toDisplayString as v, Fragment as A, renderList as V, createTextVNode as O, useModel as Q, useSlots as oe, ref as R, withDirectives as Z, vModelDynamic as ye, mergeModels as U, vModelText as ve, onMounted as se, watch as de, vModelCheckbox as be, onBeforeUnmount as j, Teleport as re, createVNode as p, Transition as ce, withCtx as J, nextTick as me, withModifiers as ue } from "vue";
2
- const W = {
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
- }, ge = ["aria-label"], he = /* @__PURE__ */ $({
9
+ }, Ce = {
10
+ SMALL: "small",
11
+ // 20px
12
+ MEDIUM: "medium",
13
+ // 32px
14
+ LARGE: "large"
15
+ // 48px
16
+ }, bt = ["aria-label"], vt = /* @__PURE__ */ x({
10
17
  __name: "DsSpinner",
11
18
  props: {
12
- 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 },
13
22
  tone: {
14
23
  type: String,
15
- default: W.DARK
24
+ default: ge.DARK
16
25
  },
17
26
  // Accessible name (DS default "Loading"); the consuming app can override for
18
27
  // i18n. role="status" + aria-label are always present, never opt-in.
19
28
  label: { type: String, default: "Loading" }
20
29
  },
21
30
  setup(e) {
22
- return (i, l) => (t(), a("span", {
23
- class: m(["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}`]),
24
43
  role: "status",
25
- style: L({ width: `${e.size}px`, height: `${e.size}px` }),
44
+ style: F({ width: `${o.value}px`, height: `${o.value}px` }),
26
45
  "aria-label": e.label || void 0
27
- }, null, 14, ge));
46
+ }, null, 14, bt));
28
47
  }
29
- }), T = (e, i) => {
30
- const l = e.__vccOpts || e;
31
- for (const [r, s] of i)
32
- l[r] = s;
33
- return l;
34
- }, Se = /* @__PURE__ */ T(he, [["__scopeId", "data-v-4d32b0a5"]]), ee = "click", C = "close", F = "focus", z = "blur", G = "copy", _ = "correct", P = "incorrect", te = "sort", ae = "edit", H = {
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 = {
35
54
  DEFAULT: "default",
36
55
  // white surface, dark text (the default value; == tertiary)
37
56
  PRIMARY: "primary",
@@ -41,14 +60,20 @@ const W = {
41
60
  TERTIARY: "tertiary",
42
61
  // white surface, dark text (low-emphasis row action)
43
62
  QUATERNARY: "quaternary",
44
- // accent text + accent-mid border on white
63
+ // accent text + accent-mid border on white (former "special")
45
64
  QUINARY: "quinary",
46
- // accent text on white, no border (link-style)
47
- WARNING: "warning",
48
- // solid red fill, white text destructive / delete
49
- DOTTED: "dotted"
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",
50
69
  // transparent, dashed border, 24px radius — "add" affordance
51
- }, ie = {
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 = {
52
77
  SMALL: "small",
53
78
  // 24px
54
79
  MEDIUM: "medium",
@@ -57,33 +82,33 @@ const W = {
57
82
  // 36px
58
83
  XLARGE: "xlarge"
59
84
  // 48px
60
- }, ke = {
85
+ }, yt = {
61
86
  BUTTON: "button",
62
87
  SUBMIT: "submit",
63
88
  RESET: "reset"
64
- }, $e = ["type", "disabled", "autofocus", "aria-busy", "aria-disabled", "aria-pressed", "aria-label"], Te = {
65
- key: 1,
89
+ }, mt = ["type", "disabled", "autofocus", "aria-busy", "aria-disabled", "aria-pressed", "aria-label"], ht = ["aria-hidden"], gt = {
90
+ key: 0,
66
91
  class: "ds-button__icon ds-button__icon--leading"
67
- }, Ie = {
92
+ }, St = {
68
93
  class: "material-icons",
69
94
  "aria-hidden": "true"
70
- }, Ce = {
71
- key: 2,
95
+ }, kt = {
96
+ key: 1,
72
97
  class: "ds-button__label"
73
- }, Ee = {
74
- key: 3,
98
+ }, pt = {
99
+ key: 2,
75
100
  class: "ds-button__icon ds-button__icon--trailing"
76
- }, we = {
101
+ }, $t = {
77
102
  class: "material-icons",
78
103
  "aria-hidden": "true"
79
- }, Le = /* @__PURE__ */ $({
104
+ }, Tt = /* @__PURE__ */ x({
80
105
  __name: "DsButton",
81
106
  props: {
82
- variant: { type: String, default: H.DEFAULT },
83
- size: { type: String, default: ie.MEDIUM },
107
+ variant: { type: String, default: Ae.DEFAULT },
108
+ size: { type: String, default: Ke.MEDIUM },
84
109
  nativeType: {
85
110
  type: String,
86
- default: ke.BUTTON
111
+ default: yt.BUTTON
87
112
  },
88
113
  // Material Icon names (rendered via <i class="material-icons">); a leading/
89
114
  // trailing slot overrides. Icon-only buttons (circle/square) need ariaLabel.
@@ -97,20 +122,23 @@ const W = {
97
122
  // Flat 4px-radius icon-only button (the DS `*-square` sizes): symmetric padding
98
123
  // per size, height === width.
99
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,
100
128
  // Toggle state: accent outline + fill; sets aria-pressed (DS `selected`).
101
129
  selected: Boolean,
102
130
  autofocus: Boolean
103
131
  },
104
- emits: [ee],
105
- setup(e, { emit: i }) {
106
- const l = e, r = i, s = h(() => l.size === ie.SMALL ? 14 : 20), n = h(
107
- () => l.variant === H.PRIMARY || l.variant === H.WARNING ? W.LIGHT : W.DARK
132
+ emits: [Z],
133
+ setup(e, { emit: n }) {
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
108
136
  );
109
- function o(c) {
110
- l.disabled || l.loading || r(ee, c);
137
+ function k(f) {
138
+ t.disabled || t.loading || o(Z, f);
111
139
  }
112
- return (c, b) => (t(), a("button", {
113
- class: m(["ds-button", [
140
+ return (f, y) => (a(), l("button", {
141
+ class: $(["ds-button", [
114
142
  `ds-button--${e.variant}`,
115
143
  `ds-button--${e.size}`,
116
144
  {
@@ -118,6 +146,7 @@ const W = {
118
146
  "is-loading": e.loading,
119
147
  "is-circle": e.circle,
120
148
  "is-square": e.square,
149
+ "is-no-padding": e.noPadding,
121
150
  "is-selected": e.selected
122
151
  }
123
152
  ]]),
@@ -128,30 +157,35 @@ const W = {
128
157
  "aria-disabled": e.disabled || e.loading || void 0,
129
158
  "aria-pressed": e.selected || void 0,
130
159
  "aria-label": e.ariaLabel || void 0,
131
- onClick: o
160
+ onClick: k
132
161
  }, [
133
- e.loading ? (t(), D(S(Se), {
162
+ e.loading ? (a(), G(_(fe), {
134
163
  key: 0,
135
164
  class: "ds-button__spinner",
136
- size: s.value,
137
- tone: n.value
138
- }, null, 8, ["size", "tone"])) : u("", !0),
139
- !e.loading && (e.leftIcon || c.$slots.leading) ? (t(), a("span", Te, [
140
- I(c.$slots, "leading", {}, () => [
141
- d("i", Ie, v(e.leftIcon), 1)
142
- ], !0)
143
- ])) : u("", !0),
144
- !e.loading && c.$slots.default ? (t(), a("span", Ce, [
145
- I(c.$slots, "default", {}, void 0, !0)
146
- ])) : u("", !0),
147
- !e.loading && (e.rightIcon || c.$slots.trailing) ? (t(), a("span", Ee, [
148
- I(c.$slots, "trailing", {}, () => [
149
- d("i", we, v(e.rightIcon), 1)
150
- ], !0)
151
- ])) : u("", !0)
152
- ], 10, $e));
165
+ size: i.value,
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));
153
187
  }
154
- }), K = /* @__PURE__ */ T(Le, [["__scopeId", "data-v-2d17382d"]]), De = {
188
+ }), oe = /* @__PURE__ */ M(Tt, [["__scopeId", "data-v-61354b19"]]), Et = {
155
189
  DEFAULT: "default",
156
190
  // white bg, slate-tint border, muted text
157
191
  GREY: "grey",
@@ -164,44 +198,58 @@ const W = {
164
198
  // e.g. Pending
165
199
  ERROR: "error"
166
200
  // e.g. Bounced
167
- }, Ne = ["aria-label"], Re = /* @__PURE__ */ $({
201
+ }, Lt = { class: "ds-tag__label" }, wt = ["aria-label"], It = /* @__PURE__ */ x({
168
202
  __name: "DsTag",
169
203
  props: {
170
204
  tone: {
171
205
  type: String,
172
- default: De.DEFAULT
206
+ default: Et.DEFAULT
173
207
  },
174
208
  // Semicircular sides (DS `rounded`): radius-round vs the default radius-control.
175
209
  rounded: Boolean,
176
210
  // Show a × close control that emits `close`.
177
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,
178
221
  // Accessible name for the × control (the app owns the wording / i18n).
179
222
  closeLabel: {
180
223
  type: String,
181
224
  default: ""
182
225
  }
183
226
  },
184
- setup(e, { emit: i }) {
185
- const l = i;
186
- return (r, s) => (t(), a("span", {
187
- class: m(["ds-tag", [`ds-tag--${e.tone}`, { "is-rounded": e.rounded }]])
227
+ setup(e, { emit: n }) {
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
+ ]])
188
234
  }, [
189
- I(r.$slots, "default", {}, void 0, !0),
190
- e.closable ? (t(), a("button", {
235
+ s("span", Lt, [
236
+ A(o.$slots, "default", {}, void 0, !0)
237
+ ]),
238
+ e.closable ? (a(), l("button", {
191
239
  key: 0,
192
240
  type: "button",
193
241
  class: "ds-tag__close",
194
242
  "aria-label": e.closeLabel || void 0,
195
- onClick: s[0] || (s[0] = (n) => l(S(C)))
196
- }, [...s[1] || (s[1] = [
197
- d("i", {
243
+ onClick: i[0] || (i[0] = ve((c) => t(_(X)), ["stop"]))
244
+ }, [...i[1] || (i[1] = [
245
+ s("i", {
198
246
  class: "material-icons",
199
247
  "aria-hidden": "true"
200
248
  }, "close", -1)
201
- ])], 8, Ne)) : u("", !0)
249
+ ])], 8, wt)) : m("", !0)
202
250
  ], 2));
203
251
  }
204
- }), ea = /* @__PURE__ */ T(Re, [["__scopeId", "data-v-fc383bb9"]]), X = {
252
+ }), xi = /* @__PURE__ */ M(It, [["__scopeId", "data-v-0540d9b3"]]), Re = {
205
253
  ACCENT: "accent",
206
254
  // e.g. Work (purple)
207
255
  GREY: "grey",
@@ -214,82 +262,193 @@ const W = {
214
262
  // coral
215
263
  WARNING: "warning"
216
264
  // orange
217
- }, Be = /* @__PURE__ */ $({
265
+ }, Ct = /* @__PURE__ */ x({
218
266
  __name: "DsBadge",
219
267
  props: {
220
268
  tone: {
221
269
  type: String,
222
- default: X.ACCENT
270
+ default: Re.ACCENT
223
271
  }
224
272
  },
225
273
  setup(e) {
226
- return (i, l) => (t(), a("span", {
227
- class: m(["ds-badge", `ds-badge--${e.tone}`])
274
+ return (n, t) => (a(), l("span", {
275
+ class: $(["ds-badge", `ds-badge--${e.tone}`])
228
276
  }, [
229
- I(i.$slots, "default", {}, void 0, !0)
277
+ A(n.$slots, "default", {}, void 0, !0)
230
278
  ], 2));
231
279
  }
232
- }), Ae = /* @__PURE__ */ T(Be, [["__scopeId", "data-v-f10a17a0"]]), Oe = ["src", "alt"], xe = ["aria-label"], Me = /* @__PURE__ */ $({
280
+ }), _t = /* @__PURE__ */ M(Ct, [["__scopeId", "data-v-f10a17a0"]]), Dt = ["src", "alt"], At = ["aria-label"], Nt = /* @__PURE__ */ x({
233
281
  __name: "DsAvatar",
234
282
  props: {
235
283
  image: { type: String, default: "" },
236
284
  firstName: { type: String, default: "" },
237
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: "" },
238
290
  uid: { type: String, default: "" },
239
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 },
240
299
  circular: Boolean,
241
- // Accessible label (defaults to "firstName lastName").
242
- 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 }
243
304
  },
244
305
  setup(e) {
245
- const i = e, l = h(
246
- () => i.firstName && i.lastName ? (i.firstName.charAt(0) + i.lastName.charAt(0)).toUpperCase() : ""
247
- ), r = h(() => i.alt || `${i.firstName} ${i.lastName}`.trim()), s = h(() => ({ width: `${i.size}px`, height: `${i.size}px` })), n = h(() => {
248
- const o = i.uid || i.firstName + i.lastName;
249
- let c = 0;
250
- for (let f = 0; f < o.length; f++)
251
- c = o.charCodeAt(f) + ((c << 5) - c), c = c & c;
252
- const b = [0, 0, 0];
253
- for (let f = 0; f < 3; f++) b[f] = c >> f * 8 & 255;
254
- const y = b[0] >= 200 && b[1] >= 200 && b[2] >= 200;
255
- return { bg: `rgb(${b[0]}, ${b[1]}, ${b[2]})`, fg: y ? "#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" };
256
329
  });
257
- return (o, c) => e.image ? (t(), a("img", {
330
+ return (d, b) => e.image ? (a(), l("img", {
258
331
  key: 0,
259
- class: m(["ds-avatar", { "is-circular": e.circular }]),
332
+ class: $(["ds-avatar", { "is-circular": e.circular }]),
260
333
  src: e.image,
261
- alt: e.alt,
262
- style: L(s.value)
263
- }, null, 14, Oe)) : l.value ? (t(), a("div", {
334
+ alt: i.value,
335
+ style: F(f.value)
336
+ }, null, 14, Dt)) : t.value ? (a(), l("div", {
264
337
  key: 1,
265
- class: m(["ds-avatar ds-avatar--initials", { "is-circular": e.circular }]),
338
+ class: $(["ds-avatar ds-avatar--initials", { "is-circular": e.circular }]),
266
339
  role: "img",
267
- "aria-label": r.value || void 0,
268
- style: L([
269
- s.value,
270
- { background: n.value.bg, color: n.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
+ }
271
349
  ])
272
- }, v(l.value), 15, xe)) : (t(), a("div", {
350
+ }, S(t.value), 15, At)) : (a(), l("div", {
273
351
  key: 2,
274
- class: m(["ds-avatar ds-avatar--placeholder", { "is-circular": e.circular }]),
275
- style: L(s.value),
352
+ class: $(["ds-avatar ds-avatar--placeholder", { "is-circular": e.circular }]),
353
+ style: F(f.value),
276
354
  "aria-hidden": "true"
277
355
  }, null, 6));
278
356
  }
279
- }), ta = /* @__PURE__ */ T(Me, [["__scopeId", "data-v-e965ed47"]]), le = {
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 = {
280
432
  LEFT: "left",
281
433
  CENTER: "center",
282
434
  RIGHT: "right"
283
- }, Ue = { class: "ds-table" }, Ve = { class: "ds-table__wrapper" }, Fe = { key: 0 }, ze = ["colspan"], Ge = /* @__PURE__ */ $({
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({
284
442
  __name: "DsTable",
285
443
  props: {
444
+ // --- Declarative API (default): the table builds itself from columns + rows. ---
286
445
  columns: {
287
446
  type: Array,
288
- required: !0
447
+ default: () => []
289
448
  },
290
449
  rows: {
291
450
  type: Array,
292
- required: !0
451
+ default: () => []
293
452
  },
294
453
  emptyMessage: {
295
454
  type: String,
@@ -306,67 +465,259 @@ const W = {
306
465
  rowHeight: {
307
466
  type: [String, Number],
308
467
  default: null
309
- }
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: "" }
310
495
  },
311
- setup(e) {
312
- const i = e, l = h(
313
- () => i.rowHeight == null ? void 0 : {
314
- "--ds-table-row-height": typeof i.rowHeight == "number" ? `${i.rowHeight}px` : i.rowHeight
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
315
503
  }
504
+ ), k = g(
505
+ () => t.height == null ? void 0 : { height: typeof t.height == "number" ? `${t.height}px` : t.height }
316
506
  );
317
- return (r, s) => (t(), a("div", Ue, [
318
- d("div", Ve, [
319
- d("table", {
320
- class: m(["ds-table__table", { "has-row-height": e.rowHeight != null }]),
321
- style: L(l.value)
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)
322
654
  }, [
323
- d("thead", null, [
324
- d("tr", null, [
325
- (t(!0), a(A, null, V(e.columns, (n) => {
326
- var o;
327
- return t(), a("th", {
328
- key: n.key,
329
- class: m(`ds-table__th--${(o = n.align) != null ? o : S(le).LEFT}`),
330
- style: L(n.width ? { width: n.width } : void 0)
331
- }, v(n.label), 7);
655
+ s("thead", null, [
656
+ s("tr", null, [
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);
332
667
  }), 128))
333
668
  ])
334
669
  ]),
335
- d("tbody", null, [
336
- e.rows.length === 0 ? (t(), a("tr", Fe, [
337
- d("td", {
670
+ s("tbody", null, [
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, [
684
+ s("td", {
338
685
  class: "ds-table__empty",
339
- colspan: e.columns.length,
686
+ colspan: Math.max(1, e.columns.length),
340
687
  "data-testid": "ds-table-empty"
341
688
  }, [
342
- I(r.$slots, "empty", {}, () => [
343
- O(v(e.emptyMessage), 1)
689
+ A(v.$slots, "empty", {}, () => [
690
+ H(S(e.emptyMessage), 1)
344
691
  ], !0)
345
- ], 8, ze)
346
- ])) : u("", !0),
347
- (t(!0), a(A, null, V(e.rows, (n) => (t(), a("tr", {
348
- key: n.id,
349
- class: m({ "is-highlighted": n.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 }),
350
696
  "data-testid": "ds-table-row"
351
697
  }, [
352
- (t(!0), a(A, null, V(e.columns, (o) => {
353
- var c;
354
- return t(), a("td", {
355
- key: o.key,
356
- class: m(`ds-table__td--${(c = o.align) != null ? c : S(le).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
357
708
  }, [
358
- I(r.$slots, `cell-${o.key}`, { row: n }, () => [
359
- O(v(n[o.key]), 1)
709
+ A(v.$slots, `cell-${I.key}`, { row: w }, () => [
710
+ H(S(w[I.key]), 1)
360
711
  ], !0)
361
- ], 2);
712
+ ], 14, jt);
362
713
  }), 128))
363
714
  ], 2))), 128))
364
715
  ])
365
716
  ], 6)
366
- ])
367
- ]));
717
+ ], 2)
718
+ ], 8, Ht));
368
719
  }
369
- }), aa = /* @__PURE__ */ T(Ge, [["__scopeId", "data-v-45342363"]]), Y = {
720
+ }), Oi = /* @__PURE__ */ M(Xt, [["__scopeId", "data-v-7a5bb12f"]]), ce = {
370
721
  TEXT: "text",
371
722
  EMAIL: "email",
372
723
  PASSWORD: "password",
@@ -374,26 +725,30 @@ const W = {
374
725
  NUMBER: "number",
375
726
  SEARCH: "search",
376
727
  URL: "url"
377
- }, _e = {
728
+ }, Zt = {
378
729
  SM: "sm",
379
730
  // 36px
380
731
  MD: "md"
381
732
  // 48px
382
- }, Pe = { class: "ds-input__wrap" }, pe = ["id", "type", "placeholder", "disabled", "name", "autocomplete", "aria-invalid", "aria-describedby"], He = {
733
+ }, Qt = { class: "ds-input__wrap" }, Jt = {
383
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,
384
739
  class: "ds-input__suffix"
385
- }, Ye = {
740
+ }, aa = {
386
741
  key: 0,
387
742
  class: "material-icons ds-input__error-icon",
388
743
  "aria-hidden": "true"
389
- }, qe = ["aria-label", "aria-pressed"], We = {
744
+ }, la = ["disabled", "aria-label", "aria-pressed"], ia = {
390
745
  class: "material-icons",
391
746
  "aria-hidden": "true"
392
- }, Ke = ["id"], Xe = /* @__PURE__ */ $({
747
+ }, na = ["id"], sa = /* @__PURE__ */ x({
393
748
  __name: "DsInput",
394
- props: /* @__PURE__ */ U({
395
- type: { type: String, default: Y.TEXT },
396
- size: { type: String, default: _e.SM },
749
+ props: /* @__PURE__ */ Q({
750
+ type: { type: String, default: ce.TEXT },
751
+ size: { type: String, default: Zt.SM },
397
752
  placeholder: { type: String, default: "" },
398
753
  disabled: Boolean,
399
754
  error: Boolean,
@@ -403,82 +758,134 @@ const W = {
403
758
  id: { type: String, default: "" },
404
759
  autocomplete: { type: String, default: "" },
405
760
  // Accessible name for the password visibility toggle.
406
- 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 }
407
767
  }, {
408
768
  modelValue: { default: "" },
409
769
  modelModifiers: {}
410
770
  }),
411
- emits: /* @__PURE__ */ U([F, z], ["update:modelValue"]),
412
- setup(e, { emit: i }) {
413
- const l = Q(e, "modelValue"), r = e, s = i, n = oe(), o = R(!1), c = h(() => r.type === Y.PASSWORD), b = h(
414
- () => c.value && o.value ? Y.TEXT : r.type
415
- ), y = h(
416
- () => !!n.suffix || r.error && r.showErrorIcon || c.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
417
784
  );
418
- return (f, g) => (t(), a("div", {
419
- class: m(["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
420
807
  }, [
421
- d("div", Pe, [
422
- Z(d("input", {
808
+ s("div", Qt, [
809
+ h.value ? (a(), l("i", Jt, "search")) : m("", !0),
810
+ Be(s("input", {
423
811
  id: e.id || void 0,
424
- "onUpdate:modelValue": g[0] || (g[0] = (k) => l.value = k),
425
- class: m(["ds-input__control", { "has-suffix": y.value }]),
426
- 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,
427
817
  placeholder: e.placeholder,
818
+ min: e.min,
819
+ max: e.max,
820
+ step: e.step,
428
821
  disabled: e.disabled,
429
822
  name: e.name || void 0,
430
823
  autocomplete: e.autocomplete || void 0,
431
824
  "aria-invalid": e.error || void 0,
432
825
  "aria-describedby": e.error && e.errorMessage && e.id ? `${e.id}-error` : void 0,
433
- onFocus: g[1] || (g[1] = (k) => s(S(F), k)),
434
- onBlur: g[2] || (g[2] = (k) => s(S(z), k))
435
- }, null, 42, pe), [
436
- [ye, l.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]
437
831
  ]),
438
- y.value ? (t(), a("div", He, [
439
- I(f.$slots, "suffix", {}, void 0, !0),
440
- e.error && e.showErrorIcon ? (t(), a("i", Ye, "warning")) : c.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", {
441
835
  key: 1,
442
836
  type: "button",
443
837
  class: "ds-input__toggle",
838
+ disabled: e.disabled,
444
839
  "aria-label": e.toggleLabel || void 0,
445
- "aria-pressed": o.value,
446
- onClick: g[3] || (g[3] = (k) => o.value = !o.value)
840
+ "aria-pressed": r.value,
841
+ onClick: d
447
842
  }, [
448
- d("i", We, v(o.value ? "visibility" : "visibility_off"), 1)
449
- ], 8, qe)) : u("", !0)
450
- ])) : u("", !0)
843
+ s("i", ia, S(r.value ? "visibility" : "visibility_off"), 1)
844
+ ], 8, la)) : m("", !0)
845
+ ])) : m("", !0)
451
846
  ]),
452
- e.error && e.errorMessage ? (t(), a("p", {
847
+ e.error && e.errorMessage ? (a(), l("p", {
453
848
  key: 0,
454
849
  id: e.id ? `${e.id}-error` : void 0,
455
850
  class: "ds-input__error"
456
- }, v(e.errorMessage), 9, Ke)) : u("", !0)
457
- ], 2));
851
+ }, S(e.errorMessage), 9, na)) : m("", !0)
852
+ ], 34));
458
853
  }
459
- }), ia = /* @__PURE__ */ T(Xe, [["__scopeId", "data-v-fb36e573"]]), Qe = ["id", "placeholder", "rows", "disabled", "name", "aria-invalid", "aria-describedby"], Ze = ["id"], je = /* @__PURE__ */ $({
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,
460
858
  __name: "DsTextarea",
461
- props: /* @__PURE__ */ U({
859
+ props: /* @__PURE__ */ Q({
462
860
  placeholder: { type: String, default: "" },
463
861
  rows: { type: Number, default: 4 },
464
862
  disabled: Boolean,
465
863
  error: Boolean,
466
864
  errorMessage: { type: String, default: "" },
467
865
  name: { type: String, default: "" },
468
- 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
+ }
469
872
  }, {
470
873
  modelValue: { default: "" },
471
874
  modelModifiers: {}
472
875
  }),
473
- emits: /* @__PURE__ */ U([F, z], ["update:modelValue"]),
474
- setup(e, { emit: i }) {
475
- const l = Q(e, "modelValue"), r = i;
476
- return (s, n) => (t(), a("div", {
477
- class: m(["ds-textarea", { "is-error": e.error, "is-disabled": e.disabled }])
478
- }, [
479
- Z(d("textarea", {
876
+ emits: /* @__PURE__ */ Q([Se, ke], ["update:modelValue"]),
877
+ setup(e, { emit: n }) {
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, {
480
887
  id: e.id || void 0,
481
- "onUpdate:modelValue": n[0] || (n[0] = (o) => l.value = o),
888
+ "onUpdate:modelValue": r[0] || (r[0] = (d) => t.value = d),
482
889
  class: "ds-textarea__control",
483
890
  placeholder: e.placeholder,
484
891
  rows: e.rows,
@@ -486,372 +893,459 @@ const W = {
486
893
  name: e.name || void 0,
487
894
  "aria-invalid": e.error || void 0,
488
895
  "aria-describedby": e.error && e.errorMessage && e.id ? `${e.id}-error` : void 0,
489
- onFocus: n[1] || (n[1] = (o) => r(S(F), o)),
490
- onBlur: n[2] || (n[2] = (o) => r(S(z), o))
491
- }, null, 40, Qe), [
492
- [ve, l.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]
493
900
  ]),
494
- e.error && e.errorMessage ? (t(), a("p", {
901
+ e.error && e.errorMessage ? (a(), l("p", {
495
902
  key: 0,
496
903
  id: e.id ? `${e.id}-error` : void 0,
497
904
  class: "ds-textarea__error"
498
- }, v(e.errorMessage), 9, Ze)) : u("", !0)
499
- ], 2));
905
+ }, S(e.errorMessage), 9, ra)) : m("", !0)
906
+ ], 16));
500
907
  }
501
- }), la = /* @__PURE__ */ T(je, [["__scopeId", "data-v-54fc312a"]]), Je = ["disabled", "name"], et = {
502
- key: 0,
503
- class: "ds-checkbox__mark",
504
- viewBox: "0 0 16 16",
505
- fill: "none",
506
- stroke: "currentColor",
507
- "stroke-width": "2.5"
508
- }, tt = {
509
- key: 1,
510
- class: "ds-checkbox__mark",
511
- viewBox: "0 0 16 16",
512
- fill: "none",
513
- stroke: "currentColor",
514
- "stroke-width": "2.5"
515
- }, at = {
516
- key: 0,
517
- class: "ds-checkbox__label"
518
- }, it = /* @__PURE__ */ $({
519
- __name: "DsCheckbox",
520
- props: /* @__PURE__ */ U({
521
- indeterminate: Boolean,
522
- disabled: Boolean,
523
- name: { type: String, default: "" },
524
- // Label text (DS `label` prop); a default slot overrides it.
525
- label: { type: String, default: "" }
526
- }, {
527
- modelValue: { type: Boolean, default: !1 },
528
- modelModifiers: {}
529
- }),
530
- emits: ["update:modelValue"],
531
- setup(e) {
532
- const i = Q(e, "modelValue"), l = e, r = R(null);
533
- function s() {
534
- r.value && (r.value.indeterminate = l.indeterminate);
535
- }
536
- return se(s), de(() => l.indeterminate, s), (n, o) => (t(), a("label", {
537
- class: m(["ds-checkbox", { "is-disabled": e.disabled }])
538
- }, [
539
- Z(d("input", {
540
- ref_key: "inputRef",
541
- ref: r,
542
- "onUpdate:modelValue": o[0] || (o[0] = (c) => i.value = c),
543
- type: "checkbox",
544
- class: "ds-checkbox__native",
545
- disabled: e.disabled,
546
- name: e.name || void 0
547
- }, null, 8, Je), [
548
- [be, i.value]
549
- ]),
550
- d("span", {
551
- class: m(["ds-checkbox__box", { "is-active": i.value || e.indeterminate }]),
552
- "aria-hidden": "true"
553
- }, [
554
- e.indeterminate ? (t(), a("svg", et, [...o[1] || (o[1] = [
555
- d("line", {
556
- x1: "4",
557
- y1: "8",
558
- x2: "12",
559
- y2: "8"
560
- }, null, -1)
561
- ])])) : i.value ? (t(), a("svg", tt, [...o[2] || (o[2] = [
562
- d("path", { d: "M3.5 8.5l3 3 6-6" }, null, -1)
563
- ])])) : u("", !0)
564
- ], 2),
565
- n.$slots.default || e.label ? (t(), a("span", at, [
566
- I(n.$slots, "default", {}, () => [
567
- O(v(e.label), 1)
568
- ], !0)
569
- ])) : u("", !0)
570
- ], 2));
571
- }
572
- }), na = /* @__PURE__ */ T(it, [["__scopeId", "data-v-8ccdf847"]]), lt = {
908
+ }), Fi = /* @__PURE__ */ M(ca, [["__scopeId", "data-v-745c01de"]]), ua = {
573
909
  SUCCESS: "success",
574
910
  INFO: "info",
575
911
  WARNING: "warning",
576
912
  ERROR: "error"
577
- }, nt = {
913
+ }, fa = {
578
914
  LIGHT: "light",
579
915
  // tinted: family tint bg + mid border + shadow text
580
916
  DARK: "dark"
581
917
  // solid: family shadow bg + white text
582
- }, ot = {
918
+ }, ba = {
583
919
  success: "check_circle",
584
920
  info: "info",
585
921
  warning: "warning",
586
922
  error: "error"
587
- }, st = {
923
+ }, va = {
588
924
  key: 0,
589
925
  class: "material-icons ds-alert__icon",
590
926
  "aria-hidden": "true"
591
- }, dt = { class: "ds-alert__content" }, rt = {
927
+ }, ya = { class: "ds-alert__content" }, ma = {
592
928
  key: 1,
593
929
  class: "ds-alert__body"
594
- }, ct = ["aria-label"], ut = /* @__PURE__ */ $({
930
+ }, ha = ["aria-label"], ga = /* @__PURE__ */ x({
595
931
  __name: "DsAlert",
596
- props: {
597
- type: { type: String, default: lt.INFO },
598
- effect: { type: String, default: nt.LIGHT },
932
+ props: /* @__PURE__ */ Q({
933
+ type: { type: String, default: ua.INFO },
934
+ effect: { type: String, default: fa.LIGHT },
599
935
  title: { type: String, default: "" },
600
936
  description: { type: String, default: "" },
601
937
  showIcon: Boolean,
602
938
  closable: Boolean,
603
939
  center: Boolean,
940
+ // Bold the title even without a body (DS: fontWeight = body || boldTitle ? 700 : 400).
941
+ boldTitle: Boolean,
604
942
  closeLabel: { type: String, default: "" }
605
- },
606
- emits: [C],
607
- setup(e, { emit: i }) {
608
- const l = e, r = i, s = oe(), n = R(!0), o = h(() => ot[l.type]), c = h(() => !!s.default || l.description.length > 0);
609
- function b() {
610
- n.value = !1, r(C);
943
+ }, {
944
+ visible: { type: Boolean, default: !0 },
945
+ visibleModifiers: {}
946
+ }),
947
+ emits: /* @__PURE__ */ Q([X], ["update:visible"]),
948
+ setup(e, { emit: n }) {
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);
611
952
  }
612
- return (y, f) => n.value ? (t(), a("div", {
613
- key: 0,
614
- class: m(["ds-alert", [`ds-alert--${e.type}`, `ds-alert--${e.effect}`, { "is-center": e.center }]]),
615
- role: "alert"
616
- }, [
617
- e.showIcon ? (t(), a("i", st, v(o.value), 1)) : u("", !0),
618
- d("div", dt, [
619
- 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", {
620
956
  key: 0,
621
- class: m(["ds-alert__title", { "has-body": c.value }])
622
- }, v(e.title), 3)) : u("", !0),
623
- c.value ? (t(), a("div", rt, [
624
- I(y.$slots, "default", {}, () => [
625
- O(v(e.description), 1)
626
- ], !0)
627
- ])) : u("", !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)
628
989
  ]),
629
- e.closable ? (t(), a("button", {
630
- key: 1,
631
- type: "button",
632
- class: "ds-alert__close",
633
- "aria-label": e.closeLabel || void 0,
634
- onClick: b
635
- }, [...f[0] || (f[0] = [
636
- d("i", {
637
- class: "material-icons",
638
- "aria-hidden": "true"
639
- }, "close", -1)
640
- ])], 8, ct)) : u("", !0)
641
- ], 2)) : u("", !0);
990
+ _: 3
991
+ }));
642
992
  }
643
- }), oa = /* @__PURE__ */ T(ut, [["__scopeId", "data-v-03bbe700"]]), ft = {
993
+ }), zi = /* @__PURE__ */ M(ga, [["__scopeId", "data-v-9ced26d6"]]), Sa = {
644
994
  SUCCESS: "success",
645
995
  INFO: "info",
646
996
  WARNING: "warning",
647
997
  ERROR: "error"
648
- }, yt = {
998
+ }, ka = {
649
999
  TOP_LEFT: "top-left",
650
1000
  TOP_RIGHT: "top-right",
651
1001
  BOTTOM_LEFT: "bottom-left",
652
1002
  BOTTOM_RIGHT: "bottom-right"
653
- }, vt = {
1003
+ }, pa = {
654
1004
  success: "check_circle",
655
1005
  info: "mode_edit",
656
1006
  warning: "warning",
657
1007
  error: "error"
658
- }, bt = {
1008
+ }, qe = {
1009
+ BLANK: "_blank",
1010
+ SELF: "_self",
1011
+ PARENT: "_parent",
1012
+ TOP: "_top"
1013
+ }, $a = {
659
1014
  class: "material-icons ds-notification__icon",
660
1015
  "aria-hidden": "true"
661
- }, mt = { class: "ds-notification__content" }, gt = {
1016
+ }, Ta = { class: "ds-notification__content" }, Ea = {
662
1017
  key: 0,
663
1018
  class: "ds-notification__title"
664
- }, ht = {
1019
+ }, La = {
665
1020
  key: 1,
666
1021
  class: "ds-notification__desc"
667
- }, St = ["href"], kt = ["aria-label"], $t = /* @__PURE__ */ $({
1022
+ }, wa = ["href", "target", "rel"], Ia = ["aria-label"], Ca = /* @__PURE__ */ x({
668
1023
  __name: "DsNotification",
669
1024
  props: {
670
- type: { type: String, default: ft.INFO },
1025
+ type: { type: String, default: Sa.INFO },
671
1026
  position: {
672
1027
  type: String,
673
- default: yt.BOTTOM_LEFT
1028
+ default: ka.BOTTOM_LEFT
674
1029
  },
675
1030
  title: { type: String, default: "" },
676
1031
  description: { type: String, default: "" },
677
1032
  linkTitle: { type: String, default: "" },
678
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
+ },
679
1041
  showClose: { type: Boolean, default: !0 },
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.
680
1046
  closeLabel: { type: String, default: "" },
681
1047
  // Auto-dismiss delay in ms (DS default 3500). 0 disables it. The timer pauses
682
1048
  // while the pointer is over the card and resumes with the remaining time.
683
1049
  duration: { type: Number, default: 3500 }
684
1050
  },
685
- emits: [C],
686
- setup(e, { emit: i }) {
687
- const l = e, r = i, s = R(!0), n = h(() => vt[l.type]);
688
- let o, c = 0, b = l.duration;
689
- function y() {
690
- o && (clearTimeout(o), o = void 0);
1051
+ emits: [X, We],
1052
+ setup(e, { emit: n }) {
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);
691
1059
  }
692
- function f(x) {
693
- y(), !(l.duration <= 0 || !s.value) && (c = Date.now(), o = setTimeout(N, x));
1060
+ function b(C) {
1061
+ d(), !(t.duration <= 0 || !i.value) && (y = Date.now(), f = setTimeout(p, C));
694
1062
  }
695
- function g() {
696
- o && (b -= Date.now() - c, y());
1063
+ function h() {
1064
+ f && (r -= Date.now() - y, d());
697
1065
  }
698
- function k() {
699
- f(b > 0 ? b : l.duration);
1066
+ function T() {
1067
+ b(r > 0 ? r : t.duration);
700
1068
  }
701
- function N() {
702
- y(), s.value = !1, r(C);
1069
+ function p() {
1070
+ d(), i.value = !1, o(X);
703
1071
  }
704
- return se(() => f(l.duration)), j(y), (x, M) => (t(), D(re, { to: "body" }, [
705
- p(ce, {
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, {
706
1077
  name: "ds-notification",
707
1078
  appear: ""
708
1079
  }, {
709
- default: J(() => [
710
- s.value ? (t(), a("div", {
1080
+ default: ie(() => [
1081
+ i.value ? (a(), l("div", {
711
1082
  key: 0,
712
- class: m(["ds-notification", `ds-notification--${e.position}`])
1083
+ class: $(["ds-notification", `ds-notification--${e.position}`])
713
1084
  }, [
714
- d("div", {
715
- class: m(["ds-notification__card", `ds-notification__card--${e.type}`]),
1085
+ s("div", {
1086
+ class: $(["ds-notification__card", `ds-notification__card--${e.type}`]),
716
1087
  role: "alert",
717
- onMouseenter: g,
718
- onMouseleave: k
1088
+ onMouseenter: h,
1089
+ onMouseleave: T
719
1090
  }, [
720
- d("i", bt, v(n.value), 1),
721
- d("div", mt, [
722
- e.title ? (t(), a("span", gt, v(e.title), 1)) : u("", !0),
723
- e.description ? (t(), a("p", ht, v(e.description), 1)) : u("", !0),
724
- e.linkTitle ? (t(), a("a", {
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", {
725
1096
  key: 2,
726
1097
  class: "ds-notification__link",
727
1098
  href: e.link || void 0,
728
- target: "_blank",
729
- rel: "noreferrer"
730
- }, v(e.linkTitle), 9, St)) : u("", !0)
1099
+ target: e.linkTarget,
1100
+ rel: k.value,
1101
+ onClick: V
1102
+ }, S(e.linkTitle), 9, wa)) : m("", !0)
731
1103
  ]),
732
- e.showClose ? (t(), a("button", {
1104
+ e.showClose ? (a(), l("button", {
733
1105
  key: 0,
734
1106
  type: "button",
735
1107
  class: "ds-notification__close",
736
1108
  "aria-label": e.closeLabel || void 0,
737
- onClick: N
738
- }, [...M[0] || (M[0] = [
739
- d("i", {
1109
+ onClick: p
1110
+ }, [...E[0] || (E[0] = [
1111
+ s("i", {
740
1112
  class: "material-icons",
741
1113
  "aria-hidden": "true"
742
1114
  }, "close", -1)
743
- ])], 8, kt)) : u("", !0)
1115
+ ])], 8, Ia)) : m("", !0)
744
1116
  ], 34)
745
- ], 2)) : u("", !0)
1117
+ ], 2)) : m("", !0)
746
1118
  ]),
747
1119
  _: 1
748
1120
  })
749
1121
  ]));
750
1122
  }
751
- }), sa = /* @__PURE__ */ T($t, [["__scopeId", "data-v-dff620c6"]]), Tt = ["aria-label"], It = {
1123
+ }), Vi = /* @__PURE__ */ M(Ca, [["__scopeId", "data-v-f1d76da5"]]), _a = ["aria-modal", "aria-labelledby", "aria-label"], Da = {
752
1124
  key: 0,
753
1125
  class: "ds-modal__header"
754
- }, Ct = { class: "ds-modal__title" }, Et = { class: "ds-modal__body" }, wt = {
1126
+ }, Aa = ["id"], Na = { class: "ds-modal__body" }, Ra = {
755
1127
  key: 1,
756
1128
  class: "ds-modal__footer"
757
- }, Lt = /* @__PURE__ */ $({
1129
+ }, Ba = /* @__PURE__ */ x({
758
1130
  __name: "DsModal",
759
1131
  props: {
760
1132
  open: Boolean,
761
1133
  title: { type: String, default: "" },
762
1134
  showClose: { type: Boolean, default: !0 },
763
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 },
764
1144
  closeOnBackdrop: { type: Boolean, default: !0 },
765
- 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" }
766
1151
  },
767
- emits: [C],
768
- setup(e, { emit: i }) {
769
- const l = e, r = i, s = R(null);
770
- let n = null;
771
- function o() {
772
- l.closeOnBackdrop && r(C);
1152
+ emits: [X],
1153
+ setup(e, { emit: n }) {
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);
773
1162
  }
774
- function c() {
775
- return s.value ? Array.from(s.value.querySelectorAll('a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(
776
- (f) => f.offsetParent !== null
1163
+ function r() {
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(
1165
+ (p) => p.offsetParent !== null
777
1166
  ) : [];
778
1167
  }
779
- function b(y) {
780
- var N;
781
- if (y.key === "Escape") {
782
- r(C);
1168
+ function d(T) {
1169
+ var E;
1170
+ if (T.key === "Escape") {
1171
+ t.closeOnEscape && o(X);
783
1172
  return;
784
1173
  }
785
- if (y.key !== "Tab") return;
786
- const f = c();
787
- if (f.length === 0) {
788
- y.preventDefault(), (N = s.value) == null || N.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();
789
1178
  return;
790
1179
  }
791
- const g = f[0], k = f[f.length - 1];
792
- y.shiftKey && document.activeElement === g ? (y.preventDefault(), k.focus()) : !y.shiftKey && document.activeElement === k && (y.preventDefault(), g.focus());
793
- }
794
- return de(
795
- () => l.open,
796
- (y) => {
797
- var f;
798
- typeof document != "undefined" && (y ? (n = document.activeElement, document.addEventListener("keydown", b), document.body.style.overflow = "hidden", me(() => {
799
- var g, k;
800
- return (k = (g = c()[0]) != null ? g : s.value) == null ? void 0 : k.focus();
801
- })) : (document.removeEventListener("keydown", b), document.body.style.overflow = "", (f = n == null ? void 0 : n.focus) == null || f.call(n)));
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());
802
1197
  },
803
1198
  { immediate: !0 }
804
- ), j(() => {
805
- typeof document != "undefined" && (document.removeEventListener("keydown", b), document.body.style.overflow = "");
806
- }), (y, f) => (t(), D(re, { to: "body" }, [
807
- p(ce, { name: "ds-modal" }, {
808
- default: J(() => [
809
- e.open ? (t(), a("div", {
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", {
810
1208
  key: 0,
811
- class: "ds-modal",
812
- onClick: o
1209
+ class: $(["ds-modal", { "is-fixed": e.fixed }]),
1210
+ style: F(e.fixed ? { paddingTop: e.top } : void 0),
1211
+ onClick: y
813
1212
  }, [
814
- d("div", {
1213
+ s("div", {
815
1214
  ref_key: "dialogRef",
816
- ref: s,
817
- class: "ds-modal__dialog",
1215
+ ref: i,
1216
+ class: $(["ds-modal__dialog", { "is-center": e.center }]),
818
1217
  role: "dialog",
819
- "aria-modal": "true",
820
- "aria-label": e.title || "dialog",
1218
+ "aria-modal": e.fixed ? "true" : "false",
1219
+ "aria-labelledby": e.title ? _(k) : void 0,
1220
+ "aria-label": e.title ? void 0 : "dialog",
821
1221
  tabindex: "-1",
822
- style: L({ width: e.width }),
823
- onClick: f[1] || (f[1] = ue(() => {
1222
+ style: F(f.value),
1223
+ onClick: p[1] || (p[1] = ve(() => {
824
1224
  }, ["stop"]))
825
1225
  }, [
826
- e.title || e.showClose ? (t(), a("div", It, [
827
- d("span", Ct, v(e.title), 1),
828
- e.showClose ? (t(), D(S(K), {
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), {
829
1232
  key: 0,
830
1233
  variant: "tertiary",
831
1234
  circle: "",
832
1235
  "left-icon": "close",
833
1236
  "aria-label": e.closeLabel || void 0,
834
- onClick: f[0] || (f[0] = (g) => r(S(C)))
835
- }, null, 8, ["aria-label"])) : u("", !0)
836
- ])) : u("", !0),
837
- d("div", Et, [
838
- I(y.$slots, "default", {}, void 0, !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)
839
1242
  ]),
840
- y.$slots.footer ? (t(), a("div", wt, [
841
- I(y.$slots, "footer", {}, void 0, !0)
842
- ])) : u("", !0)
843
- ], 12, Tt)
844
- ])) : u("", !0)
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)
845
1248
  ]),
846
1249
  _: 3
847
1250
  })
848
- ]));
1251
+ ], 8, ["disabled"]));
849
1252
  }
850
- }), da = /* @__PURE__ */ T(Lt, [["__scopeId", "data-v-19866588"]]), q = {
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 = {
851
1345
  VERIFIED: "verified",
852
1346
  UNVERIFIED: "unverified",
853
1347
  NEW: "new"
854
- }, Dt = ["aria-label", "title"], Nt = /* @__PURE__ */ $({
1348
+ }, Pa = ["aria-label", "title"], Fa = /* @__PURE__ */ x({
855
1349
  __name: "DsVerificationIcon",
856
1350
  props: {
857
1351
  // true = verified · false = not verified · null/undefined = newly found.
@@ -876,38 +1370,38 @@ const W = {
876
1370
  }
877
1371
  },
878
1372
  setup(e) {
879
- const i = e, l = h(() => i.verified === null || i.verified === void 0 ? {
880
- state: q.NEW,
1373
+ const n = e, t = g(() => n.verified === null || n.verified === void 0 ? {
1374
+ state: Ne.NEW,
881
1375
  icon: "new_releases",
882
1376
  label: "Newly found"
883
- } : i.verified ? {
884
- state: q.VERIFIED,
1377
+ } : n.verified ? {
1378
+ state: Ne.VERIFIED,
885
1379
  icon: "verified",
886
1380
  label: "Verified"
887
1381
  } : {
888
- state: q.UNVERIFIED,
889
- icon: i.isContactData ? "dangerous" : "error",
1382
+ state: Ne.UNVERIFIED,
1383
+ icon: n.isContactData ? "dangerous" : "error",
890
1384
  label: "Not verified"
891
1385
  });
892
- return (r, s) => (t(), a("i", {
893
- class: m(["material-icons ds-verification-icon", [
894
- `ds-verification-icon--${l.value.state}`,
1386
+ return (o, i) => (a(), l("i", {
1387
+ class: $(["material-icons ds-verification-icon", [
1388
+ `ds-verification-icon--${t.value.state}`,
895
1389
  { "ds-verification-icon--email": e.isContactData }
896
1390
  ]]),
897
- style: L({ fontSize: `${e.size}px` }),
1391
+ style: F({ fontSize: `${e.size}px` }),
898
1392
  role: "img",
899
- "aria-label": e.label || l.value.label,
900
- title: e.label || l.value.label
1393
+ "aria-label": e.label || t.value.label,
1394
+ title: e.label || t.value.label
901
1395
  }, [
902
- I(r.$slots, "default", {}, () => [
903
- O(v(l.value.icon), 1)
1396
+ A(o.$slots, "default", {}, () => [
1397
+ H(S(t.value.icon), 1)
904
1398
  ], !0)
905
- ], 14, Dt));
1399
+ ], 14, Pa));
906
1400
  }
907
- }), Rt = /* @__PURE__ */ T(Nt, [["__scopeId", "data-v-0fd84040"]]), Bt = ["title"], At = { class: "ds-contact-value__marquee" }, Ot = { class: "ds-contact-value__actions" }, xt = ["aria-label", "title"], Mt = {
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 = {
908
1402
  class: "material-icons",
909
1403
  "aria-hidden": "true"
910
- }, Ut = ["aria-label", "aria-pressed", "title"], Vt = ["aria-label", "aria-pressed", "title"], Ft = /* @__PURE__ */ $({
1404
+ }, Ya = ["aria-label", "aria-pressed", "title"], qa = ["aria-label", "aria-pressed", "title"], ja = /* @__PURE__ */ x({
911
1405
  __name: "DsContactValue",
912
1406
  props: {
913
1407
  value: { type: String, required: !0 },
@@ -917,117 +1411,150 @@ const W = {
917
1411
  isContactData: { type: Boolean, default: !1 },
918
1412
  showRate: { type: Boolean, default: !1 },
919
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 },
920
1416
  // User-facing labels (the app owns i18n); English DS defaults.
921
1417
  copyLabel: { type: String, default: "Copy" },
922
1418
  copiedLabel: { type: String, default: "Copied!" },
923
1419
  correctLabel: { type: String, default: "Correct" },
924
- 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: "" }
925
1423
  },
926
- emits: [G, _, P],
927
- setup(e, { emit: i }) {
928
- const l = e, r = i, s = R(!1);
929
- let n;
930
- function o() {
931
- typeof navigator != "undefined" && navigator.clipboard && navigator.clipboard.writeText(l.value).catch(() => {
932
- }), s.value = !0, clearTimeout(n), n = setTimeout(() => {
933
- s.value = !1;
934
- }, 1200), r(G, l.value);
1424
+ emits: [pe, $e, Te],
1425
+ setup(e, { emit: n }) {
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(() => {
1431
+ i.value = !1;
1432
+ }, 1200), o(pe, t.value);
935
1433
  }
936
- function c() {
937
- r(_);
1434
+ function f() {
1435
+ o($e);
938
1436
  }
939
- function b() {
940
- r(P);
1437
+ function y() {
1438
+ o(Te);
941
1439
  }
942
- return j(() => clearTimeout(n)), (y, f) => (t(), a("div", {
943
- class: m(["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 }])
944
1442
  }, [
945
- p(S(Rt), {
1443
+ j(_(za), {
946
1444
  verified: e.verified,
947
1445
  "is-contact-data": e.isContactData
948
1446
  }, null, 8, ["verified", "is-contact-data"]),
949
- d("span", {
1447
+ s("span", {
950
1448
  class: "ds-contact-value__value",
951
1449
  title: e.value
952
- }, v(e.value), 9, Bt),
953
- d("span", At, [
954
- e.valueType ? (t(), D(S(Ae), {
1450
+ }, S(e.value), 9, Va),
1451
+ s("span", Ua, [
1452
+ e.valueType ? (a(), G(_(_t), {
955
1453
  key: 0,
956
1454
  class: "ds-contact-value__badge",
957
- tone: e.main ? S(X).ACCENT : S(X).GREY,
958
- "aria-hidden": "true"
1455
+ tone: e.main ? _(Re).ACCENT : _(Re).GREY,
1456
+ title: e.valueType
959
1457
  }, {
960
- default: J(() => [
961
- O(v(e.valueType), 1)
1458
+ default: ie(() => [
1459
+ H(S(e.valueType), 1)
962
1460
  ]),
963
1461
  _: 1
964
- }, 8, ["tone"])) : u("", !0),
965
- d("span", Ot, [
966
- d("button", {
967
- type: "button",
968
- class: m(["ds-contact-value__action", { "is-copied": s.value }]),
969
- "aria-label": s.value ? e.copiedLabel : e.copyLabel,
970
- title: s.value ? e.copiedLabel : e.copyLabel,
971
- onClick: o
972
- }, [
973
- d("i", Mt, v(s.value ? "check" : "content_copy"), 1)
974
- ], 10, xt),
975
- e.showRate ? (t(), a(A, { key: 0 }, [
976
- d("button", {
977
- type: "button",
978
- class: "ds-contact-value__action",
979
- "aria-label": e.correctLabel,
980
- "aria-pressed": e.correct === !0,
981
- title: e.correctLabel,
982
- onClick: c
983
- }, [
984
- d("i", {
985
- class: m(e.correct === !0 ? "material-icons" : "material-icons-outlined"),
986
- "aria-hidden": "true"
987
- }, "thumb_up", 2)
988
- ], 8, Ut),
989
- d("button", {
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 }, [
1471
+ s("button", {
990
1472
  type: "button",
991
- class: "ds-contact-value__action",
992
- "aria-label": e.incorrectLabel,
993
- "aria-pressed": e.correct === !1,
994
- title: e.incorrectLabel,
995
- 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
996
1477
  }, [
997
- d("i", {
998
- class: m(e.correct === !1 ? "material-icons" : "material-icons-outlined"),
999
- "aria-hidden": "true"
1000
- }, "thumb_down", 2)
1001
- ], 8, Vt)
1002
- ], 64)) : u("", !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))
1003
1509
  ])
1004
1510
  ])
1005
1511
  ], 2));
1006
1512
  }
1007
- }), ne = /* @__PURE__ */ T(Ft, [["__scopeId", "data-v-75a78ae2"]]), zt = ["aria-label"], Gt = { class: "ds-data-card__heading" }, _t = {
1513
+ }), je = /* @__PURE__ */ M(ja, [["__scopeId", "data-v-4f2d5d85"]]), Xa = ["aria-label", "aria-busy"], Za = { class: "ds-data-card__heading" }, Qa = {
1008
1514
  class: "material-icons ds-data-card__icon",
1009
1515
  "aria-hidden": "true"
1010
- }, Pt = { class: "ds-data-card__title" }, pt = ["aria-label"], Ht = {
1516
+ }, Ja = { class: "ds-data-card__title" }, el = ["aria-label"], tl = {
1011
1517
  key: 0,
1012
1518
  class: "ds-data-card__body"
1013
- }, Yt = {
1519
+ }, al = {
1014
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,
1015
1527
  class: "ds-data-card__empty"
1016
- }, qt = {
1017
- 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",
1018
1530
  "aria-hidden": "true"
1019
- }, Wt = { key: 0 }, Kt = {
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 = {
1020
1535
  key: 0,
1021
1536
  class: "ds-data-card__section"
1022
- }, Xt = { key: 1 }, Qt = {
1537
+ }, vl = { key: 1 }, yl = {
1023
1538
  key: 0,
1024
1539
  class: "ds-data-card__section"
1025
- }, Zt = { class: "ds-data-card__more" }, jt = /* @__PURE__ */ $({
1540
+ }, ml = { class: "ds-data-card__more" }, hl = /* @__PURE__ */ x({
1026
1541
  __name: "DsDataCard",
1027
1542
  props: {
1028
1543
  title: { type: String, required: !0 },
1029
1544
  // Material Icon name for the header (e.g. "email", "call").
1030
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 },
1031
1558
  mostLikely: { type: Object, default: null },
1032
1559
  more: { type: Array, default: () => [] },
1033
1560
  collapsible: { type: Boolean, default: !1 },
@@ -1039,164 +1566,1224 @@ const W = {
1039
1566
  // User-facing labels (the app owns i18n); English DS defaults.
1040
1567
  editLabel: { type: String, default: "Edit" },
1041
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" },
1042
1574
  mostLikelyLabel: { type: String, default: "MOST LIKELY" },
1043
1575
  moreLabel: { type: String, default: "MORE" },
1044
1576
  sortLabel: { type: String, default: "Sort" },
1045
1577
  toggleLabel: { type: String, default: "Toggle" },
1046
1578
  closeLabel: { type: String, default: "Close" }
1047
1579
  },
1048
- emits: [G, te, ae, C, _, P],
1049
- setup(e, { emit: i }) {
1050
- const l = e, r = i, s = R(!1), n = h(() => l.more.length + (l.mostLikely ? 1 : 0)), o = h(() => n.value > 3), c = h(() => n.value === 0), b = h(() => l.collapsible && s.value);
1051
- function y() {
1052
- s.value = !s.value;
1580
+ emits: [pe, Pe, Fe, X, $e, Te],
1581
+ setup(e, { emit: n }) {
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() {
1584
+ i.value = !i.value;
1053
1585
  }
1054
- function f(B) {
1055
- r(G, B);
1586
+ function d(C) {
1587
+ o(pe, C);
1056
1588
  }
1057
- function g() {
1058
- r(te);
1589
+ function b() {
1590
+ o(Pe);
1059
1591
  }
1060
- function k() {
1061
- r(ae);
1592
+ function h() {
1593
+ o(Fe);
1062
1594
  }
1063
- function N() {
1064
- r(C);
1595
+ function T() {
1596
+ o(X);
1065
1597
  }
1066
- function x(B) {
1067
- r(_, B);
1598
+ function p(C) {
1599
+ o($e, C);
1068
1600
  }
1069
- function M(B) {
1070
- r(P, B);
1601
+ function V(C) {
1602
+ o(Te, C);
1071
1603
  }
1072
- return (B, E) => (t(), a("section", {
1604
+ return (C, E) => (a(), l("section", {
1073
1605
  class: "ds-data-card",
1074
- "aria-label": e.title
1606
+ "aria-label": e.title,
1607
+ "aria-busy": e.loading ? "true" : void 0
1075
1608
  }, [
1076
- d("div", {
1077
- class: m(["ds-data-card__header", { "is-collapsed": b.value, "is-collapsible": e.collapsible }]),
1078
- onClick: E[1] || (E[1] = (w) => e.collapsible && y())
1609
+ s("div", {
1610
+ class: $(["ds-data-card__header", { "is-collapsed": y.value, "is-collapsible": e.collapsible }]),
1611
+ onClick: E[1] || (E[1] = (N) => e.collapsible && r())
1079
1612
  }, [
1080
- d("div", Gt, [
1081
- d("i", _t, v(e.icon), 1),
1082
- d("span", Pt, v(e.title), 1)
1613
+ s("div", Za, [
1614
+ s("i", Qa, S(e.icon), 1),
1615
+ s("span", Ja, S(e.title), 1)
1083
1616
  ]),
1084
- d("div", {
1617
+ s("div", {
1085
1618
  class: "ds-data-card__actions",
1086
- onClick: E[0] || (E[0] = ue(() => {
1619
+ onClick: E[0] || (E[0] = ve(() => {
1087
1620
  }, ["stop"]))
1088
1621
  }, [
1089
- !b.value && e.showEdit ? (t(), a("button", {
1622
+ !y.value && e.showEdit ? (a(), l("button", {
1090
1623
  key: 0,
1091
1624
  type: "button",
1092
1625
  class: "ds-data-card__edit",
1093
- onClick: k
1094
- }, v(e.editLabel), 1)) : u("", !0),
1095
- !b.value && e.showSort ? (t(), D(S(K), {
1626
+ onClick: h
1627
+ }, S(e.editLabel), 1)) : m("", !0),
1628
+ !y.value && e.showSort ? (a(), G(_(oe), {
1096
1629
  key: 1,
1097
1630
  variant: "tertiary",
1098
1631
  size: "medium",
1099
1632
  circle: "",
1100
1633
  "left-icon": "swap_vert",
1101
1634
  "aria-label": e.sortLabel,
1102
- onClick: g
1103
- }, null, 8, ["aria-label"])) : u("", !0),
1104
- e.collapsible ? (t(), D(S(K), {
1635
+ onClick: b
1636
+ }, null, 8, ["aria-label"])) : m("", !0),
1637
+ e.collapsible ? (a(), G(_(oe), {
1105
1638
  key: 2,
1106
1639
  variant: "tertiary",
1107
1640
  size: "medium",
1108
1641
  circle: "",
1109
- "left-icon": s.value ? "keyboard_arrow_down" : "keyboard_arrow_up",
1642
+ "left-icon": i.value ? "keyboard_arrow_down" : "keyboard_arrow_up",
1110
1643
  "aria-label": e.toggleLabel,
1111
- onClick: y
1112
- }, null, 8, ["left-icon", "aria-label"])) : u("", !0),
1113
- e.showClose ? (t(), a("button", {
1644
+ onClick: r
1645
+ }, null, 8, ["left-icon", "aria-label"])) : m("", !0),
1646
+ e.showClose ? (a(), l("button", {
1114
1647
  key: 3,
1115
1648
  type: "button",
1116
1649
  class: "ds-data-card__close",
1117
1650
  "aria-label": e.closeLabel,
1118
- onClick: N
1651
+ onClick: T
1119
1652
  }, [...E[4] || (E[4] = [
1120
- d("i", {
1653
+ s("i", {
1121
1654
  class: "material-icons",
1122
1655
  "aria-hidden": "true"
1123
1656
  }, "close", -1)
1124
- ])], 8, pt)) : u("", !0)
1657
+ ])], 8, el)) : m("", !0)
1125
1658
  ])
1126
1659
  ], 2),
1127
- b.value ? u("", !0) : (t(), a("div", Ht, [
1128
- c.value ? (t(), a("div", Yt, [
1129
- d("i", qt, v(e.icon), 1),
1130
- d("span", null, v(e.emptyLabel), 1)
1131
- ])) : (t(), a(A, { key: 1 }, [
1132
- e.mostLikely ? (t(), a("div", Wt, [
1133
- o.value ? (t(), a("div", Kt, v(e.mostLikelyLabel), 1)) : u("", !0),
1134
- p(S(ne), {
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), {
1135
1691
  value: e.mostLikely.value,
1136
1692
  "value-type": e.mostLikely.type,
1137
1693
  verified: e.mostLikely.verified,
1138
1694
  correct: e.mostLikely.correct,
1695
+ "hide-value": e.mostLikely.hideValue,
1139
1696
  main: "",
1140
1697
  "is-contact-data": e.isContactData,
1141
1698
  "show-rate": e.showRate,
1142
- onCopy: f,
1143
- onCorrect: E[2] || (E[2] = (w) => x(e.mostLikely)),
1144
- onIncorrect: E[3] || (E[3] = (w) => M(e.mostLikely))
1145
- }, null, 8, ["value", "value-type", "verified", "correct", "is-contact-data", "show-rate"])
1146
- ])) : u("", !0),
1147
- e.more.length > 0 ? (t(), a("div", Xt, [
1148
- o.value ? (t(), a("div", Qt, v(e.moreLabel), 1)) : u("", !0),
1149
- d("div", Zt, [
1150
- (t(!0), a(A, null, V(e.more, (w) => (t(), D(S(ne), {
1151
- key: w.value,
1152
- value: w.value,
1153
- "value-type": w.type,
1154
- verified: w.verified,
1155
- correct: w.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,
1156
1714
  "is-contact-data": e.isContactData,
1157
1715
  "show-rate": e.showRate,
1158
- onCopy: f,
1159
- onCorrect: (fe) => x(w),
1160
- onIncorrect: (fe) => M(w)
1161
- }, 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))
1162
1720
  ])
1163
- ])) : u("", !0)
1721
+ ])) : m("", !0)
1164
1722
  ], 64))
1165
1723
  ]))
1166
- ], 8, zt));
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
+ ]));
1167
2731
  }
1168
- }), ra = /* @__PURE__ */ T(jt, [["__scopeId", "data-v-86467226"]]);
2732
+ }), nn = /* @__PURE__ */ M(Ri, [["__scopeId", "data-v-d6f1e6d7"]]);
1169
2733
  export {
1170
- nt as DS_ALERT_EFFECTS,
1171
- ot as DS_ALERT_ICONS,
1172
- lt as DS_ALERT_TYPES,
1173
- X as DS_BADGE_TONES,
1174
- ke as DS_BUTTON_NATIVE_TYPES,
1175
- ie as DS_BUTTON_SIZES,
1176
- H as DS_BUTTON_VARIANTS,
1177
- _e as DS_INPUT_SIZES,
1178
- Y as DS_INPUT_TYPES,
1179
- vt as DS_NOTIFICATION_ICONS,
1180
- yt as DS_NOTIFICATION_POSITIONS,
1181
- ft as DS_NOTIFICATION_TYPES,
1182
- W as DS_SPINNER_TONES,
1183
- le as DS_TABLE_ALIGN,
1184
- De as DS_TAG_TONES,
1185
- q as DS_VERIFICATION_STATES,
1186
- oa as DsAlert,
1187
- ta as DsAvatar,
1188
- Ae as DsBadge,
1189
- K as DsButton,
1190
- na as DsCheckbox,
1191
- ne as DsContactValue,
1192
- ra as DsDataCard,
1193
- ia as DsInput,
1194
- da as DsModal,
1195
- sa as DsNotification,
1196
- Se as DsSpinner,
1197
- aa as DsTable,
1198
- ea as DsTag,
1199
- la as DsTextarea,
1200
- Rt 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
1201
2788
  };
1202
2789
  //# sourceMappingURL=index.es.js.map