@rojaostudio/ds 2.0.0-next.16 → 2.0.0-next.18

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 (65) hide show
  1. package/dist/components/avatar.d.ts +20 -12
  2. package/dist/components/avatar.js +8 -6
  3. package/dist/components/badge.d.ts +7 -6
  4. package/dist/components/badge.js +2 -1
  5. package/dist/components/breadcrumb.d.ts +4 -4
  6. package/dist/components/breadcrumb.js +1 -1
  7. package/dist/components/bubble.d.ts +26 -11
  8. package/dist/components/bubble.js +3 -3
  9. package/dist/components/button.d.ts +1 -1
  10. package/dist/components/card.d.ts +18 -9
  11. package/dist/components/card.js +4 -2
  12. package/dist/components/color-input.d.ts +1 -1
  13. package/dist/components/context-menu.d.ts +5 -2
  14. package/dist/components/data-table-header.d.ts +10 -5
  15. package/dist/components/data-table-header.js +59 -4
  16. package/dist/components/date-picker.d.ts +1 -1
  17. package/dist/components/dialog.d.ts +6 -3
  18. package/dist/components/dialog.js +2 -2
  19. package/dist/components/dropdown-menu.d.ts +5 -2
  20. package/dist/components/dropzone.d.ts +2 -2
  21. package/dist/components/dropzone.js +1 -1
  22. package/dist/components/file-input.d.ts +13 -8
  23. package/dist/components/file-input.js +24 -21
  24. package/dist/components/filter-chip.d.ts +11 -5
  25. package/dist/components/filter-chip.js +15 -6
  26. package/dist/components/heading.d.ts +9 -6
  27. package/dist/components/heading.js +1 -1
  28. package/dist/components/icon-button.d.ts +1 -1
  29. package/dist/components/image-upload.d.ts +2 -2
  30. package/dist/components/image-upload.js +1 -1
  31. package/dist/components/index.d.ts +6 -6
  32. package/dist/components/internal/button.d.ts +1 -1
  33. package/dist/components/internal/menu.d.ts +3 -2
  34. package/dist/components/internal/menu.js +1 -1
  35. package/dist/components/internal/toggle.d.ts +1 -1
  36. package/dist/components/item.d.ts +14 -7
  37. package/dist/components/item.js +5 -2
  38. package/dist/components/marker.d.ts +11 -3
  39. package/dist/components/marker.js +4 -3
  40. package/dist/components/progress.d.ts +3 -3
  41. package/dist/components/progress.js +2 -2
  42. package/dist/components/row-actions.d.ts +3 -0
  43. package/dist/components/row-actions.js +8 -4
  44. package/dist/components/sidebar.d.ts +8 -11
  45. package/dist/components/sidebar.js +4 -5
  46. package/dist/components/spinner.d.ts +9 -6
  47. package/dist/components/spinner.js +3 -3
  48. package/dist/components/star-rating.d.ts +3 -3
  49. package/dist/components/star-rating.js +2 -2
  50. package/dist/components/stat.d.ts +18 -6
  51. package/dist/components/stat.js +9 -3
  52. package/dist/components/status.d.ts +4 -4
  53. package/dist/components/status.js +2 -2
  54. package/dist/components/summary-bar.d.ts +3 -2
  55. package/dist/components/summary-bar.js +10 -1
  56. package/dist/components/tile.d.ts +5 -5
  57. package/dist/components/tile.js +2 -2
  58. package/dist/components/time-picker.d.ts +1 -1
  59. package/dist/components/toast.d.ts +1 -1
  60. package/dist/components/toggle.d.ts +1 -1
  61. package/dist/components/typing-indicator.d.ts +2 -2
  62. package/dist/components/typing-indicator.js +1 -1
  63. package/package.json +1 -1
  64. package/styles/rds/components-styles.css +84 -48
  65. package/styles/rds/components.css +0 -9
@@ -3,15 +3,23 @@ import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
4
  /** person is a circle; brand is a rounded square (a brand, a company, a campaign). */
5
5
  type AvatarType = 'person' | 'brand';
6
- type AvatarSize = 'sm' | 'default' | 'lg' | 'xl';
7
- /** What the Avatar shows. It follows from the props: a photo (`src`), initials (a name) or an icon (no name). */
8
- type AvatarVariant = 'image' | 'fallback' | 'icon';
6
+ type AvatarSize = 'sm' | 'md' | 'lg' | 'xl';
7
+ /**
8
+ * What the Avatar shows (Figma: `content`). It follows from the props: a photo (`src`), initials (a name) or an icon
9
+ * (no name).
10
+ */
11
+ type AvatarContent = 'image' | 'fallback' | 'icon';
12
+ /** @deprecated Use AvatarContent (2.0.0-next: the Figma `variant` is `content`). */
13
+ type AvatarVariant = AvatarContent;
9
14
  interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
10
15
  /** person is a circle; brand is a square with rounded corners, initials in bold on the brand's mark colour. */
11
16
  type?: AvatarType;
12
- /** sm 24, default 32, lg 40, xl 56. Inside an AvatarGroup, the group's size. */
13
- size?: AvatarSize;
14
- /** The photo (Figma: `variant=image`). If it fails to load, the initials (or the icon) show instead. */
17
+ /**
18
+ * sm 24, md 32 (default), lg 40, xl 56 (Figma: `size`). Inside an AvatarGroup, the group's size. `'default'` is
19
+ * deprecated (2.0.0-next): it is `'md'`.
20
+ */
21
+ size?: AvatarSize | 'default';
22
+ /** The photo (Figma: `content=image`). If it fails to load, the initials (or the icon) show instead. */
15
23
  src?: string;
