@studiolxd/brand 38.17.0 → 40.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/dist/_shared/brandmessagescontext.js +15 -0
  3. package/dist/_shared/calendargrid.js +42 -42
  4. package/dist/_shared/datepicker.js +41 -41
  5. package/dist/_shared/imagecropdialog.js +54 -54
  6. package/dist/_shared/tokens.js +4 -0
  7. package/dist/_types/atoms/StarRating/StarRating.d.ts +87 -30
  8. package/dist/_types/messages/BrandMessages.d.ts +26 -0
  9. package/dist/_types/messages/BrandMessagesContext.d.ts +21 -0
  10. package/dist/_types/messages/BrandMessagesProvider.d.ts +46 -0
  11. package/dist/_types/messages/index.d.ts +5 -0
  12. package/dist/_types/molecules/Card/Card.d.ts +12 -1
  13. package/dist/_types/molecules/ConfirmDialog/ConfirmDialog.d.ts +42 -2
  14. package/dist/_types/molecules/Pagination/Pagination.d.ts +40 -23
  15. package/dist/_types/organisms/DataTable/DataTable.d.ts +3 -2
  16. package/dist/accordion.js +26 -26
  17. package/dist/alert.js +26 -26
  18. package/dist/annotation-thread.js +1 -1
  19. package/dist/app-header.js +8 -8
  20. package/dist/app-launcher.js +34 -34
  21. package/dist/app-shell.js +14 -14
  22. package/dist/assistant-message.js +8 -8
  23. package/dist/async-multi-select-field.js +9 -9
  24. package/dist/async-multi-select.js +40 -40
  25. package/dist/async-select-field.js +9 -9
  26. package/dist/async-select.js +64 -64
  27. package/dist/avatar-upload.js +40 -40
  28. package/dist/avatar.js +5 -5
  29. package/dist/banner.js +9 -9
  30. package/dist/brand.css +11 -2
  31. package/dist/button.js +7 -7
  32. package/dist/calendar-planner.js +16 -16
  33. package/dist/calendar.js +38 -38
  34. package/dist/card.js +28 -29
  35. package/dist/carousel.js +19 -19
  36. package/dist/chart.js +137 -137
  37. package/dist/chat-shell.js +23 -23
  38. package/dist/checkbox-field.js +11 -11
  39. package/dist/checkbox.js +7 -7
  40. package/dist/close-button.js +6 -6
  41. package/dist/code-block.js +15 -15
  42. package/dist/code.js +5 -5
  43. package/dist/collapsible.js +1 -1
  44. package/dist/columns.js +7 -7
  45. package/dist/command-palette.js +14 -14
  46. package/dist/confirm-dialog.css +1 -1
  47. package/dist/confirm-dialog.js +65 -42
  48. package/dist/connector-auth-shell.js +9 -9
  49. package/dist/consent.js +23 -23
  50. package/dist/container.js +6 -6
  51. package/dist/conversation-list.js +19 -19
  52. package/dist/conversation-thread.js +15 -15
  53. package/dist/copy-button.js +9 -9
  54. package/dist/copyable-value.js +17 -17
  55. package/dist/data-table.js +29 -29
  56. package/dist/date-picker-field.js +9 -9
  57. package/dist/date-time-field.js +12 -12
  58. package/dist/description-list.js +12 -12
  59. package/dist/docs-search.js +1 -1
  60. package/dist/dots-button.js +7 -7
  61. package/dist/dropdown-field.js +13 -13
  62. package/dist/email.js +44 -44
  63. package/dist/error-text.js +4 -4
  64. package/dist/field-row.js +20 -20
  65. package/dist/figure.js +8 -8
  66. package/dist/file-upload-field.js +9 -9
  67. package/dist/file-upload.js +29 -29
  68. package/dist/filter-bar.js +10 -10
  69. package/dist/floating-dock.js +17 -17
  70. package/dist/form-field.js +43 -43
  71. package/dist/form.js +14 -14
  72. package/dist/heading.js +5 -5
  73. package/dist/input-field.js +20 -20
  74. package/dist/input-phone-field.js +9 -9
  75. package/dist/input-phone.js +19 -19
  76. package/dist/input.js +5 -5
  77. package/dist/kbd.js +5 -5
  78. package/dist/label.js +5 -5
  79. package/dist/link.js +7 -7
  80. package/dist/list.js +7 -7
  81. package/dist/menu-button.js +7 -7
  82. package/dist/message-bubble.js +5 -5
  83. package/dist/message-composer.js +13 -13
  84. package/dist/messages.js +12 -0
  85. package/dist/multi-select-field.js +9 -9
  86. package/dist/multi-select.js +52 -52
  87. package/dist/notification-button.js +8 -8
  88. package/dist/notification-panel.js +25 -25
  89. package/dist/number-input-field.js +9 -9
  90. package/dist/number-input.js +11 -11
  91. package/dist/otp-field.js +9 -9
  92. package/dist/otp-input.js +48 -48
  93. package/dist/pagination.js +92 -89
  94. package/dist/paragraph.js +5 -5
  95. package/dist/password-field.js +15 -15
  96. package/dist/prose.js +4 -4
  97. package/dist/public-page-shell.js +11 -11
  98. package/dist/radio-field.js +11 -11
  99. package/dist/radio-group.js +5 -5
  100. package/dist/radio.js +5 -5
  101. package/dist/scroll-area.js +11 -11
  102. package/dist/search-form.js +8 -8
  103. package/dist/select-field.js +9 -9
  104. package/dist/select.js +85 -85
  105. package/dist/separator.js +6 -6
  106. package/dist/sidebar.js +16 -16
  107. package/dist/site-header.js +14 -14
  108. package/dist/site-shell.js +6 -6
  109. package/dist/sparkline.js +9 -9
  110. package/dist/star-rating.css +1 -1
  111. package/dist/star-rating.js +55 -41
  112. package/dist/stat-tile.js +12 -12
  113. package/dist/steps.js +32 -32
  114. package/dist/switcher-field.js +13 -13
  115. package/dist/switcher.js +8 -8
  116. package/dist/table-of-contents.js +14 -14
  117. package/dist/tag.js +5 -5
  118. package/dist/text.js +7 -7
  119. package/dist/textarea-field.js +11 -11
  120. package/dist/textarea.js +5 -5
  121. package/dist/time-field.js +9 -9
  122. package/dist/time-select.js +17 -17
  123. package/dist/toaster.js +16 -16
  124. package/dist/toggle-group.js +7 -7
  125. package/dist/toggle.js +5 -5
  126. package/dist/tokens.css +11 -2
  127. package/dist/tooltip.js +16 -16
  128. package/dist/tree-view.js +41 -41
  129. package/dist/uptime-bars.js +34 -34
  130. package/dist/user-message.js +8 -8
  131. package/dist/visually-hidden.js +5 -5
  132. package/package.json +5 -1
  133. package/src/tokens/components/description-list.css +1 -1
  134. package/src/tokens/components/star-rating.css +5 -0
  135. package/src/tokens/molecules/confirm-dialog.css +1 -0
  136. package/src/tokens/scss/components/_description-list.scss +1 -1
  137. package/src/tokens/scss/components/_star-rating.scss +3 -0
  138. package/src/tokens/scss/molecules/_confirm-dialog.scss +1 -0
  139. package/src/tokens/surface-invert.css +2 -0
  140. package/src/tokens/surface-public.css +1 -0
  141. package/src/tokens/tokens.json +4 -0
