@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.
- package/dist/components/avatar.d.ts +20 -12
- package/dist/components/avatar.js +8 -6
- package/dist/components/badge.d.ts +7 -6
- package/dist/components/badge.js +2 -1
- package/dist/components/breadcrumb.d.ts +4 -4
- package/dist/components/breadcrumb.js +1 -1
- package/dist/components/bubble.d.ts +26 -11
- package/dist/components/bubble.js +3 -3
- package/dist/components/button.d.ts +1 -1
- package/dist/components/card.d.ts +18 -9
- package/dist/components/card.js +4 -2
- package/dist/components/color-input.d.ts +1 -1
- package/dist/components/context-menu.d.ts +5 -2
- package/dist/components/data-table-header.d.ts +10 -5
- package/dist/components/data-table-header.js +59 -4
- package/dist/components/date-picker.d.ts +1 -1
- package/dist/components/dialog.d.ts +6 -3
- package/dist/components/dialog.js +2 -2
- package/dist/components/dropdown-menu.d.ts +5 -2
- package/dist/components/dropzone.d.ts +2 -2
- package/dist/components/dropzone.js +1 -1
- package/dist/components/file-input.d.ts +13 -8
- package/dist/components/file-input.js +24 -21
- package/dist/components/filter-chip.d.ts +11 -5
- package/dist/components/filter-chip.js +15 -6
- package/dist/components/heading.d.ts +9 -6
- package/dist/components/heading.js +1 -1
- package/dist/components/icon-button.d.ts +1 -1
- package/dist/components/image-upload.d.ts +2 -2
- package/dist/components/image-upload.js +1 -1
- package/dist/components/index.d.ts +6 -6
- package/dist/components/internal/button.d.ts +1 -1
- package/dist/components/internal/menu.d.ts +3 -2
- package/dist/components/internal/menu.js +1 -1
- package/dist/components/internal/toggle.d.ts +1 -1
- package/dist/components/item.d.ts +14 -7
- package/dist/components/item.js +5 -2
- package/dist/components/marker.d.ts +11 -3
- package/dist/components/marker.js +4 -3
- package/dist/components/progress.d.ts +3 -3
- package/dist/components/progress.js +2 -2
- package/dist/components/row-actions.d.ts +3 -0
- package/dist/components/row-actions.js +8 -4
- package/dist/components/sidebar.d.ts +8 -11
- package/dist/components/sidebar.js +4 -5
- package/dist/components/spinner.d.ts +9 -6
- package/dist/components/spinner.js +3 -3
- package/dist/components/star-rating.d.ts +3 -3
- package/dist/components/star-rating.js +2 -2
- package/dist/components/stat.d.ts +18 -6
- package/dist/components/stat.js +9 -3
- package/dist/components/status.d.ts +4 -4
- package/dist/components/status.js +2 -2
- package/dist/components/summary-bar.d.ts +3 -2
- package/dist/components/summary-bar.js +10 -1
- package/dist/components/tile.d.ts +5 -5
- package/dist/components/tile.js +2 -2
- package/dist/components/time-picker.d.ts +1 -1
- package/dist/components/toast.d.ts +1 -1
- package/dist/components/toggle.d.ts +1 -1
- package/dist/components/typing-indicator.d.ts +2 -2
- package/dist/components/typing-indicator.js +1 -1
- package/package.json +1 -1
- package/styles/rds/components-styles.css +84 -48
- 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' | '
|
|
7
|
-
/**
|
|
8
|
-
|
|
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
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
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: `
|
|
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 `
|
|
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,
|
|
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 : "
|
|
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
|
|
46
|
+
const content = src && failed !== src ? "image" : letters ? "fallback" : "icon";
|
|
46
47
|
const label = trimmed ? showBadge ? `${trimmed}, ${badgeLabel}` : trimmed : void 0;
|
|
47
|
-
const semantics =
|
|
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--${
|
|
52
|
+
className: ["rds-avatar", `rds-avatar--${type}`, `rds-avatar--${finalSize}`, `rds-avatar--${content}`, className].filter(Boolean).join(" "),
|
|
52
53
|
children: [
|
|
53
|
-
|
|
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 = "
|
|
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
|
|
6
|
-
type BadgeVariant = 'fill' | 'soft'
|
|
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):
|
|
15
|
-
*
|
|
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?:
|
|
19
|
+
variant?: BadgeVariant;
|
|
20
20
|
} | {
|
|
21
21
|
tone: 'accent';
|
|
22
|
-
|
|
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';
|
package/dist/components/badge.js
CHANGED
|
@@ -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}-${
|
|
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 = '
|
|
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.
|
|
20
|
-
*
|
|
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 = "
|
|
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
|
-
|
|
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
|
|
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
|
|
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 = "
|
|
10
|
-
if (
|
|
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: `
|
|
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 = '
|
|
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
|
|
10
|
-
* outline: only the border, no fill nor shadow, it takes the surface underneath; for cards side by
|
|
11
|
-
* inside a panel or a list.
|
|
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
|
-
/**
|
|
15
|
-
|
|
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
|
|
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 };
|
package/dist/components/card.js
CHANGED
|
@@ -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
|
|
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--${
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
32
|
-
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
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.
|
|
54
|
-
*
|
|
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, {
|
|
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(
|
|
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(
|
|
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(
|
|
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: `
|
|
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' | '
|
|
5
|
+
type DialogSize = 'sm' | 'md' | 'lg';
|
|
6
6
|
interface DialogProps extends ModalProps {
|
|
7
|
-
/**
|
|
8
|
-
|
|
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 = "
|
|
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
|
-
/**
|
|
34
|
-
|
|
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
|
|
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
|
|
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;
|