16
24
  /**
17
25
  * The full name: the photo's alt, the initials' aria-label and the source of the initials. Leave it out only for an
@@ -20,7 +28,7 @@ interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'>
20
28
  name?: string;
21
29
  /** The initials (Figma: `fallbackText`). By default two letters from `name`, one on a brand. */
22
30
  fallbackText?: string;
23
- /** The icon when there is no name (Figma: `variant=icon` + `icon`). By default a person, or a building on a brand. */
31
+ /** The icon when there is no name (Figma: `content=icon` + `icon`). By default a person, or a building on a brand. */
24
32
  icon?: ReactNode;
25
33
  /** The presence dot (Figma: `showBadge`). The colour is not the only sign: `badgeLabel` goes into the accessible name. */
26
34
  showBadge?: boolean;
@@ -31,7 +39,7 @@ interface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'>
31
39
  declare function initials(name: string): string;
32
40
  /**
33
41
  * Avatar — Figma [RDS] Content/Avatar. A person, or a brand, in miniature: photo, initials or icon. Not
34
- * interactive. The Figma `variant` follows from the props: `src` → image, a name → fallback, neither → icon.
42
+ * interactive. The Figma `content` follows from the props: `src` → image, a name → fallback, neither → icon.
35
43
  * Styles: avatar.css.
36
44
  */
37
45
  declare function Avatar({ type, size, src, name, fallbackText, icon, showBadge, badgeLabel, className, ...rest }: AvatarProps): react.JSX.Element;
@@ -39,14 +47,14 @@ type AvatarGroupSize = Exclude<AvatarSize, 'xl'>;
39
47
  interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {
40
48
  /** Who the group is ("Equipe do projeto"). Required: it names the group for screen readers. */
41
49
  'aria-label': string;
42
- /** The size of every Avatar inside (Figma: sm, default, lg). */
43
- size?: AvatarGroupSize;
50
+ /** The size of every Avatar inside (Figma: sm, md, lg). `'default'` is deprecated (2.0.0-next): it is `'md'`. */
51
+ size?: AvatarGroupSize | 'default';
44
52
  /** Show only the first `max` and a "+N" with the rest. 3 or 4 is a good limit. */
45
53
  max?: number;
46
54
  /** The Avatars. */
47
55
  children: ReactNode;
48
56
  }
49
57
  /** AvatarGroup — Figma [RDS] Content/AvatarGroup. Overlapping avatars, each with a ring that separates it. */
50
- declare function AvatarGroup({ size, max, className, children, ...rest }: AvatarGroupProps): react.JSX.Element;
58
+ declare function AvatarGroup({ size: sizeProp, max, className, children, ...rest }: AvatarGroupProps): react.JSX.Element;
51
59
 
52
- export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarGroupSize, type AvatarProps, type AvatarSize, type AvatarType, type AvatarVariant, initials };
60
+ export { Avatar, type AvatarContent, AvatarGroup, type AvatarGroupProps, type AvatarGroupSize, type AvatarProps, type AvatarSize, type AvatarType, type AvatarVariant, initials };
@@ -8,6 +8,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { Children, createContext, useContext, useState } from "react";
9
9
  import { BuildingIcon, UserIcon } from "./internal/icons.js";
10
10
  const GroupSize = createContext(void 0);
11
+ const sizeOf = (size) => size === "default" ? "md" : size;
11
12
  function initials(name) {
12
13
  const parts = name.trim().split(/\s+/).filter(Boolean);
13
14
  if (parts.length === 0) return "?";
@@ -38,26 +39,27 @@ function Avatar(_a) {
38
39
  ]);
39
40
  var _a2, _b2;
40
41
  const groupSize = useContext(GroupSize);
41
- const finalSize = (_a2 = size != null ? size : groupSize) != null ? _a2 : "default";
42
+ const finalSize = sizeOf((_a2 = size != null ? size : groupSize) != null ? _a2 : "md");
42
43
  const [failed, setFailed] = useState(null);
43
44
  const trimmed = (_b2 = name == null ? void 0 : name.trim()) != null ? _b2 : "";
44
45
  const letters = fallbackText != null ? fallbackText : trimmed ? type === "brand" ? trimmed[0].toUpperCase() : initials(trimmed) : "";
45
- const variant = src && failed !== src ? "image" : letters ? "fallback" : "icon";
46
+ const content = src && failed !== src ? "image" : letters ? "fallback" : "icon";
46
47
  const label = trimmed ? showBadge ? `${trimmed}, ${badgeLabel}` : trimmed : void 0;
