@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
@@ -3,19 +3,19 @@ import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
4
  type StatusTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
5
5
  /**
6
- * Figma calls this property `style`: outline (white pill with a hairline, for coloured bands), soft (light plate
6
+ * The emphasis (Figma: `variant`): outline (white pill with a hairline, for coloured bands), soft (light plate
7
7
  * with the tone's dark text, for dark backgrounds), fill (the tone's plate, for neutral backgrounds).
8
8
  */
9
9
  type StatusVariant = 'outline' | 'soft' | 'fill';
10
- type StatusSize = 'default' | 'sm';
10
+ type StatusSize = 'md' | 'sm';
11
11
  interface StatusProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
12
12
  /** The state, in one or two words (Figma: `label`). The text says the state; the dot only adds colour. */
13
13
  children: ReactNode;
14
14
  /** neutral (a record: draft, closed), info (in progress), success (done), warning (pending), danger (failed). */
15
15
  tone?: StatusTone;
16
16
  variant?: StatusVariant;
17
- /** default 32 tall; sm 24 (dot 6), for narrow cards and table rows. */
18
- size?: StatusSize;
17
+ /** md 32 tall (default); sm 24 (dot 6), for narrow cards and table rows. `'default'` is deprecated (2.0.0-next): it is `'md'`. */
18
+ size?: StatusSize | 'default';
19
19
  }
20
20
  /**
21
21
  * Status — Figma [RDS] Indicators/Status. A state that changes over time ("Em análise", "Concluído"): a pill with a
@@ -8,7 +8,7 @@ function Status(_a) {
8
8
  var _b = _a, {
9
9
  tone = "neutral",
10
10
  variant = "outline",
11
- size = "default",
11
+ size = "md",
12
12
  children,
13
13
  className
14
14
  } = _b, rest = __objRest(_b, [
@@ -21,7 +21,7 @@ function Status(_a) {
21
21
  return /* @__PURE__ */ jsxs(
22
22
  "span",
23
23
  __spreadProps(__spreadValues({}, rest), {
24
- className: ["rds-status", `rds-status--${tone}-${variant}`, `rds-status--${size}`, className].filter(Boolean).join(" "),
24
+ className: ["rds-status", `rds-status--${tone}-${variant}`, `rds-status--${size === "default" ? "md" : size}`, className].filter(Boolean).join(" "),
25
25
  children: [
26
26
  /* @__PURE__ */ jsx("span", { className: "rds-status__dot", "aria-hidden": "true" }),
27
27
  children
@@ -0,0 +1,33 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * Stepper — a composition of the Card (as a pill) and Buttons (Figma [RDS] Actions/Button, neutral): the
6
+ * floating steps of a flow (point of sale, checkout). The current step is the filled Button (aria-current="step");
7
+ * earlier steps go back, later ones are disabled; `canNavigate` changes the rule. `action` is a last Button after
8
+ * a vertical Separator (Reset). Where it floats is the caller's (className or a wrapper). Styles: stepper.css.
9
+ */
10
+ type StepperStep = {
11
+ key: string;
12
+ label: string;
13
+ };
14
+ interface StepperProps {
15
+ steps: StepperStep[];
16
+ /** key da etapa atual */
17
+ current: string;
18
+ onNavigate?: (key: string) => void;
19
+ /** Regra de navegação por etapa. Default: só etapas anteriores à atual. */
20
+ canNavigate?: (key: string, index: number, currentIndex: number) => boolean;
21
+ /** Ação à direita, separada por divisor (ex.: Reset). */
22
+ action?: {
23
+ label: string;
24
+ icon?: ReactNode;
25
+ onClick: () => void;
26
+ };
27
+ className?: string;
28
+ /** The navigation's name. Default "Etapas". */
29
+ 'aria-label'?: string;
30
+ }
31
+ declare function Stepper({ steps, current, onNavigate, canNavigate, action, className, 'aria-label': ariaLabel }: StepperProps): react.JSX.Element;
32
+
33
+ export { Stepper, type StepperProps, type StepperStep };
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import "../chunk-ORMEWXMH.js";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { Button } from "./button.js";
5
+ import { Card } from "./card.js";
6
+ import { Separator } from "./separator.js";
7
+ function Stepper({ steps, current, onNavigate, canNavigate, action, className, "aria-label": ariaLabel = "Etapas" }) {
8
+ const currentIdx = steps.findIndex((s) => s.key === current);
9
+ return /* @__PURE__ */ jsxs(Card, { as: "div", size: "sm", role: "navigation", "aria-label": ariaLabel, className: ["rds-stepper", className].filter(Boolean).join(" "), children: [
10
+ steps.map((s, idx) => {
11
+ const isCurrent = idx === currentIdx;
12
+ const canGo = canNavigate ? canNavigate(s.key, idx, currentIdx) : idx < currentIdx;
13
+ return /* @__PURE__ */ jsx(
14
+ Button,
15
+ {
16
+ tone: "neutral",
17
+ variant: isCurrent ? "fill" : "ghost",
18
+ disabled: !canGo && !isCurrent,
19
+ "aria-current": isCurrent ? "step" : void 0,
20
+ onClick: () => {
21
+ if (canGo && !isCurrent) onNavigate == null ? void 0 : onNavigate(s.key);
22
+ },
23
+ children: s.label
24
+ },
25
+ s.key
26
+ );
27
+ }),
28
+ action && /* @__PURE__ */ jsxs(Fragment, { children: [
29
+ /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "rds-stepper__divider" }),
30
+ /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "ghost", icon: action.icon, onClick: action.onClick, children: action.label })
31
+ ] })
32
+ ] });
33
+ }
34
+ export {
35
+ Stepper
36
+ };
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
- import { StatTone } from './stat.js';
3
+ import { StatTone, LegacyStatTone } from './stat.js';
4
4
 