@@ -3,8 +3,8 @@ import { Spinner as e } from "../spinner.js";
3
3
  import { Button as t } from "../button.js";
4
4
  import { Alert as n } from "../alert.js";
5
5
  import { Modal as r } from "../modal.js";
6
- import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
7
- import s, { PureComponent as c, createRef as l, useRef as u, useState as d } from "react";
6
+ import i, { PureComponent as a, createRef as o, useRef as s, useState as c } from "react";
7
+ import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
8
8
  //#region node_modules/.pnpm/react-image-crop@11.1.2_react@19.2.4/node_modules/react-image-crop/dist/index.js
9
9
  var f = {
10
10
  x: 0,
@@ -72,7 +72,7 @@ function x(e, t, n, r) {
72
72
  var S = {
73
73
  capture: !0,
74
74
  passive: !1
75
- }, C = 0, w = class e extends c {
75
+ }, C = 0, w = class e extends a {
76
76
  static xOrds = ["e", "w"];
77
77
  static yOrds = ["n", "s"];
78
78
  static xyOrds = [
@@ -110,8 +110,8 @@ var S = {
110
110
  clientY: 0,
111
111
  isResize: !0
112
112
  };
113
- componentRef = l();
114
- mediaRef = l();
113
+ componentRef = o();
114
+ mediaRef = o();
115
115
  resizeObserver;
116
116
  initChangeCalled = !1;
117
117
  instanceId = `rc-${C++}`;
@@ -277,8 +277,8 @@ var S = {
277
277
  return n || e.xyOrds.indexOf(u) > -1 ? c = h : e.xOrds.indexOf(u) > -1 ? (c.x = h.x, c.width = h.width) : e.yOrds.indexOf(u) > -1 && (c.y = h.y, c.height = h.height), c.x = p(c.x, 0, a.width - c.width), c.y = p(c.y, 0, a.height - c.height), c;
278
278
  }
279
279
  renderCropSelection() {
280
- let { ariaLabels: t = e.defaultProps.ariaLabels, disabled: n, locked: r, renderSelectionAddon: i, ruleOfThirds: a, crop: o } = this.props, c = this.getCropStyle();
281
- if (o) return /* @__PURE__ */ s.createElement("div", {
280
+ let { ariaLabels: t = e.defaultProps.ariaLabels, disabled: n, locked: r, renderSelectionAddon: a, ruleOfThirds: o, crop: s } = this.props, c = this.getCropStyle();
281
+ if (s) return /* @__PURE__ */ i.createElement("div", {
282
282
  style: c,
283
283
  className: "ReactCrop__crop-selection",
284
284
  onPointerDown: this.onCropPointerDown,
@@ -286,81 +286,81 @@ var S = {
286
286
  tabIndex: 0,
287
287
  onKeyDown: this.onComponentKeyDown,
288
288
  role: "group"
289
- }, !n && !r && /* @__PURE__ */ s.createElement("div", {
289
+ }, !n && !r && /* @__PURE__ */ i.createElement("div", {
290
290
  className: "ReactCrop__drag-elements",
291
291
  onFocus: this.onDragFocus
292
- }, /* @__PURE__ */ s.createElement("div", {
292
+ }, /* @__PURE__ */ i.createElement("div", {
293
293
  className: "ReactCrop__drag-bar ord-n",
294
294
  "data-ord": "n"
295
- }), /* @__PURE__ */ s.createElement("div", {
295
+ }), /* @__PURE__ */ i.createElement("div", {
296
296
  className: "ReactCrop__drag-bar ord-e",
297
297
  "data-ord": "e"
298
- }), /* @__PURE__ */ s.createElement("div", {
298
+ }), /* @__PURE__ */ i.createElement("div", {
299
299
  className: "ReactCrop__drag-bar ord-s",
300
300
  "data-ord": "s"
301
- }), /* @__PURE__ */ s.createElement("div", {
301
+ }), /* @__PURE__ */ i.createElement("div", {
302
302
  className: "ReactCrop__drag-bar ord-w",
303
303
  "data-ord": "w"
304
- }), /* @__PURE__ */ s.createElement("div", {
304
+ }), /* @__PURE__ */ i.createElement("div", {
305
305
  className: "ReactCrop__drag-handle ord-nw",
306
306
  "data-ord": "nw",
307
307
  tabIndex: 0,
308
308
  "aria-label": t.nwDragHandle,
309
309
  onKeyDown: (e) => this.onHandlerKeyDown(e, "nw"),
310
310
  role: "button"
311
- }), /* @__PURE__ */ s.createElement("div", {
311
+ }), /* @__PURE__ */ i.createElement("div", {
312
312
  className: "ReactCrop__drag-handle ord-n",
313
313
  "data-ord": "n",
314
314
  tabIndex: 0,
315
315
  "aria-label": t.nDragHandle,
316
316
  onKeyDown: (e) => this.onHandlerKeyDown(e, "n"),
317
317
  role: "button"
318
- }), /* @__PURE__ */ s.createElement("div", {
318
+ }), /* @__PURE__ */ i.createElement("div", {
319
319
  className: "ReactCrop__drag-handle ord-ne",
320
320
  "data-ord": "ne",
321
321
  tabIndex: 0,
322
322
  "aria-label": t.neDragHandle,
323
323
  onKeyDown: (e) => this.onHandlerKeyDown(e, "ne"),
324
324
  role: "button"
325
- }), /* @__PURE__ */ s.createElement("div", {
325
+ }), /* @__PURE__ */ i.createElement("div", {
326
326
  className: "ReactCrop__drag-handle ord-e",
327
327
  "data-ord": "e",
328
328
  tabIndex: 0,
329
329
  "aria-label": t.eDragHandle,
330
330
  onKeyDown: (e) => this.onHandlerKeyDown(e, "e"),
331
331
  role: "button"
332
- }), /* @__PURE__ */ s.createElement("div", {
332
+ }), /* @__PURE__ */ i.createElement("div", {
333
333
  className: "ReactCrop__drag-handle ord-se",
334
334
  "data-ord": "se",
335
335
  tabIndex: 0,
336
336
  "aria-label": t.seDragHandle,
337
337
  onKeyDown: (e) => this.onHandlerKeyDown(e, "se"),
338
338
  role: "button"
339
- }), /* @__PURE__ */ s.createElement("div", {
339
+ }), /* @__PURE__ */ i.createElement("div", {
340
340
  className: "ReactCrop__drag-handle ord-s",
341
341
  "data-ord": "s",
342
342
  tabIndex: 0,
343
343
  "aria-label": t.sDragHandle,
344
344
  onKeyDown: (e) => this.onHandlerKeyDown(e, "s"),
345
345
  role: "button"
346
- }), /* @__PURE__ */ s.createElement("div", {
346
+ }), /* @__PURE__ */ i.createElement("div", {
347
347
  className: "ReactCrop__drag-handle ord-sw",
348
348
  "data-ord": "sw",
349
349
  tabIndex: 0,
350
350
  "aria-label": t.swDragHandle,
351
351
  onKeyDown: (e) => this.onHandlerKeyDown(e, "sw"),
352
352
  role: "button"
353
- }), /* @__PURE__ */ s.createElement("div", {
353
+ }), /* @__PURE__ */ i.createElement("div", {
354
354
  className: "ReactCrop__drag-handle ord-w",
355
355
  "data-ord": "w",
356
356
  tabIndex: 0,
357
357
  "aria-label": t.wDragHandle,
358
358
  onKeyDown: (e) => this.onHandlerKeyDown(e, "w"),
359
359
  role: "button"
360
- })), i && /* @__PURE__ */ s.createElement("div", {
360
+ })), a && /* @__PURE__ */ i.createElement("div", {
361
361
  className: "ReactCrop__selection-addon",
362
362
  onPointerDown: (e) => e.stopPropagation()
363
- }, i(this.state)), a && /* @__PURE__ */ s.createElement(s.Fragment, null, /* @__PURE__ */ s.createElement("div", { className: "ReactCrop__rule-of-thirds-hz" }), /* @__PURE__ */ s.createElement("div", { className: "ReactCrop__rule-of-thirds-vt" })));
363
+ }, a(this.state)), o && /* @__PURE__ */ i.createElement(i.Fragment, null, /* @__PURE__ */ i.createElement("div", { className: "ReactCrop__rule-of-thirds-hz" }), /* @__PURE__ */ i.createElement("div", { className: "ReactCrop__rule-of-thirds-vt" })));
364
364
  }
365
365
  makePixelCrop(e) {
366
366
  return y({
@@ -369,36 +369,36 @@ var S = {
369
369
  }, e.width, e.height);
370
370
  }
371
371
  render() {
372
- let { aspect: e, children: t, circularCrop: n, className: r, crop: i, disabled: a, locked: o, style: c, ruleOfThirds: l } = this.props, { cropIsActive: u, newCropIsBeingDrawn: d } = this.state, f = i ? this.renderCropSelection() : null, p = m("ReactCrop", r, u && "ReactCrop--active", a && "ReactCrop--disabled", o && "ReactCrop--locked", d && "ReactCrop--new-crop", i && e && "ReactCrop--fixed-aspect", i && n && "ReactCrop--circular-crop", i && l && "ReactCrop--rule-of-thirds", !this.dragStarted && i && !i.width && !i.height && "ReactCrop--invisible-crop", n && "ReactCrop--no-animate");
373
- return /* @__PURE__ */ s.createElement("div", {
372
+ let { aspect: e, children: t, circularCrop: n, className: r, crop: a, disabled: o, locked: s, style: c, ruleOfThirds: l } = this.props, { cropIsActive: u, newCropIsBeingDrawn: d } = this.state, f = a ? this.renderCropSelection() : null, p = m("ReactCrop", r, u && "ReactCrop--active", o && "ReactCrop--disabled", s && "ReactCrop--locked", d && "ReactCrop--new-crop", a && e && "ReactCrop--fixed-aspect", a && n && "ReactCrop--circular-crop", a && l && "ReactCrop--rule-of-thirds", !this.dragStarted && a && !a.width && !a.height && "ReactCrop--invisible-crop", n && "ReactCrop--no-animate");
373
+ return /* @__PURE__ */ i.createElement("div", {
374
374
  ref: this.componentRef,
375
375
  className: p,
376
376
  style: c
377
- }, /* @__PURE__ */ s.createElement("div", {
377
+ }, /* @__PURE__ */ i.createElement("div", {
378
378
  ref: this.mediaRef,
379
379
  className: "ReactCrop__child-wrapper",
380
380
  onPointerDown: this.onComponentPointerDown
381
- }, t), i ? /* @__PURE__ */ s.createElement("svg", {
381
+ }, t), a ? /* @__PURE__ */ i.createElement("svg", {
382
382
  className: "ReactCrop__crop-mask",
383
383
  width: "100%",
384
384
  height: "100%"
385
- }, /* @__PURE__ */ s.createElement("defs", null, /* @__PURE__ */ s.createElement("mask", { id: `hole-${this.instanceId}` }, /* @__PURE__ */ s.createElement("rect", {
385
+ }, /* @__PURE__ */ i.createElement("defs", null, /* @__PURE__ */ i.createElement("mask", { id: `hole-${this.instanceId}` }, /* @__PURE__ */ i.createElement("rect", {
386
386
  width: "100%",
387
387
  height: "100%",
388
388
  fill: "white"
389
- }), n ? /* @__PURE__ */ s.createElement("ellipse", {
390
- cx: `${i.x + i.width / 2}${i.unit}`,
391
- cy: `${i.y + i.height / 2}${i.unit}`,
392
- rx: `${i.width / 2}${i.unit}`,
393
- ry: `${i.height / 2}${i.unit}`,
389
+ }), n ? /* @__PURE__ */ i.createElement("ellipse", {
390
+ cx: `${a.x + a.width / 2}${a.unit}`,
391
+ cy: `${a.y + a.height / 2}${a.unit}`,
392
+ rx: `${a.width / 2}${a.unit}`,
393
+ ry: `${a.height / 2}${a.unit}`,
394
394
  fill: "black"
395
- }) : /* @__PURE__ */ s.createElement("rect", {
396
- x: `${i.x}${i.unit}`,
397
- y: `${i.y}${i.unit}`,
398
- width: `${i.width}${i.unit}`,
399
- height: `${i.height}${i.unit}`,
395
+ }) : /* @__PURE__ */ i.createElement("rect", {
396
+ x: `${a.x}${a.unit}`,
397
+ y: `${a.y}${a.unit}`,
398
+ width: `${a.width}${a.unit}`,
399
+ height: `${a.height}${a.unit}`,
400
400
  fill: "black"
401
- }))), /* @__PURE__ */ s.createElement("rect", {
401
+ }))), /* @__PURE__ */ i.createElement("rect", {
402
402
  fill: "black",
403
403
  fillOpacity: .5,
404
404
  width: "100%",
@@ -431,9 +431,9 @@ function E(e, t, n) {
431
431
  }
432
432
  //#endregion
433
433
  //#region src/stories/molecules/ImageCropDialog/ImageCropDialog.tsx
434
- function D({ sourceUrl: s, title: c, description: l, circularCrop: f = !1, aspect: p = 1, outputSize: m = 512, outputMimeType: h, busy: g = !1, cancelLabel: _, confirmLabel: v, closeLabel: y, loadingLabel: b = "Cargando imagen…", errorMessage: x = "No hemos podido cargar la imagen. Prueba con otro archivo.", onConfirm: S, onClose: C, className: D }) {
435
- let O = u(null), [k, A] = d(), [j, M] = d(), [N, P] = d("loading"), [F, I] = d(s);
436
- s !== F && (I(s), P("loading"), A(void 0), M(void 0));
434
+ function D({ sourceUrl: i, title: a, description: o, circularCrop: f = !1, aspect: p = 1, outputSize: m = 512, outputMimeType: h, busy: g = !1, cancelLabel: _, confirmLabel: v, closeLabel: y, loadingLabel: b = "Cargando imagen…", errorMessage: x = "No hemos podido cargar la imagen. Prueba con otro archivo.", onConfirm: S, onClose: C, className: D }) {
435
+ let O = s(null), [k, A] = c(), [j, M] = c(), [N, P] = c("loading"), [F, I] = c(i);
436
+ i !== F && (I(i), P("loading"), A(void 0), M(void 0));
437
437
  let L = () => {
438
438
  A(void 0), M(void 0), C();
439
439
  }, R = async () => {
@@ -443,40 +443,40 @@ function D({ sourceUrl: s, title: c, description: l, circularCrop: f = !1, aspec
443
443
  outputSize: m
444
444
  })), L());
445
445
  };
446
- return /* @__PURE__ */ a(r, {
447
- open: s !== null,
446
+ return /* @__PURE__ */ u(r, {
447
+ open: i !== null,
448
448
  onClose: () => {
449
449
  g || L();
450
450
  },
451
- title: c,
451
+ title: a,
452
452
  ...y ? { closeLabel: y } : {},
453
- ...l == null ? {} : { description: l },
453
+ ...o == null ? {} : { description: o },
454
454
  footerClassName: "image-crop-dialog__actions",
455
- footer: /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a(t, {
455
+ footer: /* @__PURE__ */ d(l, { children: [/* @__PURE__ */ u(t, {
456
456
  variant: "outline",
457
457
  disabled: g,
458
458
  onClick: L,
459
459
  children: _
460
- }), /* @__PURE__ */ a(t, {
460
+ }), /* @__PURE__ */ u(t, {
461
461
  disabled: g || !j?.width,
462
462
  onClick: R,
463
463
  children: v
464
464
  })] }),
465
- children: /* @__PURE__ */ a("div", {
465
+ children: /* @__PURE__ */ u("div", {
466
466
  className: ["image-crop-dialog", D].filter(Boolean).join(" "),
467
- children: /* @__PURE__ */ o("div", {
467
+ children: /* @__PURE__ */ d("div", {
468
468
  className: "image-crop-dialog__area",
469
469
  children: [
470
- N === "loading" && /* @__PURE__ */ a(e, {
470
+ N === "loading" && /* @__PURE__ */ u(e, {
471
471
  size: "lg",
472
472
  label: b
473
473
  }),
474
- N === "error" && /* @__PURE__ */ a(n, {
474
+ N === "error" && /* @__PURE__ */ u(n, {
475
475
  variant: "error",
476
476
  description: x,
477
477
  className: "image-crop-dialog__error"
478
478
  }),
479
- s && N !== "error" && /* @__PURE__ */ a(w, {
479
+ i && N !== "error" && /* @__PURE__ */ u(w, {
480
480
  crop: k,
481
481
  onChange: (e, t) => A(t),
482
482
  onComplete: (e) => M(e),
@@ -484,9 +484,9 @@ function D({ sourceUrl: s, title: c, description: l, circularCrop: f = !1, aspec
484
484
  circularCrop: f,
485
485
  minWidth: 64,
486
486
  keepSelection: !0,
487
- children: /* @__PURE__ */ a("img", {
487
+ children: /* @__PURE__ */ u("img", {
488
488
  ref: O,
489
- src: s,
489
+ src: i,
490
490
  alt: "",
491
491
  onLoad: (e) => {
492
492
  let { width: t, height: n } = e.currentTarget;
@@ -1656,7 +1656,10 @@ var e = {
1656
1656
  "--star-rating-star-size": "1.25em",
1657
1657
  "--star-rating-sm-star-size": "1em",
1658
1658
  "--star-rating-lg-star-size": "1.5em",
1659
+ "--star-rating-count-gap": "0.5rem",
1659
1660
  "--star-rating-track-color": "#6b6b6b",
1661
+ "--star-rating-count-color": "#4a4a4a",
1662
+ "--star-rating-empty-color": "#4a4a4a",
1660
1663
  "--star-rating-fill-color": "#111e30",
1661
1664
  "--star-rating-cursor": "pointer",
1662
1665
  "--star-rating-disabled-cursor": "not-allowed",
@@ -2356,6 +2359,7 @@ var e = {
2356
2359
  "--command-palette-item-highlighted-color": "#ffffff",
2357
2360
  "--command-palette-item-icon-size": "1.5rem",
2358
2361
  "--confirm-dialog-actions-space-before": "1.5rem",
2362
+ "--confirm-dialog-phrase-space-before": "1rem",
2359
2363
  "--consent-banner-bg": "#ffffff",
2360
2364
  "--consent-banner-color": "#111e30",
2361
2365
  "--consent-banner-border-color": "#111e30",
@@ -1,55 +1,112 @@
1
1
  import './StarRating.css';
2
- export interface StarRatingProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue'> {
3
- /** Valoración mostrada. En lectura se redondea a media estrella. */
4
- value?: number;
5
- /** Valoración al montar, cuando la entrada no está controlada. */
6
- defaultValue?: number;
7
- /** Se llama con la valoración elegida. Solo en entrada (`readOnly={false}`). */
8
- onValueChange?: (value: number) => void;
9
- /** Cuántas estrellas tiene la escala. */
2
+ /** Lo que no depende del modo ni de los textos. */
3
+ export interface StarRatingCommonProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue'> {
4
+ /** Cuántas estrellas tiene la escala. Default: 5. */
10
5
  max?: number;
6
+ /** Talla de la estrella, relativa al texto que la rodea. */
7
+ size?: 'sm' | 'md' | 'lg';
8
+ /** Se añade DESPUÉS de las clases propias. */
9
+ className?: string;
10
+ }
11
+ /**
12
+ * El recuento de reseñas y su rótulo viajan juntos: sin `reviewCount` no hay
13
+ * nada que escribir, y con él hace falta saber cómo se escribe.
14
+ */
15
+ export type StarRatingCountProps = {
16
+ /**
17
+ * Cuántas reseñas hay detrás de la media: se pinta a continuación («(24)»)
18
+ * y entra en el nombre accesible. **Sin él** la nota es la de UNA reseña
19
+ * suelta, donde un recuento no significa nada.
20
+ */
21
+ reviewCount?: undefined;
22
+ countLabel?: (reviewCount: number) => string;
23
+ } | {
24
+ /** Cuántas reseñas hay detrás de la media. Obliga a pasar `countLabel`. */
25
+ reviewCount: number;
26
+ /**
27
+ * Cómo se escribe el recuento visible («(24)»). **Obligatorio** con
28
+ * `reviewCount`: el componente no escribe texto por su cuenta.
29
+ */
30
+ countLabel: (reviewCount: number) => string;
31
+ };
32
+ /**
33
+ * El valor y el texto del vacío, igual: `emptyLabel` solo se lee cuando `value`
34
+ * puede ser `null`, así que solo lo pide quien pueda pasarlo.
35
+ */
36
+ export type StarRatingValueProps = {
37
+ /** Valoración mostrada. Se redondea a media estrella. */
38
+ value: number;
39
+ emptyLabel?: string;
40
+ } | {
41
+ /**
42
+ * Valoración mostrada. Se redondea a media estrella.
43
+ *
44
+ * **`null` no es cero**: es «todavía sin reseñas». Con `null` la escala no
45
+ * se dibuja —cinco estrellas vacías son el dibujo de «valorado con 0», que
46
+ * es una nota de verdad y la peor— y en su lugar va `emptyLabel`.
47
+ */
48
+ value: number | null;
49
+ /**
50
+ * Qué se lee y se ve cuando `value` es `null`. **Obligatorio** en cuanto
51
+ * `value` pueda serlo: el componente no escribe «Todavía sin reseñas» por
52
+ * su cuenta.
53
+ */
54
+ emptyLabel: string;
55
+ };
56
+ /** Modo lectura (el de siempre): una imagen con su nombre accesible. */
57
+ export type StarRatingReadProps = StarRatingCommonProps & StarRatingCountProps & StarRatingValueProps & {
11
58
  /**
12
59
  * Solo lectura (por defecto). El componente nace para **mostrar** una media;
13
60
  * para capturar una valoración hay que pedirlo con `readOnly={false}`.
14
61
  */
15
- readOnly?: boolean;
62
+ readOnly?: true;
63
+ /**
64
+ * Nombre accesible de la valoración: recibe el valor ya redondeado a media
65
+ * estrella, el máximo y, si lo hay, el recuento. Es el nombre COMPLETO —el
66
+ * recuento visible queda dentro de la imagen y no se lee aparte—, p. ej.
67
+ * «4,5 de 5 estrellas, 24 reseñas». **Obligatorio**: el nombre accesible lo
68
+ * pasa el consumidor.
69
+ */
70
+ valueLabel: (value: number, max: number, reviewCount?: number) => string;
71
+ };
72
+ /** Modo entrada (`readOnly={false}`): un grupo de radios nativos. */
73
+ export type StarRatingInputProps = StarRatingCommonProps & {
74
+ /** Modo entrada. */
75
+ readOnly: false;
76
+ /** Valoración elegida, cuando la entrada está controlada. */
77
+ value?: number;
78
+ /** Valoración al montar, cuando la entrada no está controlada. */
79
+ defaultValue?: number;
80
+ /** Se llama con la valoración elegida. */
81
+ onValueChange?: (value: number) => void;
16
82
  /** Deshabilita la entrada. */
17
83
  disabled?: boolean;
18
- /** Talla de la estrella, relativa al texto que la rodea. */
19
- size?: 'sm' | 'md' | 'lg';
20
84
  /** `name` de los radios que envían la valoración con el formulario. */
21
85
  name?: string;
22
- /** Idioma con el que se escribe el número del nombre accesible. */
23
- locale?: string;
24
- /**
25
- * Nombre accesible en lectura: recibe el valor ya redondeado a media estrella
26
- * y el máximo. Default: «4,5 de 5 estrellas» (castellano). Una app
27
- * multiidioma debe pasarlo traducido.
28
- */
29
- valueLabel?: (value: number, max: number) => string;
30
86
  /**
31
- * Nombre accesible de cada estrella elegible. Default: «3 de 5 estrellas»
32
- * (castellano). Una app multiidioma debe pasarlo traducido.
87
+ * Nombre accesible de cada estrella elegible, p. ej. «3 de 5 estrellas».
88
+ * **Obligatorio**: lo pasa el consumidor.
33
89
  */
34
- optionLabel?: (value: number, max: number) => string;
90
+ optionLabel: (value: number, max: number) => string;
35
91
  /**
36
- * Nombre accesible del grupo en modo entrada. Default: «Valoración»
37
- * (castellano). Una app multiidioma debe pasarlo traducido.
92
+ * Nombre accesible del grupo, p. ej. «Valoración». **Obligatorio**, igual que
93
+ * `optionLabel`.
38
94
  */
39
- groupLabel?: string;
40
- /** Se añade DESPUÉS de las clases propias. */
41
- className?: string;
42
- }
95
+ groupLabel: string;
96
+ };
97
+ export type StarRatingProps = StarRatingReadProps | StarRatingInputProps;
43
98
  /**
44
99
  * Valoración en estrellas, de lectura o de entrada.
45
100
  *
46
101
  * **En lectura** es una sola imagen: `role="img"` con el valor exacto en el
47
102
  * nombre accesible («4,5 de 5 estrellas»), no cinco iconos que el lector tenga
48
- * que contar. Admite **media estrella**, que es como se lee una media.
103
+ * que contar. Admite **media estrella**, que es como se lee una media, y
104
+ * **`value={null}`** para «todavía sin reseñas», que no se dibuja con estrellas
105
+ * porque las estrellas vacías ya significan otra cosa.
49
106
  *
50
107
  * **En entrada** (`readOnly={false}`) es un grupo de radios nativos —teclado,
51
108
  * envío de formulario y estado marcado vienen del navegador— con una estrella
52
109
  * por opción. La entrada va en pasos enteros: la media estrella describe una
53
110
  * media calculada, no algo que una persona elija.
54
111
  */
55
- export declare function StarRating({ value: valueProp, defaultValue, onValueChange, max, readOnly, disabled, size, name: nameProp, locale, valueLabel, optionLabel, groupLabel, className, ...rest }: StarRatingProps): import("react/jsx-runtime").JSX.Element;
112
+ export declare function StarRating(props: StarRatingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,26 @@
1
+ import type { PaginationMessages } from '../molecules/Pagination/Pagination';
2
+ /**
3
+ * El contrato de textos de la librería: un espacio por componente, y dentro
4
+ * de cada espacio **todas las claves obligatorias**.
5
+ *
6
+ * El tipo nace aquí, en el DS, y es el catálogo de la aplicación el que lo
7
+ * satisface — nunca al revés. Si el tipo se generase desde el JSON de una
8
+ * suite concreta, el DS pasaría a depender de un paquete de producto para
9
+ * declarar su propio contrato y dejaría de sostenerse solo.
10
+ *
11
+ * Anidado por componente, no plano: son 310 textos en 111 componentes, y una
12
+ * lista plana de claves sueltas (`paginationPrevious`, `modalClose`…) no se
13
+ * puede escribir ni revisar. Los espacios calcan además los que el catálogo
14
+ * de la suite ya tiene (`pagination`, `table`, `common`…), así que montar el
15
+ * proveedor es mapear namespaces, no inventarlos.
16
+ *
17
+ * Cada interfaz de espacio vive **junto a su componente** (como
18
+ * `RecoveryCodesLabels`), no aquí: aquí solo se ensamblan. Un componente que
19
+ * gana textos declara su interfaz al lado de sus props y añade una línea a
20
+ * este tipo; a partir de ese momento, una aplicación que no la rellene no
21
+ * compila.
22
+ */
23
+ export interface BrandMessages {
24
+ pagination: PaginationMessages;
25
+ }
26
+ export type { PaginationMessages };
@@ -0,0 +1,21 @@
1
+ import type { BrandMessages } from './BrandMessages';
2
+ /**
3
+ * El catálogo montado por la aplicación, o `null` si no hay proveedor. Lo
4
+ * pone `BrandMessagesProvider` y lo leen los componentes con
5
+ * `useBrandMessages`.
6
+ */
7
+ export declare const BrandMessagesContext: import("react").Context<BrandMessages | null>;
8
+ /**
9
+ * Lee un texto del espacio de un componente: `t('previous')` devuelve el del
10
+ * proveedor, y `t('previous', previousLabel)` deja ganar a la prop cuando el
11
+ * consumidor la pasa.
12
+ */
13
+ export interface BrandMessagesReader<K extends keyof BrandMessages> {
14
+ <N extends keyof BrandMessages[K]>(key: N, override?: BrandMessages[K][N]): BrandMessages[K][N];
15
+ }
16
+ /**
17
+ * El lector del espacio de un componente. Se llama **en el punto donde el
18
+ * texto se pinta**, no al principio del render: así un componente que no
19
+ * enseña el selector de tamaño tampoco exige su texto.
20
+ */
21
+ export declare function useBrandMessages<K extends keyof BrandMessages>(namespace: K): BrandMessagesReader<K>;
@@ -0,0 +1,46 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { BrandMessages } from './BrandMessages';
3
+ export interface BrandMessagesProviderProps {
4
+ /**
5
+ * El catálogo entero, en el idioma vigente. Es `BrandMessages`, con todas
6
+ * sus claves: si falta una, no compila. Ese es el punto del proveedor —
7
+ * olvidar un texto tiene que ser un error de compilación y no un
8
+ * «Cancelar» castellano dentro de una página en francés.
9
+ */
10
+ messages: BrandMessages;
11
+ children: ReactNode;
12
+ }
13
+ /**
14
+ * Los textos que los componentes emiten por su cuenta, montado **una vez en
15
+ * la raíz de la aplicación** y alimentado desde el catálogo de la app (en la
16
+ * suite, `@slxd/messages`).
17
+ *
18
+ * El orden de resolución de cada texto es **prop → proveedor → error**, y no
19
+ * hay un cuarto escalón: ningún componente trae el castellano puesto. La prop
20
+ * suelta sigue existiendo como anulación puntual —el `ariaLabel` de un
21
+ * paginador concreto no es el de todos—, pero cuando no se pasa, el texto
22
+ * sale del proveedor o revienta con un mensaje que dice qué falta.
23
+ *
24
+ * ```tsx
25
+ * // app/[locale]/layout.tsx
26
+ * const t = await getTranslations();
27
+ *
28
+ * <BrandMessagesProvider
29
+ * messages={{
30
+ * pagination: {
31
+ * label: t('pagination.label'),
32
+ * pagesGroup: t('pagination.pagesGroup'),
33
+ * previous: t('pagination.previous'),
34
+ * next: t('pagination.next'),
35
+ * goToPage: (page) => t('pagination.goToPage', { page }),
36
+ * perPage: t('pagination.perPage'),
37
+ * total: (count) => t('pagination.total', { count }),
38
+ * allOption: t('pagination.allOption'),
39
+ * },
40
+ * }}
41
+ * >
42
+ * {children}
43
+ * </BrandMessagesProvider>
44
+ * ```
45
+ */
46
+ export declare function BrandMessagesProvider({ messages, children }: BrandMessagesProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export { BrandMessagesProvider } from './BrandMessagesProvider';
2
+ export type { BrandMessagesProviderProps } from './BrandMessagesProvider';
3
+ export { useBrandMessages } from './BrandMessagesContext';
4
+ export type { BrandMessagesReader } from './BrandMessagesContext';
5
+ export type { BrandMessages, PaginationMessages } from './BrandMessages';
@@ -50,7 +50,18 @@ export interface CardProps extends Omit<React.ComponentPropsWithoutRef<'div'>, '
50
50
  * consumidor (varios párrafos, `<Tag>`, texto con formato…).
51
51
  */
52
52
  description?: React.ReactNode;
53
- /** Texto accesible del CTA, visually-hidden (modo link — se espera junto a `href` o `render`). */
53
+ /**
54
+ * Texto accesible del CTA (modo link), *visually-hidden*. **Manda sobre la
55
+ * flecha**: con `ctaLabel` la tarjeta pinta la flecha Y su nombre accesible;
56
+ * sin `ctaLabel` no pinta ninguna de las dos cosas. Una sola decisión en vez
57
+ * de dos props que puedan contradecirse — no hay `showArrow`.
58
+ *
59
+ * Omitirlo es lo que se quiere en una rejilla de catálogo, donde la flecha
60
+ * repetida en cada tarjeta es ruido y el destino ya lo dice el título. Con
61
+ * él, en cambio, la tarjeta suelta de marketing gana la llamada visible y el
62
+ * enlace un nombre accesible completo («Ver más sobre plataformas LMS»)
63
+ * cuando lo único visible sería la flecha.
64
+ */
54
65
  ctaLabel?: string;
55
66
  /** Color de fondo. Default: `'outline'`. */
56
67
  color?: CardColor;
@@ -1,7 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import { type ModalProps } from '../Modal/Modal';
3
3
  import './ConfirmDialog.css';
4
- export interface ConfirmDialogProps {
4
+ export interface ConfirmDialogBaseProps {
5
5
  open: boolean;
6
6
  /** Título del diálogo: la pregunta, no «Confirmar». */
7
7
  title: string;
@@ -67,6 +67,42 @@ export interface ConfirmDialogProps {
67
67
  /** Se añade DESPUÉS de las clases propias del pie del diálogo. */
68
68
  className?: string;
69
69
  }
70
+ /**
71
+ * La frase de confirmación y sus dos textos viajan juntos: sin `confirmPhrase`
72
+ * no hay campo que rotular ni discrepancia que contar, y con ella los dos
73
+ * textos los pasa el producto —dicen QUÉ hay que teclear—, así que no llevan
74
+ * default castellano.
75
+ */
76
+ export type ConfirmDialogPhraseProps = {
77
+ /**
78
+ * Exige teclear una frase exacta —el nombre de la organización, el del
79
+ * plugin— antes de poder confirmar. El botón de confirmar nace apagado y
80
+ * solo se enciende cuando lo tecleado coincide.
81
+ */
82
+ confirmPhrase?: undefined;
83
+ confirmPhraseLabel?: string;
84
+ confirmPhraseMismatch?: string;
85
+ } | {
86
+ /**
87
+ * La frase exacta que hay que teclear para poder confirmar. Se compara
88
+ * sin los espacios de los extremos —un espacio pegado al pegar no es un
89
+ * error de la persona— pero sin tocar nada más: ni la caja ni los
90
+ * acentos, que es de lo que vive esta barrera.
91
+ */
92
+ confirmPhrase: string;
93
+ /**
94
+ * Rótulo del campo. **Obligatorio** con `confirmPhrase`, sin default: es
95
+ * donde el producto dice qué hay que teclear («Escribe *acme* para
96
+ * confirmar»), y eso el diálogo no lo sabe.
97
+ */
98
+ confirmPhraseLabel: string;
99
+ /**
100
+ * Mensaje cuando lo tecleado no coincide. **Obligatorio** con
101
+ * `confirmPhrase`, sin default, por lo mismo.
102
+ */
103
+ confirmPhraseMismatch: string;
104
+ };
105
+ export type ConfirmDialogProps = ConfirmDialogBaseProps & ConfirmDialogPhraseProps;
70
106
  /**
71
107
  * La pregunta antes de una acción que no se puede deshacer: borrar una
72
108
  * organización, revocar una clave, expulsar a alguien de un equipo.
@@ -80,5 +116,9 @@ export interface ConfirmDialogProps {
80
116
  * queda abierto y ocupado —no se cierra en falso ni deja pulsar dos veces— y
81
117
  * se cierra solo al resolver. Si rechaza, sigue abierto: el error lo cuenta el
82
118
  * consumidor, que es quien sabe qué ha pasado.
119
+ *
120
+ * Con `confirmPhrase` monta además la **barrera de teclear el identificador**
121
+ * —el patrón de «escribe el nombre de la organización para borrarla»—: un campo
122
+ * bajo la pregunta y el botón de confirmar apagado hasta que coincida.
83
123
  */
84
- export declare function ConfirmDialog({ open, title, description, children, onConfirm, onCancel, onConfirmError, secondaryActionLabel, onSecondaryAction, destructive, confirmLabel, cancelLabel, pendingLabel, closeLabel, container, className, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
124
+ export declare function ConfirmDialog({ open, title, description, children, onConfirm, onCancel, onConfirmError, secondaryActionLabel, onSecondaryAction, destructive, confirmLabel, cancelLabel, pendingLabel, closeLabel, confirmPhrase, confirmPhraseLabel, confirmPhraseMismatch, container, className, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;