47
- const semantics = variant === "image" ? {} : label ? { role: "img", "aria-label": label } : { "aria-hidden": true };
48
+ const semantics = content === "image" ? {} : label ? { role: "img", "aria-label": label } : { "aria-hidden": true };
48
49
  return /* @__PURE__ */ jsxs(
49
50
  "span",
50
51
  __spreadProps(__spreadValues(__spreadValues({}, semantics), rest), {
51
- className: ["rds-avatar", `rds-avatar--${type}`, `rds-avatar--${finalSize}`, `rds-avatar--${variant}`, className].filter(Boolean).join(" "),
52
+ className: ["rds-avatar", `rds-avatar--${type}`, `rds-avatar--${finalSize}`, `rds-avatar--${content}`, className].filter(Boolean).join(" "),
52
53
  children: [
53
- variant === "image" ? /* @__PURE__ */ jsx("img", { className: "rds-avatar__image", src, alt: label != null ? label : "", onError: () => setFailed(src != null ? src : null) }) : /* @__PURE__ */ jsx("span", { className: "rds-avatar__fallback", "aria-hidden": "true", children: variant === "fallback" ? letters : icon != null ? icon : type === "brand" ? /* @__PURE__ */ jsx(BuildingIcon, {}) : /* @__PURE__ */ jsx(UserIcon, {}) }),
54
+ content === "image" ? /* @__PURE__ */ jsx("img", { className: "rds-avatar__image", src, alt: label != null ? label : "", onError: () => setFailed(src != null ? src : null) }) : /* @__PURE__ */ jsx("span", { className: "rds-avatar__fallback", "aria-hidden": "true", children: content === "fallback" ? letters : icon != null ? icon : type === "brand" ? /* @__PURE__ */ jsx(BuildingIcon, {}) : /* @__PURE__ */ jsx(UserIcon, {}) }),
54
55
  showBadge && /* @__PURE__ */ jsx("span", { className: "rds-avatar__badge", "aria-hidden": "true" })
55
56
  ]
56
57
  })
57
58
  );
58
59
  }
59
60
  function AvatarGroup(_c) {
60
- var _d = _c, { size = "default", max, className, children } = _d, rest = __objRest(_d, ["size", "max", "className", "children"]);
61
+ var _d = _c, { size: sizeProp = "md", max, className, children } = _d, rest = __objRest(_d, ["size", "max", "className", "children"]);
62
+ const size = sizeOf(sizeProp);
61
63
  const items = Children.toArray(children);
62
64
  const shown = max && items.length > max ? items.slice(0, max) : items;
63
65
  const hidden = items.length - shown.length;
@@ -2,8 +2,8 @@ import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
4
  type BadgeTone = 'neutral' | 'action' | 'accent' | 'inverse';
5
- /** Figma calls this property `style`. */
6
- type BadgeVariant = 'fill' | 'soft' | 'highlight';
5
+ /** The emphasis (Figma: `variant`): fill (solid) or soft (a light plate; on accent, the brand's highlighter). */
6
+ type BadgeVariant = 'fill' | 'soft';
7
7
  interface BadgeBase extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
8
8
  /** The label (Figma: `label`): "Nova", "Grátis". Ignored when `value` is given. */
9
9
  children?: ReactNode;
@@ -11,15 +11,16 @@ interface BadgeBase extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
11
11
  value?: number;
12
12
  }
13
13
  /**
14
- * Not every tone has every variant (as in Figma): soft only on neutral and action, highlight only on accent,
15
- * inverse only fill. The types allow only those.
14
+ * Not every tone has every variant (as in Figma): inverse is only fill. On accent, soft is the brand's highlighter
15
+ * (the old `highlight`). The types allow only those.
16
16
  */