5
5
  /** @deprecated Use StatTone. */
6
6
  type SummaryBarTone = StatTone;
@@ -8,7 +8,8 @@ type SummaryBarTone = StatTone;
8
8
  interface SummaryBarItem {
9
9
  label: string;
10
10
  value: string;
11
- tone?: StatTone;
11
+ /** `'muted'` (the 2.0.0-next tone) is the Stat's `muted`. */
12
+ tone?: StatTone | LegacyStatTone | 'muted';
12
13
  /** Ignored: the Stat has no icon in the Figma [RDS]. */
13
14
  icon?: ReactNode;
14
15
  }
@@ -9,7 +9,16 @@ import { Children } from "react";
9
9
  import { Stat, StatFramedDefault } from "./stat.js";
10
10
  function SummaryBar(_a) {
11
11
  var _b = _a, { children, layout = "row", items, className } = _b, rest = __objRest(_b, ["children", "layout", "items", "className"]);
12
- const cells = items ? items.map((item, i) => /* @__PURE__ */ jsx(Stat, { label: item.label, value: item.value, tone: item.tone }, i)) : Children.toArray(children);
12
+ const cells = items ? items.map((item, i) => /* @__PURE__ */ jsx(
13
+ Stat,
14
+ {
15
+ label: item.label,
16
+ value: item.value,
17
+ tone: item.tone === "muted" ? void 0 : item.tone,
18
+ muted: item.tone === "muted"
19
+ },
20
+ i
21
+ )) : Children.toArray(children);
13
22
  return /* @__PURE__ */ jsx(StatFramedDefault.Provider, { value: false, children: /* @__PURE__ */ jsx("ul", __spreadProps(__spreadValues({}, rest), { className: ["rds-summary-bar", `rds-summary-bar--${layout}`, className].filter(Boolean).join(" "), children: cells.map((cell, i) => /* @__PURE__ */ jsx("li", { className: "rds-summary-bar__cell", children: cell }, i)) })) });
14
23
  }
