@rojaostudio/ds 2.0.0-next.2 → 2.0.0-next.21

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 (101) hide show
  1. package/README.md +42 -2
  2. package/THIRD_PARTY_NOTICES.md +66 -0
  3. package/dist/components/avatar.d.ts +20 -12
  4. package/dist/components/avatar.js +8 -6
  5. package/dist/components/badge.d.ts +7 -6
  6. package/dist/components/badge.js +2 -1
  7. package/dist/components/breadcrumb.d.ts +4 -4
  8. package/dist/components/breadcrumb.js +1 -1
  9. package/dist/components/bubble.d.ts +26 -11
  10. package/dist/components/bubble.js +3 -3
  11. package/dist/components/button.d.ts +1 -1
  12. package/dist/components/card.d.ts +28 -12
  13. package/dist/components/card.js +4 -2
  14. package/dist/components/chart.d.ts +17 -3
  15. package/dist/components/chart.js +70 -24
  16. package/dist/components/choice-carousel.d.ts +1 -1
  17. package/dist/components/choice-carousel.js +2 -4
  18. package/dist/components/choice-list.d.ts +40 -0
  19. package/dist/components/choice-list.js +122 -0
  20. package/dist/components/choice-preview-card.d.ts +1 -7
  21. package/dist/components/color-input.d.ts +1 -1
  22. package/dist/components/context-menu.d.ts +5 -2
  23. package/dist/components/currency-input.d.ts +0 -2
  24. package/dist/components/data-table-header.d.ts +34 -16
  25. package/dist/components/data-table-header.js +132 -67
  26. package/dist/components/date-picker.d.ts +1 -1
  27. package/dist/components/dialog.d.ts +6 -3
  28. package/dist/components/dialog.js +2 -2
  29. package/dist/components/dropdown-menu.d.ts +5 -2
  30. package/dist/components/dropzone.d.ts +2 -2
  31. package/dist/components/dropzone.js +1 -1
  32. package/dist/components/file-input.d.ts +13 -8
  33. package/dist/components/file-input.js +24 -21
  34. package/dist/components/filter-chip.d.ts +11 -5
  35. package/dist/components/filter-chip.js +15 -6
  36. package/dist/components/floating-stepper.d.ts +11 -28
  37. package/dist/components/floating-stepper.js +2 -30
  38. package/dist/components/heading.d.ts +42 -0
  39. package/dist/components/heading.js +25 -0
  40. package/dist/components/icon-button.d.ts +1 -1
  41. package/dist/components/image-crop-dialog.d.ts +60 -0
  42. package/dist/components/image-crop-dialog.js +240 -0
  43. package/dist/components/image-crop-modal.d.ts +12 -55
  44. package/dist/components/image-crop-modal.js +2 -249
  45. package/dist/components/image-upload.d.ts +8 -17
  46. package/dist/components/image-upload.js +3 -3
  47. package/dist/components/index.d.ts +11 -8
  48. package/dist/components/index.js +8 -0
  49. package/dist/components/internal/button.d.ts +1 -1
  50. package/dist/components/internal/icons.d.ts +11 -1
  51. package/dist/components/internal/icons.js +20 -0
  52. package/dist/components/internal/menu.d.ts +3 -2
  53. package/dist/components/internal/menu.js +1 -1
  54. package/dist/components/internal/modal.js +9 -0
  55. package/dist/components/internal/toggle.d.ts +1 -1
  56. package/dist/components/item.d.ts +14 -7
  57. package/dist/components/item.js +5 -2
  58. package/dist/components/marker.d.ts +11 -3
  59. package/dist/components/marker.js +4 -3
  60. package/dist/components/number-input.d.ts +1 -1
  61. package/dist/components/progress.d.ts +3 -3
  62. package/dist/components/progress.js +2 -2
  63. package/dist/components/row-actions.d.ts +3 -0
  64. package/dist/components/row-actions.js +8 -4
  65. package/dist/components/saving-bar.d.ts +16 -4
  66. package/dist/components/saving-bar.js +37 -9
  67. package/dist/components/section-header.d.ts +4 -3
  68. package/dist/components/selectable-card.d.ts +2 -10
  69. package/dist/components/sidebar.d.ts +8 -11
  70. package/dist/components/sidebar.js +4 -5
  71. package/dist/components/spinner.d.ts +9 -6
  72. package/dist/components/spinner.js +3 -3
  73. package/dist/components/star-rating.d.ts +3 -3
  74. package/dist/components/star-rating.js +2 -2
  75. package/dist/components/stat.d.ts +18 -6
  76. package/dist/components/stat.js +9 -3
  77. package/dist/components/status.d.ts +4 -4
  78. package/dist/components/status.js +2 -2
  79. package/dist/components/stepper.d.ts +33 -0
  80. package/dist/components/stepper.js +36 -0
  81. package/dist/components/summary-bar.d.ts +3 -2
  82. package/dist/components/summary-bar.js +10 -1
  83. package/dist/components/tile.d.ts +5 -5
  84. package/dist/components/tile.js +2 -2
  85. package/dist/components/time-picker.d.ts +1 -1
  86. package/dist/components/toast.d.ts +17 -6
  87. package/dist/components/toast.js +5 -3
  88. package/dist/components/toggle-card-compact.d.ts +6 -25
  89. package/dist/components/toggle-card-compact.js +8 -35
  90. package/dist/components/toggle-card.d.ts +23 -9
  91. package/dist/components/toggle-card.js +38 -2
  92. package/dist/components/toggle.d.ts +1 -1
  93. package/dist/components/typing-indicator.d.ts +2 -2
  94. package/dist/components/typing-indicator.js +1 -1
  95. package/package.json +4 -4
  96. package/styles/base.css +13 -1
  97. package/styles/rds/components-styles.css +611 -173
  98. package/styles/rds/components.css +40 -25
  99. package/styles/rds/foundation.css +1 -1
  100. package/styles/rds/theme.css +40 -29
  101. package/styles/rds.css +1 -1