17
17
  type BadgeProps = BadgeBase & ({
18
18
  tone?: 'neutral' | 'action';
19
- variant?: 'fill' | 'soft';
19
+ variant?: BadgeVariant;
20
20
  } | {
21
21
  tone: 'accent';
22
- variant?: 'fill' | 'highlight';
22
+ /** `'highlight'` is deprecated (2.0.0-next): it is `variant="soft"` on `tone="accent"`. */
23
+ variant?: BadgeVariant | 'highlight';
23
24
  } | {
24
25
  tone: 'inverse';
25
26
  variant?: 'fill';
@@ -10,10 +10,11 @@ function formatBadgeValue(value) {
10
10
  function Badge(_a) {
11
11
  var _b = _a, { tone = "neutral", variant = "fill", value, children, className } = _b, rest = __objRest(_b, ["tone", "variant", "value", "children", "className"]);
12
12
  const isNumber = value !== void 0;
13
+ const emphasis = variant === "highlight" ? "soft" : variant;
13
14
  return /* @__PURE__ */ jsx(
14
15
  "span",
15
16
  __spreadProps(__spreadValues({}, rest), {
16
- className: ["rds-badge", `rds-badge--${tone}-${variant}`, isNumber && "rds-badge--number", className].filter(Boolean).join(" "),
17
+ className: ["rds-badge", `rds-badge--${tone}-${emphasis}`, isNumber && "rds-badge--number", className].filter(Boolean).join(" "),
17
18
  children: isNumber ? formatBadgeValue(value) : children
18
19
  })
19
20
  );
@@ -6,7 +6,7 @@ interface BreadcrumbItem {
6
6
  /** Where the step leads. The last step is the current page and never gets a link. */
7
7
  href?: string;
8
8
  }
9
- type BreadcrumbTone = 'default' | 'inverse';
9
+ type BreadcrumbTone = 'neutral' | 'inverse';
10
10
  type BreadcrumbLinkComponent = ComponentType<{
11
11
  href: string;
12
12
  className?: string;
@@ -16,10 +16,10 @@ interface BreadcrumbProps extends Omit<HTMLAttributes<HTMLElement>, 'children'>
16
16
  /** The path, from the most general to the current page, the last one (Figma: the `items` slot). */
17
17
  items: BreadcrumbItem[];
18
18
  /**
19
- * default on a light surface; inverse over colors/primary. Deprecated in the Figma since 27/09/2026: for the brand
20
- * colour, put the Breadcrumb in a brand-mode scope and keep the default tone.
19
+ * neutral (default) on a light surface; inverse over colors/primary (Figma: `tone`). For the brand colour prefer a
20
+ * brand-mode scope (`.ds-plate`) with the neutral tone. `'default'` is deprecated (2.0.0-next): it is `'neutral'`.
21
21
  */
22
- tone?: BreadcrumbTone;
22
+ tone?: BreadcrumbTone | 'default';
23
23
  /** More steps than this: the middle ones hide behind "…", a button that shows the whole path. */
24
24
  maxItems?: number;
25
25
  /** The link element (default `<a>`). Pass a framework Link (Next's `Link`) to navigate on the client. */
@@ -11,7 +11,7 @@ function Anchor({ href, className, children }) {
11
11
  return /* @__PURE__ */ jsx("a", { href, className, children });
12
12
  }
13
13
  function Breadcrumb(_a) {
14
- var _b = _a, { items, tone = "default", maxItems = 4, linkAs: Link = Anchor, className } = _b, rest = __objRest(_b, ["items", "tone", "maxItems", "linkAs", "className"]);
14
+ var _b = _a, { items, tone = "neutral", maxItems = 4, linkAs: Link = Anchor, className } = _b, rest = __objRest(_b, ["items", "tone", "maxItems", "linkAs", "className"]);
15
15
  const [expanded, setExpanded] = useState(false);
16
16
  const list = useRef(null);
17
17
  const collapse = !expanded && items.length > maxItems;
@@ -1,29 +1,44 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
- type BubbleVariant = 'fill' | 'muted' | 'tinted' | 'outline' | 'ghost' | 'error' | 'typing';
4
+ /** The emphasis (Figma: `variant`). */
5
+ type BubbleVariant = 'fill' | 'soft' | 'outline' | 'ghost';
6
+ /** The colour (Figma: `tone`). action and danger exist only on soft. */
7
+ type BubbleTone = 'neutral' | 'action' | 'danger';
5
8
  type BubbleAlign = 'start' | 'end';
6
- interface BubbleProps extends HTMLAttributes<HTMLDivElement> {
7
- /**
8
- * The surface (Figma: `style`). fill: the person writing, in the brand colour. muted or tinted: the one answering.
9
- * outline: on a coloured background. ghost: a long answer from the assistant, no box. error: it was not sent.
10
- * typing: the three dots of the one answering while they write; no text, no reactions.
11
- */
12
- variant?: BubbleVariant;
9
+ interface BubbleBase extends HTMLAttributes<HTMLDivElement> {
13
10
  /** start: the one answering, the small corner bottom left; end: the person writing, bottom right. */
14
11
  align?: BubbleAlign;
15
12
  /**
16
- * The message (Figma: `text`). Line breaks are kept. In `typing` it is what a screen reader hears instead of the
13
+ * The three dots of the one answering while they write (Figma: `typing=true`); no text, no reactions. The
14
+ * surface is the soft neutral one, whatever `variant` and `tone` say.
15
+ */
16
+ typing?: boolean;
17
+ /**
18
+ * The message (Figma: `text`). Line breaks are kept. With `typing` it is what a screen reader hears instead of the
17
19
  * dots, "digitando…" by default ("Ana está digitando…").
18
20
  */
19
21
  children?: ReactNode;
20
22
  /** How many reacted (Figma: `showReactions` + `reactions`). The pill goes under the text; 0 hides it. */
21
23
  reactions?: number;
22
24
  }
25
+ /**
26
+ * The surface (Figma: `variant` × `tone`, only the combinations the Figma draws):
27
+ * - soft (default): the one answering. tone neutral (default), action (the brand tint) or danger (it was not sent).
28
+ * - fill: the person writing, in the brand colour. outline: on a coloured background. ghost: a long answer from the
29
+ * assistant, no box. These three are neutral only.
30
+ */
31
+ type BubbleProps = BubbleBase & ({
32
+ variant?: 'soft';
33
+ tone?: BubbleTone;
34
+ } | {
35
+ variant: 'fill' | 'outline' | 'ghost';
36
+ tone?: 'neutral';
37
+ });
23
38
  /**
24
39
  * Bubble — Figma [RDS] Chat/Bubble. The surface of a message: it grows up to 480 and wraps. Inside a Message,
25
40
  * which adds the avatar, the name and the actions. Styles: bubble.css.
26
41
  */
27
- declare function Bubble({ variant, align, children, reactions, className, ...rest }: BubbleProps): react.JSX.Element;
42
+ declare function Bubble({ variant, tone, typing, align, children, reactions, className, ...rest }: BubbleProps): react.JSX.Element;
28
43
 
29
- export { Bubble, type BubbleAlign, type BubbleProps, type BubbleVariant };
44
+ export { Bubble, type BubbleAlign, type BubbleProps, type BubbleTone, type BubbleVariant };
@@ -6,8 +6,8 @@ import {
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { ThumbsUpIcon } from "./internal/icons.js";
8
8
  function Bubble(_a) {
9
- var _b = _a, { variant = "muted", align = "start", children, reactions, className } = _b, rest = __objRest(_b, ["variant", "align", "children", "reactions", "className"]);
10
- if (variant === "typing") {
9
+ var _b = _a, { variant = "soft", tone = "neutral", typing = false, align = "start", children, reactions, className } = _b, rest = __objRest(_b, ["variant", "tone", "typing", "align", "children", "reactions", "className"]);
10
+ if (typing) {
11
11
  return /* @__PURE__ */ jsxs("div", __spreadProps(__spreadValues({ role: "status" }, rest), { className: ["rds-bubble", "rds-bubble--typing", `rds-bubble--${align}`, className].filter(Boolean).join(" "), children: [
12
12
  /* @__PURE__ */ jsxs("span", { className: "rds-bubble__dots", "aria-hidden": "true", children: [
13
13
  /* @__PURE__ */ jsx("span", {}),
@@ -17,7 +17,7 @@ function Bubble(_a) {
17
17
  /* @__PURE__ */ jsx("span", { className: "rds-visually-hidden", children: children != null ? children : "digitando\u2026" })
18
18
  ] }));
19
19
  }
20
- return /* @__PURE__ */ jsxs("div", __spreadProps(__spreadValues({}, rest), { className: ["rds-bubble", `rds-bubble--${variant}`, `rds-bubble--${align}`, className].filter(Boolean).join(" "), children: [
20
+ return /* @__PURE__ */ jsxs("div", __spreadProps(__spreadValues({}, rest), { className: ["rds-bubble", `rds-bubble--${variant}`, `rds-bubble--${tone}`, `rds-bubble--${align}`, className].filter(Boolean).join(" "), children: [
21
21
  /* @__PURE__ */ jsx("div", { className: "rds-bubble__text", children }),
22
22
  reactions !== void 0 && reactions > 0 && /* @__PURE__ */ jsx("div", { className: "rds-bubble__reactions-row", children: /* @__PURE__ */ jsxs("span", { className: "rds-bubble__reactions", children: [
23
23
  /* @__PURE__ */ jsxs("span", { className: "rds-bubble__reactions-count", "aria-hidden": "true", children: [
@@ -9,7 +9,7 @@ interface ButtonProps extends ComponentPropsWithRef<'button'> {
9
9
  children: ReactNode;
10
10
  /** The role: brand click (action), quiet (neutral), destructive (danger), or over the brand plate (inverse). */
11
11
  tone?: ButtonTone;
12
- /** The emphasis (Figma: `style`): fill draws the most attention, ghost the least. */
12
+ /** The emphasis (Figma: `variant`): fill draws the most attention, ghost the least. */
13
13
  variant?: ButtonVariant;
14
14
  /**
15
15
  * The height, by the space available (Figma: `size`): sm 36, md 44 (default), lg 52. Text 14/20 on sm and md,
@@ -1,18 +1,27 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
 
4
+ /** The surface (Figma: `variant`). */
5
+ type CardVariant = 'surface' | 'soft' | 'outline';
6
+ /** @deprecated Use CardVariant (2.0.0-next): default → surface, tint → soft, outline stays. */
4
7
  type CardSurface = 'default' | 'outline' | 'tint';
5
- type CardSize = 'default' | 'sm';
8
+ type CardSize = 'md' | 'sm';
6
9
  type Heading = 'h2' | 'h3' | 'h4';
7
10
  interface CardProps extends HTMLAttributes<HTMLElement> {
8
11
  /**
9
- * default: white, with a border and elevation/raised; the default, for a topic on its own on the page.
10
- * outline: only the border, no fill nor shadow, it takes the surface underneath; for cards side by side in a grid,
11
- * inside a panel or a list. tint: the brand's light plate, no border nor shadow; a rare highlight, one per screen.
12
+ * The surface (Figma: `variant`). surface (default): white, with a border and elevation/raised, for a topic on its
13
+ * own on the page. outline: only the border, no fill nor shadow, it takes the surface underneath; for cards side by
14
+ * side in a grid, inside a panel or a list. soft: the brand's light plate, no border nor shadow; a rare highlight,
15
+ * one per screen.
12
16
  */
17
+ variant?: CardVariant;
18
+ /** @deprecated Use `variant` (2.0.0-next): default → surface, tint → soft, outline → outline. */
13
19
  surface?: CardSurface;
14
- /** sm pads 16 (default 24) and makes the header text smaller, for dense lists and indicators. */
15
- size?: CardSize;
20
+ /**
21
+ * md (default) pads 24; sm pads 16 and makes the header text smaller, for dense lists and indicators (Figma:
22
+ * `size`). `'default'` is deprecated (2.0.0-next): it is `'md'`.
23
+ */
24
+ size?: CardSize | 'default';
16
25
  /** article (default) for a topic that reads on its own; section or div when it is part of something larger. */
17
26
  as?: 'article' | 'section' | 'div';
18
27
  /**
@@ -25,7 +34,7 @@ interface CardProps extends HTMLAttributes<HTMLElement> {
25
34
  * Card — Figma [RDS] Content/Card. A topic that reads on its own: a plan, a summary with an action. Never a card
26
35
  * inside a card. When it has a CardHeader, the title names the card. Styles: card.css.
27
36
  */
28
- declare function Card({ surface, size, as: Root, className, children, ...rest }: CardProps): react.JSX.Element;
37
+ declare function Card({ variant, surface, size, as: Root, className, children, ...rest }: CardProps): react.JSX.Element;
29
38
  interface CardHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
30
39
  /** What the card is about (Figma: `title`). It names the card for screen readers. */
31
40
  title: ReactNode;
@@ -33,7 +42,7 @@ interface CardHeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
33
42
  titleAs?: Heading;
34
43
  /** One supporting line (Figma: `showDescription` + `description`). */
35
44
  description?: ReactNode;
36
- /** A Tile before the text (Figma: `showIcon`): variant soft, size default (sm on a small card). */
45
+ /** A Tile before the text (Figma: `showIcon`): variant soft, size md (sm on a small card). */
37
46
  icon?: ReactNode;
38
47
  /** Opt-in: one action on the right (Figma: `showAction` + `action`), a ghost Button or an IconButton. None by default. */
39
48
  action?: ReactNode;
@@ -59,4 +68,4 @@ interface CardFooterProps extends HTMLAttributes<HTMLElement> {
59
68
  /** The card's footer, with its actions (Figma: .card/footer). No band and no rule: spacing sets it apart. */
60
69
  declare function CardFooter({ align, note, className, children, ...rest }: CardFooterProps): react.JSX.Element;
61
70
 
62
- export { Card, CardContent, type CardContentProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, type CardSize, type CardSurface };
71
+ export { Card, CardContent, type CardContentProps, CardFooter, type CardFooterProps, CardHeader, type CardHeaderProps, type CardProps, type CardSize, type CardSurface, type CardVariant };
@@ -6,9 +6,11 @@ import {
6
6
  } from "../chunk-ORMEWXMH.js";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { createContext, useContext, useId } from "react";
9
+ const SURFACE_TO_VARIANT = { default: "surface", tint: "soft", outline: "outline" };
9
10
  const TitleId = createContext(void 0);
10
11
  function Card(_a) {
11
- var _b = _a, { surface = "default", size = "default", as: Root = "article", className, children } = _b, rest = __objRest(_b, ["surface", "size", "as", "className", "children"]);
12
+ var _b = _a, { variant, surface, size = "md", as: Root = "article", className, children } = _b, rest = __objRest(_b, ["variant", "surface", "size", "as", "className", "children"]);
13
+ const look = variant != null ? variant : surface ? SURFACE_TO_VARIANT[surface] : "surface";
12
14
  const titleId = useId();
13
15
  const labelled = Root !== "div" && !rest["aria-label"] && !rest["aria-labelledby"];
14
16
  return /* @__PURE__ */ jsx(TitleId.Provider, { value: labelled ? titleId : void 0, children: /* @__PURE__ */ jsx(
@@ -16,7 +18,7 @@ function Card(_a) {
16
18
  __spreadProps(__spreadValues({
17
19
  "aria-labelledby": labelled ? titleId : void 0
18
20
  }, rest), {
19
- className: ["rds-card", `rds-card--${surface}`, size === "sm" && "rds-card--sm", className].filter(Boolean).join(" "),
21
+ className: ["rds-card", `rds-card--${look}`, size === "sm" && "rds-card--sm", className].filter(Boolean).join(" "),
20
22
  children
21
23
  })
22
24
  ) });
@@ -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
  }
@@ -32,15 +32,15 @@ type DataTableHeaderProps = {
32
32
  onClear?: () => void;
33
33
  /**
34
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 on a narrow screen too.
35
+ * Checkbox "Agrupar por produto". In view in the compact arrangement too.
36
36
  */
37
37
  view?: ReactNode;
38
38
  actions?: ReactNode;
39
39
  className?: string;
40
- /** On a narrow screen, moves the filters and the actions into a Drawer. The quick filters stay in view. */
40
+ /** In the compact arrangement (bar below 1024), moves the filters and the actions into a Drawer. The quick filters stay in view. */
41
41
  mobileCollapse?: boolean;
42
42
  };
43
- /** One filter as a DropdownMenu of radio items (one filter on a wide screen). */
43
+ /** One filter as a DropdownMenu of radio items (one filter, expanded). */
44
44
  declare function FilterDropdown({ f, placement }: {
45
45
  f: DataTableFilterDef;
46
46
  placement?: 'bottom-start' | 'bottom-end';
@@ -50,8 +50,13 @@ declare function FilterDropdown({ f, placement }: {
50
50
  * the Drawer: the bar above a table. The search is always on the left and takes the free width (at least 320); the
51
51
  * filters are always on the right; what does not fit wraps. Quick filters go in the `quickFilters` slot; one filter
52
52
  * is a dropdown, two or more collapse into "Filtros" (the active ones stay in view as removable Chips); the `view`
53
- * control comes after the filters, before the actions. From 768 the wide layout shows; below it, the filters open
54
- * in a Drawer or a Popover. "Filtros · N" counts the active `filters`, the ones that button opens.
53
+ * control comes after the filters, before the actions. "Filtros · N" counts the active `filters`, the ones that
54
+ * button opens.
55
+ *
56
+ * Two arrangements, by the bar's own width (a size container, as the Figma's viewport mode; the SavingBar's cut):
57
+ * expanded from 1024, the Separator and the Buttons with their labels; compact below it, the search accepts 200 and
58
+ * the filter is an outline IconButton (sliders, 44) with a dot (one filter on) or a counter (several), opening the
59
+ * same Drawer or Popover. There is no screen prop.
55
60
  * Styles: data-table-header.css.
56
61
  */
57
62
  declare function DataTableHeader({ search, filters, quickFilters, onClear, view, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
@@ -6,6 +6,7 @@ import {
6
6
  } from "../chunk-ORMEWXMH.js";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { useState } from "react";
9
+ import { Badge } from "./badge.js";
9
10
  import { Button } from "./button.js";
10
11
  import { Chip } from "./chip.js";
11
12
  import { Drawer } from "./drawer.js";
@@ -52,7 +53,7 @@ function FilterGroups({
52
53
  return /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__groups", children: [
53
54
  filters.map((f) => /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__group", children: [
54
55
  /* @__PURE__ */ jsx("p", { className: "rds-data-table-header__group-label", "aria-hidden": "true", children: f.label }),
55
- /* @__PURE__ */ jsx(FilterChipGroup, { "aria-label": f.label, children: f.options.map((opt) => /* @__PURE__ */ jsx(FilterChip, { active: f.value === opt.value, count: opt.count, onClick: () => onPick(f, opt.value), children: opt.label }, opt.value)) })
56
+ /* @__PURE__ */ jsx(FilterChipGroup, { "aria-label": f.label, children: f.options.map((opt) => /* @__PURE__ */ jsx(FilterChip, { pressed: f.value === opt.value, count: opt.count, onClick: () => onPick(f, opt.value), children: opt.label }, opt.value)) })
56
57
  ] }, f.key)),
57
58
  onClear && showClear && /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "ghost", onClick: onClear, children: "Limpar filtros" })
58
59
  ] });
@@ -80,10 +81,49 @@ function FiltersPopover({
80
81
  }
81
82
  ) }) });
82
83
  }
84
+ function CompactFilterTrigger(_e) {
85
+ var _f = _e, {
86
+ label,
87
+ state,
88
+ indicator
89
+ } = _f, rest = __objRest(_f, [
90
+ "label",
91
+ "state",
92
+ "indicator"
93
+ ]);
94
+ return /* @__PURE__ */ jsxs("span", { className: "rds-data-table-header__trigger", children: [
95
+ /* @__PURE__ */ jsx(Tooltip, { text: label, children: /* @__PURE__ */ jsx(
96
+ IconButton,
97
+ __spreadProps(__spreadValues({}, rest), {
98
+ icon: /* @__PURE__ */ jsx(SlidersIcon, {}),
99
+ label: state ? `${label}, ${state}` : label,
100
+ variant: "outline",
101
+ tone: "neutral",
102
+ size: "md",
103
+ "data-filter-toggle": ""
104
+ })
105
+ ) }),
106
+ indicator === "dot" && /* @__PURE__ */ jsx("span", { className: "rds-data-table-header__dot", "aria-hidden": "true" }),
107
+ typeof indicator === "number" && /* @__PURE__ */ jsx(Badge, { className: "rds-data-table-header__count", tone: "neutral", value: indicator, "aria-hidden": "true" })
108
+ ] });
109
+ }
110
+ function activeState(count) {
111
+ if (count === 0) return void 0;
112
+ return count === 1 ? "1 ativo" : `${count} ativos`;
113
+ }
83
114
  function MobileSingleFilter({ f }) {
84
115
  const [open, setOpen] = useState(false);
116
+ const on = f.value !== "";
85
117
  return /* @__PURE__ */ jsxs(Fragment, { children: [
86
- /* @__PURE__ */ jsx(FilterTrigger, { filter: f, onClick: () => setOpen(true) }),
118
+ /* @__PURE__ */ jsx(
119
+ CompactFilterTrigger,
120
+ {
121
+ label: f.label,
122
+ state: on ? optionLabel(f) : void 0,
123
+ indicator: on ? "dot" : void 0,
124
+ onClick: () => setOpen(true)
125
+ }
126
+ ),
87
127
  /* @__PURE__ */ jsx(Drawer, { open, onOpenChange: setOpen, title: f.label, children: /* @__PURE__ */ jsx(
88
128
  FilterGroups,
89
129
  {
@@ -153,11 +193,26 @@ function DataTableHeader({
153
193
  filters,
154
194
  onClear,
155
195
  showClear: activeFilterCount > 0,
156
- trigger: /* @__PURE__ */ jsx(FiltersButton, { count: activeFilterCount })
196
+ trigger: /* @__PURE__ */ jsx(
197
+ CompactFilterTrigger,
198
+ {
199
+ label: "Filtros",
200
+ state: activeState(activeFilterCount),
201
+ indicator: activeFilterCount > 0 ? activeFilterCount : void 0
202
+ }
203
+ )
157
204
  }
158
205
  ) }),
159
206
  mobileCollapse && (filters.length >= 2 || actions) && /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__narrow", children: [
160
- /* @__PURE__ */ jsx(FiltersButton, { count: activeFilterCount, onClick: () => setSheetOpen(true) }),
207
+ /* @__PURE__ */ jsx(
208
+ CompactFilterTrigger,
209
+ {
210
+ label: "Filtros",
211
+ state: activeState(activeFilterCount),
212
+ indicator: activeFilterCount === 0 ? void 0 : filters.length === 1 ? "dot" : activeFilterCount,
213
+ onClick: () => setSheetOpen(true)
214
+ }
215
+ ),
161
216
  /* @__PURE__ */ jsx(Drawer, { open: sheetOpen, onOpenChange: setSheetOpen, title: "Filtros", children: /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__groups", children: [
162
217
  /* @__PURE__ */ jsx(
163
218
  FilterGroups,
@@ -30,7 +30,7 @@ interface DatePickerProps extends FieldTextProps {
30
30
  }
31
31
  /**
32
32
  * DatePicker — Figma [RDS] Forms/DatePicker. A date field that takes typing (dd/mm/aaaa, the slashes come by
33
- * themselves) and, from the calendar button, opens the Calendar in a popover (Figma: `menu`). Choosing a day
33
+ * themselves) and, from the calendar button, opens the Calendar in a popover (Figma: `open`). Choosing a day
34
34
  * closes it and gives the focus back to the field; Escape closes without choosing. For a date near today, where
35
35
  * seeing the month helps: a birth date is an Input. Styles: date-picker.css, internal/field.css, calendar.css.
36
36
  */
@@ -2,10 +2,13 @@ import * as _radix_ui_react_dialog from '@radix-ui/react-dialog';
2
2
  import * as react from 'react';
3
3
  import { ModalProps } from './internal/modal.js';
4
4
 
5
- type DialogSize = 'sm' | 'default' | 'lg';
5
+ type DialogSize = 'sm' | 'md' | 'lg';
6
6
  interface DialogProps extends ModalProps {
7
- /** sm 400 (a question with one field), default 560 (a short form), lg 720 (a table or a preview). */
8
- size?: DialogSize;
7
+ /**
8
+ * sm 400 (a question with one field), md 560 (a short form, the default), lg 720 (a table or a preview) (Figma:
9
+ * `size`). `'default'` is deprecated (2.0.0-next): it is `'md'`.
10
+ */
11
+ size?: DialogSize | 'default';
9
12
  }
10
13
  /**
11
14
  * Dialog — Figma [RDS] Overlays/Dialog. A window over the screen for a short task: create, edit (Radix Dialog).
@@ -6,8 +6,8 @@ import {
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { ModalClose, ModalShell } from "./internal/modal.js";
8
8
  function Dialog(_a) {
9
- var _b = _a, { size = "default" } = _b, props = __objRest(_b, ["size"]);
10
- return /* @__PURE__ */ jsx(ModalShell, __spreadValues({ prefix: "rds-dialog", modifiers: [`rds-dialog--${size}`] }, props));
9
+ var _b = _a, { size = "md" } = _b, props = __objRest(_b, ["size"]);
10
+ return /* @__PURE__ */ jsx(ModalShell, __spreadValues({ prefix: "rds-dialog", modifiers: [`rds-dialog--${size === "default" ? "md" : size}`] }, props));
11
11
  }
12
12
  const DialogClose = ModalClose;
13
13
  export {
@@ -30,8 +30,11 @@ declare function DropdownMenu({ trigger, children, align, side, open, defaultOpe
30
30
  interface DropdownMenuItemProps extends MenuItemContentProps {
31
31
  /** Runs when the item is chosen (click, Enter or Space); the menu then closes. A destructive action asks first (AlertDialog). */
32
32
  onSelect?: () => void;
33
- /** danger for what destroys: last, after a separator (Figma: `tone`). */
34
- tone?: DropdownMenuItemTone;
33
+ /**
34
+ * neutral (default), or danger for what destroys: last, after a separator (Figma: `tone`). `'default'` is
35
+ * deprecated (2.0.0-next): it is `'neutral'`.
36
+ */
37
+ tone?: DropdownMenuItemTone | 'default';
35
38
  /** Stays in the list, can't be chosen, and the arrows skip it. */
36
39
  disabled?: boolean;
37
40
  /** The text typing jumps by, when the label is not plain text. */
@@ -2,7 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
 
4
4
  /**
5
- * @deprecated Use `<FileInput variant="dropzone">` (Figma [RDS] Forms/FileInput), which has the label, the hint, the
5
+ * @deprecated Use `<FileInput layout="dropzone">` (Figma [RDS] Forms/FileInput), which has the label, the hint, the
6
6
  * error and the chosen file's row. Kept as a thin wrapper so 1.x code keeps compiling.
7
7
  */
8
8
  interface DropzoneProps {
@@ -17,7 +17,7 @@ interface DropzoneProps {
17
17
  'aria-label'?: string;
18
18
  }
19
19
  /**
20
- * @deprecated Use `<FileInput variant="dropzone">`. A drop target only: it hands the files over and stays empty,
20
+ * @deprecated Use `<FileInput layout="dropzone">`. A drop target only: it hands the files over and stays empty,
21
21
  * ready for the next ones, as the 1.x Dropzone did.
22
22
  */
23
23
  declare function Dropzone({ onFiles, accept, multiple, disabled, className, children, 'aria-label': ariaLabel, }: DropzoneProps): react.JSX.Element;
@@ -14,7 +14,7 @@ function Dropzone({
14
14
  return /* @__PURE__ */ jsx(
15
15
  FileInput,
16
16
  {
17
- variant: "dropzone",
17
+ layout: "dropzone",
18
18
  "aria-label": ariaLabel,
19
19
  dropTitle: children,
20
20
  fileName: "",