15
24
  export {
@@ -2,18 +2,18 @@ import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
4
  type TileTone = 'action' | 'neutral' | 'info' | 'success' | 'warning' | 'danger';
5
- /** Figma calls this property `style`; here it is `variant` because `style` belongs to React. */
5
+ /** The emphasis (Figma: `variant`). */
6
6
  type TileVariant = 'fill' | 'soft';
7
- type TileSize = 'sm' | 'default' | 'lg';
7
+ type TileSize = 'sm' | 'md' | 'lg';
8
8
  interface TileProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
9
9
  /** The icon (Figma: `icon`), an inline SVG. The Tile sizes it: 16, 24 or 32. */
10
10
  icon: ReactNode;
11
11
  /** action is the brand; the others follow feedback: success only for what went right, danger for what went wrong. */
12
12
  tone?: TileTone;
13
- /** fill is strong; soft is light, with the icon in the tone's colour (Figma: `style`). Same variant across a list. */
13
+ /** fill is strong; soft is light, with the icon in the tone's colour (Figma: `variant`). Same variant across a list. */
14
14
  variant?: TileVariant;
15
- /** sm 32, default 48, lg 64. */
16
- size?: TileSize;
15
+ /** sm 32, md 48 (default), lg 64 (Figma: `size`). `'default'` is deprecated (2.0.0-next): it is `'md'`. */
16
+ size?: TileSize | 'default';
17
17
  }
18
18
  /**
19
19
  * Tile — Figma [RDS] Content/Tile. An icon with weight, in a circle: a benefit in a list, a card's header, the top
@@ -5,13 +5,13 @@ import {
5
5
  } from "../chunk-ORMEWXMH.js";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  function Tile(_a) {
8
- var _b = _a, { icon, tone = "action", variant = "fill", size = "default", className } = _b, rest = __objRest(_b, ["icon", "tone", "variant", "size", "className"]);
8
+ var _b = _a, { icon, tone = "action", variant = "fill", size = "md", className } = _b, rest = __objRest(_b, ["icon", "tone", "variant", "size", "className"]);
9
9
  return /* @__PURE__ */ jsx(
10
10
  "span",
11
11
  __spreadProps(__spreadValues({
12
12
  "aria-hidden": "true"
13
13
  }, rest), {
14
- className: ["rds-tile", `rds-tile--${tone}-${variant}`, `rds-tile--${size}`, className].filter(Boolean).join(" "),
14
+ className: ["rds-tile", `rds-tile--${tone}-${variant}`, `rds-tile--${size === "default" ? "md" : size}`, className].filter(Boolean).join(" "),
15
15
  children: icon
16
16
  })
17
17
  );
@@ -38,7 +38,7 @@ declare function parseTime(text: string): string | null;
38
38
  declare function formatTime(time: string, format?: TimeFormat): string;
39
39
  /**
40
40
  * TimePicker — Figma [RDS] Forms/TimePicker. A time field that takes typing (HH:mm, the colon comes by itself) and
41
- * opens the list of times in the chosen step (Figma: menu=open). It is the Input with the clock at the end and the
41
+ * opens the list of times in the chosen step (Figma: open=true). It is the Input with the clock at the end and the
42
42
  * Listbox under it (ARIA combobox), as the DatePicker is the Input with the Calendar: the focus stays in the field,
43
43
  * the arrows walk the list, Enter chooses and Escape closes without changing. No tokens of its own (--input-*,
44
44
  * --listbox-*). A date is the DatePicker; a duration, the NumberInput. Styles: time-picker.css,
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
 
4
4
  type ToastTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
5
- /** Figma calls this property `style`: outline (white with a border, the default), soft (light plate), fill (full plate). */
5
+ /** The emphasis (Figma: `variant`): outline (white with a border, the default), soft (light plate), fill (full plate). */
6
6
  type ToastVariant = 'outline' | 'soft' | 'fill';