@@ -36,7 +36,11 @@ function Chart(_a) {
36
36
  showRightAxis = true,
37
37
  showLegend = true,
38
38
  showTooltip = true,
39
- showAllDates = true,
39
+ dates,
40
+ dateEvery,
41
+ showAllDates,
42
+ hrefs,
43
+ onSelect,
40
44
  showTable = false,
41
45
  height = 200,
42
46
  className
@@ -50,7 +54,11 @@ function Chart(_a) {
50
54
  "showRightAxis",
51
55
  "showLegend",
52
56
  "showTooltip",
57
+ "dates",
58
+ "dateEvery",
53
59
  "showAllDates",
60
+ "hrefs",
61
+ "onSelect",
54
62
  "showTable",
55
63
  "height",
56
64
  "className"
@@ -78,7 +86,14 @@ function Chart(_a) {
78
86
  return `${s.name} ${formatFor(s)((_a3 = s.data[index]) != null ? _a3 : 0)}`;
79
87
  }).join(", ");
80
88
  const legendName = (s) => dual ? `${s.name} (${onRight(s) ? "direita" : "esquerda"})` : s.name;
81
- const labelIndexes = showAllDates || count <= 3 ? labels.map((_, i) => i) : [0, Math.floor((count - 1) / 2), count - 1];
89
+ const every = dateEvery && dateEvery > 1 ? Math.floor(dateEvery) : null;
90
+ const allDates = (dates != null ? dates : showAllDates === void 0 ? "edges" : showAllDates ? "all" : "edges") === "all";
91
+ const labelIndexes = every ? labels.map((_, i) => i).filter((i) => i % every === 0) : allDates || count <= 3 ? labels.map((_, i) => i) : [0, Math.floor((count - 1) / 2), count - 1];
92
+ const linked = type !== "line" && Boolean(onSelect || (hrefs == null ? void 0 : hrefs.some(Boolean)));
93
+ const choose = (index) => {
94
+ if (onSelect) onSelect(index);
95
+ else if (hrefs == null ? void 0 : hrefs[index]) window.location.assign(hrefs[index]);
96
+ };
82
97
  const onPointerMove = (event) => {
83
98
  const box = event.currentTarget.getBoundingClientRect();
84
99
  const ratio = Math.min(1, Math.max(0, (event.clientX - box.left) / box.width));
@@ -94,6 +109,11 @@ function Chart(_a) {
94
109
  Home: 0,
95
110
  End: count - 1
96
111
  };
112
+ if (linked && event.key === "Enter" && active !== null) {
113
+ event.preventDefault();
114
+ choose(active);
115
+ return;
116
+ }
97
117
  if (!(event.key in keys)) return;
98
118
  event.preventDefault();
99
119
  setActive(keys[event.key]);
@@ -133,6 +153,7 @@ function Chart(_a) {
133
153
  onPointerLeave: (event) => {
134
154
  if (document.activeElement !== event.currentTarget) setActive(null);
135
155
  },
156
+ onClick: linked ? () => active !== null && choose(active) : void 0,
136
157
  onFocus: () => setActive((current) => current != null ? current : 0),
137
158
  onBlur: () => setActive(null),
138
159
  onKeyDown
@@ -142,19 +163,37 @@ function Chart(_a) {
142
163
  if (type === "bar") {
143
164
  const s = shown[0];
144
165
  const top = Math.max(0, ...(_a2 = s == null ? void 0 : s.data) != null ? _a2 : [0]);
145
- body = /* @__PURE__ */ jsx("div", { className: "rds-chart__bars", "aria-hidden": "true", children: labels.map((name, i) => {
166
+ body = /* @__PURE__ */ jsx("div", { className: "rds-chart__bars", "aria-hidden": linked ? void 0 : true, children: labels.map((name, i) => {
146
167
  var _a3, _b2;
147
- return /* @__PURE__ */ jsxs("div", { className: "rds-chart__bar-row", children: [
168
+ const value = s ? formatLeft((_a3 = s.data[i]) != null ? _a3 : 0) : "";
169
+ const parts = /* @__PURE__ */ jsxs(Fragment, { children: [
148
170
  /* @__PURE__ */ jsx("span", { className: "rds-chart__bar-label", children: name }),
149
171
  /* @__PURE__ */ jsx("span", { className: "rds-chart__track", children: /* @__PURE__ */ jsx(
150
172
  "span",
151
173
  {
152
174
  className: "rds-chart__bar",
153
- style: __spreadProps(__spreadValues({}, seriesStyle(i + 1)), { width: `${top ? ((_a3 = s == null ? void 0 : s.data[i]) != null ? _a3 : 0) / top * 100 : 0}%` })
175
+ style: __spreadProps(__spreadValues({}, seriesStyle(i + 1)), { width: `${top ? ((_b2 = s == null ? void 0 : s.data[i]) != null ? _b2 : 0) / top * 100 : 0}%` })
154
176
  }
155
177
  ) }),
156
- /* @__PURE__ */ jsx("span", { className: "rds-chart__bar-value", children: s ? formatLeft((_b2 = s.data[i]) != null ? _b2 : 0) : "" })
157
- ] }, name);
178
+ /* @__PURE__ */ jsx("span", { className: "rds-chart__bar-value", children: value })
179
+ ] });
180
+ const href = hrefs == null ? void 0 : hrefs[i];
181
+ const accessibleName = `${name}: ${value}`;
182
+ if (linked && href && !onSelect)
183
+ return /* @__PURE__ */ jsx("a", { href, className: "rds-chart__bar-row rds-chart__bar-row--link", "aria-label": accessibleName, children: parts }, name);
184
+ if (linked && onSelect)
185
+ return /* @__PURE__ */ jsx(
186
+ "button",
187
+ {
188
+ type: "button",
189
+ className: "rds-chart__bar-row rds-chart__bar-row--link",
190
+ "aria-label": accessibleName,
191
+ onClick: () => onSelect(i),
192
+ children: parts
193
+ },
194
+ name
195
+ );
196
+ return /* @__PURE__ */ jsx("div", { className: "rds-chart__bar-row", children: parts }, name);
158
197
  }) });
159
198
  } else {
160
199
  body = /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -208,7 +247,10 @@ function Chart(_a) {
208
247
  ] })),
209
248
  rightScale && /* @__PURE__ */ jsx(Axis, { ticks: rightScale.ticks, format: formatRight, side: "right" })
210
249
  ] }),
211
- /* @__PURE__ */ jsx("div", { className: "rds-chart__labels", "aria-hidden": "true", children: /* @__PURE__ */ jsx("div", { className: `rds-chart__labels-track rds-chart__labels-track--${type}`, children: labelIndexes.map((i) => /* @__PURE__ */ jsx("span", { className: "rds-chart__label", style: { left: `${x(i)}%` }, children: labels[i] }, i)) }) })
250
+ /* @__PURE__ */ jsx("div", { className: "rds-chart__labels", "aria-hidden": "true", children: /* @__PURE__ */ jsxs("div", { className: `rds-chart__labels-track rds-chart__labels-track--${type}${every ? " rds-chart__labels-track--ticks" : ""}`, children: [
251
+ every && labels.map((_, i) => /* @__PURE__ */ jsx("i", { className: "rds-chart__tick", style: { left: `${x(i)}%` } }, `t${i}`)),
252
+ labelIndexes.map((i) => /* @__PURE__ */ jsx("span", { className: "rds-chart__label", style: { left: `${x(i)}%` }, children: labels[i] }, i))
253
+ ] }) })
212
254
  ] });