7
7
  interface ToastOptions {
8
8
  /** What happened, in a few words (Figma: `title`). */
@@ -14,12 +14,18 @@ interface ToastOptions {
14
14
  variant?: ToastVariant;
15
15
  /** The tone's icon (Figma: `showIcon`). Decorative. */
16
16
  showIcon?: boolean;
17
- /** One action (Figma: `showAction`): "Desfazer", "Ver". With an action it stays at least 6 s. */
17
+ /**
18
+ * One action (Figma: `showAction`): "Desfazer", "Ver". A toast with an action does not close by itself (WCAG 2.2.1,
19
+ * Timing Adjustable): it stays until the person uses the action or the ×. Choosing the action also closes it.
20
+ */
18
21
  action?: {
19
22
  label: string;
20
23
  onClick: () => void;
21
24
  };
22
- /** ms on screen. Default 5 s, 6 s with an action. It pauses while the mouse or the focus is on it. */
25
+ /**
26
+ * ms on screen. Default 5 s; `Infinity` (until closed) with an action. It pauses while the mouse or the focus is on
27
+ * it. A number given here wins, also with an action: give one only when the action can be reached some other way.
28
+ */
23
29
  duration?: number;
24
30
  /** Give the same id to replace a toast that is on screen instead of stacking another one. */
25
31
  id?: string;
@@ -50,14 +56,19 @@ declare function useToast(): ToastFn;
50
56
  interface ToasterProps {
51
57
  /** The region's name, said with the F8 shortcut that takes the focus to it. */
52
58
  label?: string;
59
+ /** The ×'s accessible name (and its Tooltip), on every toast. Default "Fechar". */
60
+ closeLabel?: string;
53
61
  /** The app, when the Toaster wraps it. It can also be mounted alone, once, anywhere on the page. */
54
62
  children?: ReactNode;
55
63
  }
64
+ /** @internal How long a toast stays: 5 s, or until closed when it has an action (WCAG 2.2.1). */
65
+ declare const toastDuration: (duration: number | undefined, hasAction: boolean) => number;
56
66
  /**
57
67
  * Toaster — the region where the toasts of the Figma [RDS] Feedback/Toast appear (Radix Toast): the bottom-right
58
68
  * corner, up to three at a time (a fourth pushes the oldest out), each one announced in a live region (danger
59
- * assertively, the others politely). F8 takes the focus to the region; swiping right dismisses. Styles: toast.css.
69
+ * assertively, the others politely). F8 takes the focus to the region; swiping right dismisses. A toast closes by
70
+ * itself after 5 s; one with an action stays until the action or the × (WCAG 2.2.1). Styles: toast.css.
60
71
  */
61
- declare function Toaster({ label, children }: ToasterProps): react.JSX.Element;
72
+ declare function Toaster({ label, closeLabel, children }: ToasterProps): react.JSX.Element;
62
73
 
63
- export { type ToastFn, type ToastOptions, type ToastTone, type ToastVariant, ToastView, type ToastViewProps, Toaster, type ToasterProps, toast, toastClassName, useToast };
74
+ export { type ToastFn, type ToastOptions, type ToastTone, type ToastVariant, ToastView, type ToastViewProps, Toaster, type ToasterProps, toast, toastClassName, toastDuration, useToast };
@@ -66,7 +66,8 @@ function useToast() {
66
66
  return toast;
67
67
  }
68
68
  const MAX_VISIBLE = 3;
69
- function Toaster({ label = "Notifica\xE7\xF5es", children }) {
69
+ const toastDuration = (duration, hasAction) => duration != null ? duration : hasAction ? Infinity : 5e3;
70
+ function Toaster({ label = "Notifica\xE7\xF5es", closeLabel = "Fechar", children }) {
70
71
  const [items, setItems] = useState([]);
71
72
  useEffect(() => {
72
73
  const listener = (event) => {
@@ -102,7 +103,7 @@ function Toaster({ label = "Notifica\xE7\xF5es", children }) {
102
103
  if (!next) close(key);
103
104
  },
104
105
  type: tone === "danger" ? "foreground" : "background",
105
- duration: duration != null ? duration : action ? 6e3 : 5e3,
106
+ duration: toastDuration(duration, Boolean(action)),
106
107
  className: toastClassName(tone, variant),
107
108
  children: [
108
109
  /* @__PURE__ */ jsx(
@@ -115,7 +116,7 @@ function Toaster({ label = "Notifica\xE7\xF5es", children }) {
115
116
  }
116
117
  ),
117
118
  action && /* @__PURE__ */ jsx(ToastPrimitive.Action, { altText: action.label, asChild: true, children: /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "ghost", className: "rds-toast__action", onClick: action.onClick, children: action.label }) }),
118
- /* @__PURE__ */ jsx(Tooltip, { text: "Fechar", children: /* @__PURE__ */ jsx(ToastPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(CloseIcon, {}), label: "Fechar", tone: "neutral", variant: "ghost", className: "rds-toast__close" }) }) })
119
+ /* @__PURE__ */ jsx(Tooltip, { text: closeLabel, children: /* @__PURE__ */ jsx(ToastPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(CloseIcon, {}), label: closeLabel, tone: "neutral", variant: "ghost", className: "rds-toast__close" }) }) })
119
120
  ]