213
255
  }
214
256
  const firstColumn = type === "line" ? "Data" : "Categoria";
@@ -216,7 +258,7 @@ function Chart(_a) {
216
258
  "figure",
217
259
  __spreadProps(__spreadValues({}, rest), {
218
260
  "aria-label": label,
219
- className: ["rds-chart", `rds-chart--${type}`, dual && "rds-chart--dual", className].filter(Boolean).join(" "),
261
+ className: ["rds-chart", `rds-chart--${type}`, dual && "rds-chart--dual", linked && "rds-chart--linked", className].filter(Boolean).join(" "),
220
262
  children: [
221
263
  body,
222
264
  showLegend && type !== "bar" && /* @__PURE__ */ jsx("ul", { className: "rds-chart__legend", "aria-hidden": "true", children: shown.map((s, n) => /* @__PURE__ */ jsxs("li", { children: [
@@ -229,26 +271,30 @@ function Chart(_a) {
229
271
  shown.map((s) => /* @__PURE__ */ jsx(TableHead, { align: "end", children: legendName(s) }, s.name))
230
272
  ] }) }),
231
273
  /* @__PURE__ */ jsx(TableBody, { children: labels.map((name, i) => /* @__PURE__ */ jsxs(TableRow, { children: [
232
- /* @__PURE__ */ jsx(TableCell, { children: name }),
274
+ /* @__PURE__ */ jsx(TableCell, { children: linked && onSelect ? /* @__PURE__ */ jsx("button", { type: "button", className: "rds-chart__table-link", onClick: () => onSelect(i), children: name }) : linked && (hrefs == null ? void 0 : hrefs[i]) ? /* @__PURE__ */ jsx("a", { className: "rds-chart__table-link", href: hrefs[i], children: name }) : name }),
233
275
  shown.map((s) => {
234
276
  var _a3;
235
277
  return /* @__PURE__ */ jsx(TableCell, { align: "end", children: formatFor(s)((_a3 = s.data[i]) != null ? _a3 : 0) }, s.name);
236
278
  })
237
279
  ] }, name)) })
238
- ] }) : /* @__PURE__ */ jsxs("table", { className: "rds-visually-hidden", children: [
239
- /* @__PURE__ */ jsx("caption", { children: label }),
240
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
241
- /* @__PURE__ */ jsx("th", { scope: "col", children: firstColumn }),
242
- shown.map((s) => /* @__PURE__ */ jsx("th", { scope: "col", children: legendName(s) }, s.name))
243
- ] }) }),
244
- /* @__PURE__ */ jsx("tbody", { children: labels.map((name, i) => /* @__PURE__ */ jsxs("tr", { children: [
245
- /* @__PURE__ */ jsx("th", { scope: "row", children: name }),
246
- shown.map((s) => {
247
- var _a3;
248
- return /* @__PURE__ */ jsx("td", { children: formatFor(s)((_a3 = s.data[i]) != null ? _a3 : 0) }, s.name);
249
- })
250
- ] }, name)) })
251
- ] })
280
+ ] }) : (
281
+ // The clip goes on a wrapper: a <table> ignores the 1px box and overflow of .rds-visually-hidden, so it
282
+ // kept its full size, anchored to the page and stretched the page scroll.
283
+ /* @__PURE__ */ jsx("div", { className: "rds-visually-hidden", children: /* @__PURE__ */ jsxs("table", { children: [
284
+ /* @__PURE__ */ jsx("caption", { children: label }),
285
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
286
+ /* @__PURE__ */ jsx("th", { scope: "col", children: firstColumn }),
287
+ shown.map((s) => /* @__PURE__ */ jsx("th", { scope: "col", children: legendName(s) }, s.name))
288
+ ] }) }),
289
+ /* @__PURE__ */ jsx("tbody", { children: labels.map((name, i) => /* @__PURE__ */ jsxs("tr", { children: [
290
+ /* @__PURE__ */ jsx("th", { scope: "row", children: name }),
291
+ shown.map((s) => {
292
+ var _a3;
293
+ return /* @__PURE__ */ jsx("td", { children: formatFor(s)((_a3 = s.data[i]) != null ? _a3 : 0) }, s.name);
294
+ })
295
+ ] }, name)) })
296
+ ] }) })
297
+ )
252
298
  ]