120
121
  },
121
122
  key
@@ -128,5 +129,6 @@ export {
128
129
  Toaster,
129
130
  toast,
130
131
  toastClassName,
132
+ toastDuration,
131
133
  useToast
132
134
  };
@@ -1,31 +1,12 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
2
+ import { ToggleCardProps } from './toggle-card.js';
3
3
 
4
- interface ToggleCardCompactProps {
5
- /** An icon before the text (the Item's media). */
6
- icon?: ReactNode;
7
- /** The setting it turns on (the Item's title and the Switch's name). */
8
- label: string;
9
- /** The line under the label while off. */
10
- description?: ReactNode;
11
- /** The line under the label while on (a summary of what is set); it replaces `description`. */
12
- summary?: ReactNode;
13
- checked: boolean;
14
- onCheckedChange?: (checked: boolean) => void;
15
- /** Shows the pencil (an IconButton) while on: opens the setting's options (a Dialog). */
16
- onEdit?: () => void;
17
- /** The pencil's accessible name and tooltip. */
18
- editLabel?: string;
19
- /** Submits 'on' (or '') under this name with a native form, through a hidden input. */
20
- name?: string;
21
- disabled?: boolean;
22
- className?: string;
23
- }
4
+ /** @deprecated Use ToggleCardProps (with layout="compact"). */
5
+ type ToggleCardCompactProps = Omit<ToggleCardProps, 'layout' | 'children'>;
24
6
  /**
25
- * ToggleCardCompact — a composition of the Item (outline), the Switch and the IconButton with its Tooltip: a
26
- * setting in one row, its summary under the label while on and a pencil that opens its options. Styles:
27
- * toggle-card-compact.css.
7
+ * @deprecated Use `<ToggleCard layout="compact">` (Figma [RDS] Forms/ToggleCard, layout=compact), with the same
8
+ * props. A thin wrapper over it, kept so the old name keeps compiling; the codemod rewrites it.
28
9
  */
29
- declare function ToggleCardCompact({ icon, label, description, summary, checked, onCheckedChange, onEdit, editLabel, name, disabled, className, }: ToggleCardCompactProps): react.JSX.Element;
10
+ declare function ToggleCardCompact(props: ToggleCardCompactProps): react.JSX.Element;
30
11
 
31
12
  export { ToggleCardCompact, type ToggleCardCompactProps };
@@ -1,39 +1,12 @@
1
1
  "use client";
2
- import "../chunk-ORMEWXMH.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
- import { IconButton } from "./icon-button.js";
5
- import { PencilIcon } from "./internal/icons.js";
6
- import { Item } from "./item.js";
7
- import { Switch } from "./switch.js";
8
- import { Tooltip } from "./tooltip.js";
9
- function ToggleCardCompact({
10
- icon,
11
- label,
12
- description,
13
- summary,
14
- checked,
15
- onCheckedChange,
16
- onEdit,
17
- editLabel = "Editar",
18
- name,
19
- disabled,
20
- className
21
- }) {
22
- return /* @__PURE__ */ jsx(
23
- Item,
24
- {
25
- variant: "outline",
26
- className: ["rds-toggle-card-compact", className].filter(Boolean).join(" "),
27
- media: icon,
28
- title: label,
29
- description: (checked ? summary : description) || void 0,
30
- action: /* @__PURE__ */ jsxs("span", { className: "rds-toggle-card-compact__actions", children: [
31
- name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: checked ? "on" : "" }),
32
- checked && onEdit && /* @__PURE__ */ jsx(Tooltip, { text: editLabel, children: /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(PencilIcon, {}), label: editLabel, variant: "ghost", tone: "neutral", onClick: onEdit, disabled }) }),
33
- /* @__PURE__ */ jsx(Switch, { "aria-label": label, checked, onCheckedChange, disabled })
34
- ] })
35
- }
36
- );
2
+ import {
3
+ __spreadProps,
4
+ __spreadValues
5
+ } from "../chunk-ORMEWXMH.js";
6
+ import { jsx } from "react/jsx-runtime";
7
+ import { ToggleCard } from "./toggle-card.js";
8
+ function ToggleCardCompact(props) {
9
+ return /* @__PURE__ */ jsx(ToggleCard, __spreadProps(__spreadValues({}, props), { layout: "compact" }));
37
10
  }