253
299
  })
254
300
  );
@@ -18,7 +18,7 @@ interface ChoiceCarouselProps<T> {
18
18
  /**
19
19
  * ChoiceCarousel — a horizontal, scroll-snapped row of options to pick one (radiogroup) or several (group of
20
20
  * checkboxes); the options are drawn by `renderCard`. On a wide screen two outline IconButtons (with their Tooltips)
21
- * scroll it by one option; the arrow keys do the same on the row. Styles: choice-carousel.css.
21
+ * scroll it by one option, each one there only while there is more that way; the arrow keys do the same on the row. Styles: choice-carousel.css.
22
22
  */
23
23
  declare function ChoiceCarousel<T>({ options, getKey, renderCard, value, onChange, multiple, ariaLabel, isDisabled, }: ChoiceCarouselProps<T>): react.JSX.Element;
24
24
 
@@ -75,7 +75,7 @@ function ChoiceCarousel({
75
75
  }
76
76
  };
77
77
  return /* @__PURE__ */ jsxs("div", { className: "rds-choice-carousel", children: [
78
- /* @__PURE__ */ jsx(Tooltip, { text: "Anterior", children: /* @__PURE__ */ jsx(
78
+ canScrollLeft && /* @__PURE__ */ jsx(Tooltip, { text: "Anterior", children: /* @__PURE__ */ jsx(
79
79
  IconButton,
80
80
  {
81
81
  className: "rds-choice-carousel__arrow rds-choice-carousel__arrow--prev",
@@ -84,7 +84,6 @@ function ChoiceCarousel({
84
84
  variant: "outline",
85
85
  tone: "neutral",
86
86
  onClick: () => scrollByAmount(-1),
87
- disabled: !canScrollLeft,
88
87
  tabIndex: -1
89
88
  }
90
89
  ) }),
@@ -123,7 +122,7 @@ function ChoiceCarousel({
123
122
  })
124
123
  }
125
124
  ),
126
- /* @__PURE__ */ jsx(Tooltip, { text: "Pr\xF3ximo", children: /* @__PURE__ */ jsx(
125
+ canScrollRight && /* @__PURE__ */ jsx(Tooltip, { text: "Pr\xF3ximo", children: /* @__PURE__ */ jsx(
127
126
  IconButton,
128
127
  {
129
128
  className: "rds-choice-carousel__arrow rds-choice-carousel__arrow--next",
@@ -132,7 +131,6 @@ function ChoiceCarousel({
132
131
  variant: "outline",
133
132
  tone: "neutral",
134
133
  onClick: () => scrollByAmount(1),
135
- disabled: !canScrollRight,
136
134
  tabIndex: -1
137
135
  }
138
136
  ) })
@@ -0,0 +1,40 @@
1
+ import * as react from 'react';
2
+ import { ComponentPropsWithRef, ReactNode } from 'react';
3
+
4
+ interface ChoiceListProps extends Omit<ComponentPropsWithRef<'ul'>, 'children' | 'defaultValue' | 'onChange'> {
5
+ /** The ChoiceListItems (Figma: the slot `items`). */
6
+ children: ReactNode;
7
+ /** Controlled: the chosen row's value. */
8
+ value?: string;
9
+ /** Uncontrolled: the row chosen at first. */
10
+ defaultValue?: string;
11
+ onValueChange?: (value: string) => void;
12
+ }
13
+ /**
14
+ * ChoiceList — Figma [RDS] Content/ChoiceList. A dense list to choose one thing from: a client, a product, an
15
+ * order. Each row is media, a title, a muted description and a trailing value; a line under each row, dozens on
16
+ * screen. One chosen at a time, marked by the tint and a bar on the left (role listbox, aria-selected). The list
17
+ * takes the focus: the arrows move the active row past disabled ones, Home and End go to the ends, Enter or Space
18
+ * choose, a click chooses. Name it with aria-label or aria-labelledby. Styles: choice-list.css.
19
+ *
20
+ * Not for 2 to 4 options that need an explanation (ChoiceCard), nor for a list that only shows (Item).
21
+ */
22
+ declare function ChoiceList({ children, value, defaultValue, onValueChange, className, onKeyDown, onFocus, ref, ...rest }: ChoiceListProps): react.JSX.Element;
23
+ interface ChoiceListItemProps {
24
+ /** The value it stands for. */
25
+ value: string;
26
+ /** The name, one line (Figma: `title`). It is the row's accessible name. */
27
+ title: ReactNode;
28
+ /** One muted line under the title (Figma: `showDescription` + `description`). */
29
+ description?: ReactNode;
30
+ /** An Avatar for a person, a Tile for a thing, 32 (Figma: `showMedia` + `media`). Decorative: hidden from screen readers. */
31
+ media?: ReactNode;
32
+ /** A value or a date on the right (Figma: `showTrailing` + `trailing`). */
33
+ trailing?: ReactNode;
34
+ /** Cannot be chosen now: skipped by the arrows, read as unavailable. */
35
+ disabled?: boolean;
36
+ }
37
+ /** One row of the ChoiceList (Figma: .choice-list/item). The whole row is the target. */
38
+ declare function ChoiceListItem({ value, title, description, media, trailing, disabled }: ChoiceListItemProps): react.JSX.Element;
39
+
40
+ export { ChoiceList, ChoiceListItem, type ChoiceListItemProps, type ChoiceListProps };
@@ -0,0 +1,122 @@
1
+ "use client";
2
+ import {
3
+ __objRest,
4
+ __spreadProps,
5
+ __spreadValues
6
+ } from "../chunk-ORMEWXMH.js";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import {
9
+ createContext,
10
+ useContext,
11
+ useId,
12
+ useRef,
13
+ useState
14
+ } from "react";
15
+ import { warnIfUnlabelled } from "./internal/field.js";
16
+ const ChoiceListContext = createContext(null);
17
+ function ChoiceList(_a) {
18
+ var _b = _a, { children, value, defaultValue, onValueChange, className, onKeyDown, onFocus, ref } = _b, rest = __objRest(_b, ["children", "value", "defaultValue", "onValueChange", "className", "onKeyDown", "onFocus", "ref"]);
19
+ warnIfUnlabelled("ChoiceList", void 0, rest["aria-label"], rest["aria-labelledby"]);
20
+ const [own, setOwn] = useState(defaultValue);
21
+ const selected = value !== void 0 ? value : own;
22
+ const [activeId, setActiveId] = useState(null);
23
+ const list = useRef(null);
24
+ const rows = () => {
25
+ var _a2, _b2;
26
+ return Array.from((_b2 = (_a2 = list.current) == null ? void 0 : _a2.querySelectorAll('[role="option"]')) != null ? _b2 : []).filter(
27
+ (o) => o.getAttribute("aria-disabled") !== "true"
28
+ );
29
+ };
30
+ function choose(next) {
31
+ if (value === void 0) setOwn(next);
32
+ onValueChange == null ? void 0 : onValueChange(next);
33
+ }
34
+ function activate(row) {
35
+ if (!row) return;
36
+ setActiveId(row.id);
37
+ row.scrollIntoView({ block: "nearest" });
38
+ }
39
+ function keyDown(event) {
40
+ var _a2;
41
+ onKeyDown == null ? void 0 : onKeyDown(event);
42
+ if (event.defaultPrevented) return;
43
+ const all = rows();
44
+ const index = all.findIndex((o) => o.id === activeId);
45
+ const moves = {
46
+ ArrowDown: () => all[Math.min(index + 1, all.length - 1)],
47
+ ArrowUp: () => all[Math.max(index - 1, 0)],
48
+ Home: () => all[0],
49
+ End: () => all[all.length - 1]
50
+ };
51
+ if (moves[event.key]) {
52
+ event.preventDefault();
53
+ activate(moves[event.key]());
54
+ } else if ((event.key === "Enter" || event.key === " ") && index >= 0) {
55
+ event.preventDefault();
56
+ choose((_a2 = all[index].dataset.value) != null ? _a2 : "");
57
+ }
58
+ }
59
+ function setRef(node) {
60
+ list.current = node;
61
+ if (typeof ref === "function") ref(node);
62
+ else if (ref) ref.current = node;
63
+ }
64
+ return /* @__PURE__ */ jsx(ChoiceListContext.Provider, { value: { selected, activeId, setActiveId, choose }, children: /* @__PURE__ */ jsx(
65
+ "ul",
66
+ __spreadProps(__spreadValues({
67
+ tabIndex: 0
68
+ }, rest), {
69
+ ref: setRef,
70
+ role: "listbox",
71
+ "aria-activedescendant": activeId != null ? activeId : void 0,
72
+ className: ["rds-choice-list", className].filter(Boolean).join(" "),
73
+ onKeyDown: keyDown,
74
+ onFocus: (event) => {
75
+ var _a2;
76
+ onFocus == null ? void 0 : onFocus(event);
77
+ if (activeId && document.getElementById(activeId)) return;
78
+ const all = rows();
79
+ activate((_a2 = all.find((o) => o.dataset.value === selected)) != null ? _a2 : all[0]);
80
+ },
81
+ children
82
+ })
83
+ ) });
84
+ }
85
+ function ChoiceListItem({ value, title, description, media, trailing, disabled }) {
86
+ const context = useContext(ChoiceListContext);
87
+ const id = useId();
88
+ if (!context) throw new Error("[@rojaostudio/ds] ChoiceListItem goes inside a ChoiceList.");
89
+ const selected = context.selected === value;
90
+ const describedBy = [description != null && `${id}-description`, trailing != null && `${id}-trailing`].filter(Boolean).join(" ");
91
+ return /* @__PURE__ */ jsxs(
92
+ "li",
93
+ {
94
+ id,
95
+ role: "option",
96
+ "data-value": value,
97
+ "aria-selected": selected,
98
+ "aria-disabled": disabled || void 0,
99
+ "aria-labelledby": `${id}-title`,
100
+ "aria-describedby": describedBy || void 0,
101
+ "data-active": context.activeId === id ? "" : void 0,
102
+ className: "rds-choice-list__item",
103
+ onClick: () => {
104
+ if (disabled) return;
105
+ context.setActiveId(id);
106
+ context.choose(value);
107
+ },
108
+ children: [
109
+ media != null && /* @__PURE__ */ jsx("span", { className: "rds-choice-list__media", "aria-hidden": "true", children: media }),
110
+ /* @__PURE__ */ jsxs("span", { className: "rds-choice-list__content", children: [
111
+ /* @__PURE__ */ jsx("span", { id: `${id}-title`, className: "rds-choice-list__title", children: title }),
112
+ description != null && /* @__PURE__ */ jsx("span", { id: `${id}-description`, className: "rds-choice-list__description", children: description })
113
+ ] }),
114
+ trailing != null && /* @__PURE__ */ jsx("span", { id: `${id}-trailing`, className: "rds-choice-list__trailing", children: trailing })
115
+ ]
116
+ }
117
+ );
118
+ }
119
+ export {
120
+ ChoiceList,
121
+ ChoiceListItem
122
+ };
@@ -9,18 +9,12 @@ interface ChoicePreviewCardProps {
9
9
  preview: ReactNode;
10
10
  label: string;
11
11
  description?: string;
12
- /** Ignored: the ChoiceCard has no locked state. */
13
- locked?: boolean;
14
12
  disabled?: boolean;
15
- /** Ignored: the ChoiceCard has no badge on the picture. */
16
- badge?: ReactNode;
17
- /** Ignored: the picture is always 16:9. */
18
- previewAspect?: 'square' | 'video' | 'wide';
19
13
  className?: string;
20
14
  }
21
15
  /**
22
16
  * @deprecated Use ChoiceCard with layout="preview" (Figma [RDS] Content/ChoiceCard). A thin wrapper over it: `label`
23
- * is the children. It is a native radio now, not a toggle button; `locked`, `badge` and `previewAspect` are ignored.
17
+ * is the children. It is a native radio now, not a toggle button (`locked`, `badge` and `previewAspect` left in 2.0).
24
18
  */
25
19
  declare function ChoicePreviewCard({ selected, onSelect, preview, label, description, disabled, className }: ChoicePreviewCardProps): react.JSX.Element;
26
20
 
@@ -35,7 +35,7 @@ declare function normalizeHex(text: string): string | null;
35
35
  /**
36
36
  * ColorInput — Figma [RDS] Forms/ColorInput. One colour, chosen or typed: the swatch shows it and the hex beside it
37
37
  * is editable (#RRGGBB, with or without #). The swatch opens a popover with the palette the caller passes (Figma:
38
- * menu=open); without one, the system's colour picker. Enter or leaving the field confirms the hex; an invalid hex
38
+ * open=true); without one, the system's colour picker. Enter or leaving the field confirms the hex; an invalid hex
39
39
  * goes back to the last valid one. The swatch's colour is the person's data, not a token: it is the one inline
40
40
  * style the DS allows (style.backgroundColor of the swatch and of each palette colour). Choosing among a few fixed
41
41
  * colours without a hex is the ToggleGroup or the ChoiceCard. Styles: color-input.css and internal/field.css.
@@ -28,8 +28,11 @@ declare function ContextMenu({ children, items, disabled, onOpenChange, classNam
28
28
  interface ContextMenuItemProps extends MenuItemContentProps {
29
29
  /** Runs when the item is chosen; the menu then closes. */
30
30
  onSelect?: () => void;
31
- /** danger for what destroys: last, after a separator. */
32
- tone?: ContextMenuItemTone;
31
+ /**
32
+ * neutral (default), or danger for what destroys: last, after a separator (Figma: `tone`). `'default'` is
33
+ * deprecated (2.0.0-next): it is `'neutral'`.
34
+ */
35
+ tone?: ContextMenuItemTone | 'default';
33
36
  disabled?: boolean;
34
37
  textValue?: string;
35
38
  }
@@ -30,8 +30,6 @@ interface CurrencyInputProps {
30
30
  maxDigits?: number;
31
31
  /** Shows 0,00 instead of the placeholder when the value is zero. */
32
32
  showZero?: boolean;
33
- /** @deprecated The [RDS] Input has one height (44). Ignored. */
34
- size?: 'sm' | 'md' | 'lg';
35
33
  id?: string;
36
34
  className?: string;
37
35
  }
@@ -20,35 +20,53 @@ type DataTableFilterDef = {
20
20
  options: DataTableFilterOption[];
21
21
  onChange: (v: string) => void;
22
22
  };
23
- type DataTablePillDef = {
24
- key: string;
25
- label: string;
26
- active: boolean;
27
- count?: number;
28
- onClick: () => void;
29
- };
30
23
  type DataTableHeaderProps = {
31
24
  search?: DataTableHeaderSearch;
32
25
  filters?: DataTableFilterDef[];
33
- /** Quick filters, always in view: FilterChips. */
34
- pillFilters?: DataTablePillDef[];
26
+ /**
27
+ * Quick filters, always in view (Figma: `showQuickFilters` + the `quickFilters` slot): up to three, a
28
+ * FilterChipGroup with its FilterChips; four or more, one Button with a menu (DropdownMenu), "Categoria: Todas".
29
+ */
30
+ quickFilters?: ReactNode;
31
+ /** Clears the `filters` (the quick filters are cleared where they are, in view). */
35
32
  onClear?: () => void;
33
+ /**
34
+ * A view control after the filters and before the actions (Figma: `showView` + the `view` slot), such as a
35
+ * Checkbox "Agrupar por produto". In view in the compact arrangement too.
36
+ */
37
+ view?: ReactNode;
38
+ /**
39
+ * The list's action (Figma: `showActions`, off by default, + the `actions` instance): an IconButton, neutral outline
40
+ * md, with its Tooltip, such as a gear "Organizar categorias" or exporting. It sits outside the tools, always at the
41
+ * end of the FIRST line, on the right; the tools wrap, the action never goes down.
42
+ * Creating is NOT an action of the bar: creating is the FAB. The component does not enforce this; it documents it.
43
+ */
36
44
  actions?: ReactNode;
37
45
  className?: string;
38
- /** On a narrow screen, moves the filters and the actions into a Drawer. The quick filters stay in view. */
46
+ /** In the compact arrangement (bar below 1024), moves the filters and the actions into a Drawer. The quick filters stay in view. */
39
47
  mobileCollapse?: boolean;
40
48
  };
41
- /** One filter as a DropdownMenu of radio items (one filter on a wide screen). */
49
+ /** One filter as a DropdownMenu of radio items (one filter, expanded). */
42
50
  declare function FilterDropdown({ f, placement }: {
43
51
  f: DataTableFilterDef;
44
52
  placement?: 'bottom-start' | 'bottom-end';
45
53
  }): react.JSX.Element;
46
54
  /**
47
55
  * DataTableHeader — a composition of the Input (search), FilterChips, Buttons, the DropdownMenu, the Popover and
48
- * the Drawer: the bar above a table. The search fills the row; quick filters are FilterChips; one filter is a
49
- * dropdown, two or more collapse into "Filtros" (the active ones stay in view as removable Chips). From 768 the
50
- * wide layout shows; below it, the filters open in a Drawer or a Popover. Styles: data-table-header.css.
56
+ * the Drawer: the bar above a table. A row that never wraps: the tools (the search, the quick filters, the filters,
57
+ * the view control) wrap inside their own group; the action stays outside it, at the end of the first line, on the
58
+ * right. The search is always on the left and takes the free width (at least 320); the filters are always on the
59
+ * right; what does not fit wraps. Quick filters go in the `quickFilters` slot; one filter
60
+ * is a dropdown, two or more collapse into "Filtros" (the active ones stay in view as removable Chips); the `view`
61
+ * control comes after the filters, before the actions. "Filtros · N" counts the active `filters`, the ones that
62
+ * button opens.
63
+ *
64
+ * Two arrangements, by the screen width, as the Figma viewport mode (layout/compact below lg 1024; the SavingBar's cut):
65
+ * expanded from 1024, the Separator and the Buttons with their labels; compact below it, the search accepts 200 and
66
+ * the filter is an outline IconButton (sliders, 44) with a dot (one filter on) or a counter (several), opening the
67
+ * same Drawer or Popover. There is no screen prop.
68
+ * Styles: data-table-header.css.
51
69
  */
52
- declare function DataTableHeader({ search, filters, pillFilters, onClear, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
70
+ declare function DataTableHeader({ search, filters, quickFilters, onClear, view, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
53
71
 
54
- export { type DataTableFilterDef, type DataTableFilterOption, DataTableHeader, type DataTableHeaderProps, type DataTableHeaderSearch, type DataTablePillDef, FilterDropdown };
72
+ export { type DataTableFilterDef, type DataTableFilterOption, DataTableHeader, type DataTableHeaderProps, type DataTableHeaderSearch, FilterDropdown };