38
11
  export {
39
12
  ToggleCardCompact
@@ -1,24 +1,38 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
 
4
+ /** Figma [RDS] Forms/ToggleCard `layout`: the Card with the options below it, or one row (the Item). */
5
+ type ToggleCardLayout = 'default' | 'compact';
4
6
  interface ToggleCardProps {
5
- /** The setting it turns on (the Switch's label). */
7
+ /** `default`: a Card with the Switch and, while on, the options below it. `compact`: one row (an outline Item). */
8
+ layout?: ToggleCardLayout;
9
+ /** The setting it turns on (the Switch's label; in compact, the Item's title and the Switch's name). */
6
10
  label: string;
7
- /** A line under the label (the Switch's hint). */
8
- description?: string;
11
+ /** A line under the label (default: the Switch's hint; compact: shown while off). */
12
+ description?: ReactNode;
13
+ /** Compact only: the line under the label while on (a summary of what is set); it replaces `description`. */
14
+ summary?: ReactNode;
15
+ /** Compact only: an icon before the text (the Item's media). */
16
+ icon?: ReactNode;
9
17
  checked: boolean;
10
- onCheckedChange: (checked: boolean) => void;
18
+ onCheckedChange?: (checked: boolean) => void;
19
+ /** Compact only: shows the pencil (an IconButton) while on; it opens the setting's options (a Dialog). */
20
+ onEdit?: () => void;
21
+ /** Compact only: the pencil's accessible name and tooltip. Default "Editar". */
22
+ editLabel?: string;
11
23
  /** Submits 'on' (or '') under this name with a native form, through a hidden input. */
12
24
  name?: string;
13
- /** The setting's options, shown under it while it is on. */
25
+ /** Default only: the setting's options, shown under it while it is on. */
14
26
  children?: ReactNode;
15
27
  disabled?: boolean;
16
28
  className?: string;
17
29
  }
18
30
  /**
19
- * ToggleCard — a composition of the Card and the Switch (Figma [RDS] Forms/Switch): a setting that, when on, opens
20
- * its own options below it. Styles: toggle-card.css.
31
+ * ToggleCard — Figma [RDS] Forms/ToggleCard: a setting that, when on, opens its own options. `layout="default"` is
32
+ * a composition of the Card and the Switch, the options below it; `layout="compact"` is one row (the Item outline,
33
+ * the Switch and the IconButton with its Tooltip): the summary under the label while on and a pencil that opens the
34
+ * options. Styles: toggle-card.css.
21
35
  */
22
- declare function ToggleCard({ label, description, checked, onCheckedChange, name, children, disabled, className }: ToggleCardProps): react.JSX.Element;
36
+ declare function ToggleCard({ layout, label, description, summary, icon, checked, onCheckedChange, onEdit, editLabel, name, children, disabled, className, }: ToggleCardProps): react.JSX.Element;
23
37
 
24
- export { ToggleCard, type ToggleCardProps };
38
+ export { ToggleCard, type ToggleCardLayout, type ToggleCardProps };
@@ -2,10 +2,46 @@
2
2
  import "../chunk-ORMEWXMH.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { Card } from "./card.js";
5
+ import { IconButton } from "./icon-button.js";
6
+ import { PencilIcon } from "./internal/icons.js";
7
+ import { Item } from "./item.js";
5
8
  import { Switch } from "./switch.js";
6
- function ToggleCard({ label, description, checked, onCheckedChange, name, children, disabled, className }) {
9
+ import { Tooltip } from "./tooltip.js";
10
+ function ToggleCard({
11
+ layout = "default",
12
+ label,
13
+ description,
14
+ summary,
15
+ icon,
16
+ checked,
17
+ onCheckedChange,
18
+ onEdit,
19
+ editLabel = "Editar",
20
+ name,
21
+ children,
22
+ disabled,
23
+ className
24
+ }) {
25
+ const hidden = name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: checked ? "on" : "" });
26
+ if (layout === "compact") {
27
+ return /* @__PURE__ */ jsx(
28
+ Item,
29
+ {
30
+ variant: "outline",
31
+ className: ["rds-toggle-card", "rds-toggle-card--compact", className].filter(Boolean).join(" "),
32
+ media: icon,
33
+ title: label,
34
+ description: (checked ? summary : description) || void 0,
35
+ action: /* @__PURE__ */ jsxs("span", { className: "rds-toggle-card__actions", children: [
36
+ hidden,
37
+ checked && onEdit && /* @__PURE__ */ jsx(Tooltip, { text: editLabel, children: /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(PencilIcon, {}), label: editLabel, variant: "ghost", tone: "neutral", onClick: onEdit, disabled }) }),
38
+ /* @__PURE__ */ jsx(Switch, { "aria-label": label, checked, onCheckedChange, disabled })
39
+ ] })
40
+ }
41
+ );
42
+ }
7
43
  return /* @__PURE__ */ jsxs(Card, { as: "div", className: ["rds-toggle-card", className].filter(Boolean).join(" "), children: [
8
- name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: checked ? "on" : "" }),
44
+ hidden,
9
45
  /* @__PURE__ */ jsx("div", { className: "rds-toggle-card__header", children: /* @__PURE__ */ jsx(Switch, { checked, onCheckedChange, hint: description, disabled, children: label }) }),
10
46
  checked && children && /* @__PURE__ */ jsx("div", { className: "rds-toggle-card__content", children })
11
47
  ] });
@@ -8,7 +8,7 @@ interface ToggleProps extends Omit<ComponentPropsWithRef<typeof TogglePrimitive.
8
8
  children?: ReactNode;
9
9
  /** Icon before the text (Figma: `showIcon` + `iconName`). Decorative, rendered with aria-hidden. */
10
10
  icon?: ReactNode;
11
- /** The emphasis (Figma: `style`): ghost in a toolbar, outline when it stands alone. */
11
+ /** The emphasis (Figma: `variant`): ghost in a toolbar, outline when it stands alone. */
12
12
  variant?: ToggleVariant;
13
13
  /** Rendered as aria-disabled="true": stays in the tab order and takes focus, but does not toggle. */
14
14
  disabled?: boolean;
@@ -1,12 +1,12 @@
1
1
  import * as react from 'react';
2
2
 
3
- /** @deprecated Use Bubble with variant="typing". */
3
+ /** @deprecated Use Bubble with `typing`. */
4
4
  interface TypingIndicatorProps {
5
5
  /** What a screen reader hears. Default "Digitando". */
6
6
  ariaLabel?: string;
7
7
  }
8
8
  /**
9
- * @deprecated Use `<Bubble variant="typing" />` (Figma [RDS] Chat/Bubble, style=typing). A thin wrapper over it: the
9
+ * @deprecated Use `<Bubble typing />` (Figma [RDS] Chat/Bubble, typing=true). A thin wrapper over it: the
10
10
  * label becomes the bubble's announcement.
11
11
  */
12
12
  declare function TypingIndicator({ ariaLabel }: TypingIndicatorProps): react.JSX.Element;
@@ -2,7 +2,7 @@ import "../chunk-ORMEWXMH.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { Bubble } from "./bubble.js";
4
4
  function TypingIndicator({ ariaLabel = "Digitando" }) {
5
- return /* @__PURE__ */ jsx(Bubble, { variant: "typing", align: "start", children: ariaLabel });
5
+ return /* @__PURE__ */ jsx(Bubble, { typing: true, align: "start", children: ariaLabel });
6
6
  }
7
7
  export {
8
8
  TypingIndicator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rojaostudio/ds",
3
- "version": "2.0.0-next.2",
3
+ "version": "2.0.0-next.21",
4
4
  "type": "module",
5
5
  "description": "Rojão Design System — componentes React, estilos e alvo React Native. O motor vive em @rojaostudio/ds-core.",
6
6
  "license": "MIT",
@@ -100,6 +100,7 @@
100
100
  },
101
101
  "files": [
102
102
  "LICENSE",
103
+ "THIRD_PARTY_NOTICES.md",
103
104
  "README.md",
104
105
  "dist",
105
106
  "styles"
@@ -167,7 +168,6 @@
167
168
  "playwright": "^1.63.0",
168
169
  "react-image-crop": "^11.0.10",
169
170
  "react-international-phone": "^4.8.0",
170
- "ts-morph": "^28.0.0",
171
171
  "tsup": "^8.5.1",
172
172
  "tsx": "^4.21.0",
173
173
  "typescript": "^5",
@@ -190,7 +190,7 @@
190
190
  "@radix-ui/react-toggle": "^1.1.18",
191
191
  "@radix-ui/react-toggle-group": "^1.1.19",
192
192
  "@radix-ui/react-tooltip": "^1.2.16",
193
- "@rojaostudio/ds-core": "1.1.0-next.1"
193
+ "@rojaostudio/ds-core": "1.1.0-next.8"
194
194
  },
195
195
  "scripts": {
196
196
  "build": "pnpm run build:tokens && pnpm run build:themes && pnpm run build:rds && pnpm run build:native && tsup",
@@ -207,6 +207,6 @@
207
207
  "lint": "eslint .",
208
208
  "build:brands": "tsx scripts/build-brands.ts",
209
209
  "build:rds": "tsx scripts/build-rds-tokens.ts",
210
- "migrate:consumer": "tsx scripts/migrate-consumer.ts"
210
+ "migrate:consumer": "tsx ../codemod/src/cli.ts"
211
211
  }
212
212
  }
package/styles/base.css CHANGED
@@ -26,9 +26,17 @@
26
26
  Run `pnpm build:tokens` in the DS to regenerate.
27
27
  ───────────────────────────────────────────────────────────── */
28
28
 
29
+ /* Cascade layers, lowest first: the same order rds.css declares, whichever of the two is imported first.
30
+ Everything of this file except Tailwind's @utility and @theme blocks (which Tailwind wants at the top level)
31
+ lives in rds.legacy, below rds.theme: with rds.css also imported, the 2.0 variables win wherever the names
32
+ collide (--surface-page, --text-muted, --border-default, --radius-card, --z-modal, --space-*, --toast-text…)
33
+ and the h1–h6 rule loses to the 2.0 components. */
34
+ @layer rds.legacy, rds.theme, rds.tokens, rds.components;
35
+
29
36
  /* Primitives — auto-generated from tokens/index.ts */
30
- @import "./_primitives.generated.css";
37
+ @import "./_primitives.generated.css" layer(rds.legacy);
31
38
 
39
+ @layer rds.legacy {
32
40
  /* ── CSS Custom Properties — light (default, neutral theme) ── */
33
41
  /* .ds-scope: qualquer wrapper que precise recalcular tokens de COMPONENTE (ex.
34
42
  --option-tile-bg) sob um override local de token SEMÂNTICO (ex. --surface-default)
@@ -724,6 +732,7 @@ h1, h2, h3, h4, h5, h6 {
724
732
  .rojao-toast--enter-top, .rojao-toast--enter-bottom,
725
733
  .rojao-toast--exit-top, .rojao-toast--exit-bottom { animation: none; }
726
734
  }
735
+ } /* @layer rds.legacy */
727
736
 
728
737
  /* ── Control size utilities — h-control-sm/md/lg, size-control-sm/md/lg ── */
729
738
  @utility h-control-sm { height: var(--space-control-height-sm); }
@@ -925,6 +934,9 @@ h1, h2, h3, h4, h5, h6 {
925
934
  * sem ele, num botão com borda da mesma família de cor, o anel some dentro da
926
935
  * borda. E ele é desenhado com a cor da superfície, então funciona igual sobre
927
936
  * fundo claro e sobre o escuro do chrome.
937
+ *
938
+ * Stays in Tailwind's `base` layer, not in rds.legacy: it sets no variable, and in `base` Tailwind's utilities
939
+ * (`outline-none`) still win over it, as they did in 1.x. Both layers sit below the rds.* ones.
928
940
  */
929
941
  @layer base {
930
942
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {