@rojaostudio/ds 2.0.0-next.26 → 2.0.0-next.27
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.
|
@@ -4,8 +4,10 @@ import { ReactNode } from 'react';
|
|
|
4
4
|
type DataTableHeaderSearch = {
|
|
5
5
|
value: string;
|
|
6
6
|
onChange: (v: string) => void;
|
|
7
|
-
/**
|
|
7
|
+
/** What the field shows while empty, saying what is searched ("Buscar produtos…"). Default "Buscar…". */
|
|
8
8
|
placeholder?: string;
|
|
9
|
+
/** The field's accessible name, apart from the placeholder ("Buscar produtos"). Default "Buscar". */
|
|
10
|
+
label?: string;
|
|
9
11
|
};
|
|
10
12
|
type DataTableFilterOption = {
|
|
11
13
|
value: string;
|
|
@@ -26,15 +28,24 @@ type DataTableHeaderProps = {
|
|
|
26
28
|
/**
|
|
27
29
|
* Quick filters, always in view (Figma: `showQuickFilters` + the `quickFilters` slot): up to three, a
|
|
28
30
|
* FilterChipGroup with its FilterChips; four or more, one Button with a menu (DropdownMenu), "Categoria: Todas".
|
|
31
|
+
* No quick filters: do not pass the slot (Figma: `showQuickFilters` false). Wrapped in a group "Filtros rápidos".
|
|
29
32
|
*/
|
|
30
33
|
quickFilters?: ReactNode;
|
|
31
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Clears the `filters` (Figma: `clear`, "Limpar filtros" at the end of the active filters line, shown while a
|
|
36
|
+
* filter is on). The focus goes back to the search.
|
|
37
|
+
*/
|
|
32
38
|
onClear?: () => void;
|
|
33
39
|
/**
|
|
34
|
-
* A view control after the filters
|
|
35
|
-
*
|
|
40
|
+
* A view control after the filters (Figma: `showView` + the `view` slot), such as a Checkbox "Agrupar por
|
|
41
|
+
* produto". In view in the compact arrangement too.
|
|
36
42
|
*/
|
|
37
43
|
view?: ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* How many results (Figma: `showCount` + `count`), at the end of the tools: "128 resultados". A live region
|
|
46
|
+
* (aria-live polite), so the total is announced as the list is filtered.
|
|
47
|
+
*/
|
|
48
|
+
count?: ReactNode;
|
|
38
49
|
/**
|
|
39
50
|
* The list's action (Figma: `showActions`, off by default, + the `actions` instance): an IconButton, neutral outline
|
|
40
51
|
* md, with its Tooltip, such as a gear "Organizar categorias" or exporting. It sits outside the tools, always at the
|
|
@@ -52,21 +63,29 @@ declare function FilterDropdown({ f, placement }: {
|
|
|
52
63
|
placement?: 'bottom-start' | 'bottom-end';
|
|
53
64
|
}): react.JSX.Element;
|
|
54
65
|
/**
|
|
55
|
-
* DataTableHeader — a composition of the Input (search), FilterChips, Buttons, the DropdownMenu, the Popover
|
|
56
|
-
* the Drawer: the bar above a table
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
66
|
+
* DataTableHeader — a composition of the Input (search), FilterChips, Chips, Buttons, the DropdownMenu, the Popover
|
|
67
|
+
* and the Drawer: the bar above a table (Figma [RDS] DataTableHeader, no variants). Two lines, 8 apart:
|
|
68
|
+
*
|
|
69
|
+
* - `row`, which never wraps: the tools (the search, the quick filters, the filter trigger, the view control and the
|
|
70
|
+
* count) wrap inside their own group, packed to the start; the action stays outside it, at the end of the first
|
|
71
|
+
* line, on the right. The search is always first and takes the free width, at least `--data-table-header-search-min`
|
|
72
|
+
* (320; 200 below 1024); what does not fit wraps.
|
|
73
|
+
* - `active`, only while a filter is on (one filter too): the active filters as removable Chips ("Status: Abertos"),
|
|
74
|
+
* wrapping, and "Limpar filtros" (a ghost sm Button, `onClear`) at the end, which gives the focus back to the search.
|
|
75
|
+
*
|
|
76
|
+
* Quick filters go in the `quickFilters` slot; 0 quick filters = do not pass the slot. One filter is a Button with a
|
|
77
|
+
* menu; two or more collapse into "Filtros" (a Popover), the count in its label ("Filtros · 2"). No Separator between
|
|
78
|
+
* the groups (it is left orphaned at the start of a wrapped line) and no Badge over the trigger.
|
|
63
79
|
*
|
|
64
80
|
* Two arrangements, by the screen width, as the Figma viewport mode (layout/compact below lg 1024; the SavingBar's cut):
|
|
65
|
-
* expanded from 1024, the
|
|
66
|
-
*
|
|
67
|
-
*
|
|
81
|
+
* expanded from 1024, the trigger is a Button with its label; compact below it, an outline IconButton (sliders, 44)
|
|
82
|
+
* that, while a filter is on, becomes a fill Button with the number ("2"), named "Filtros, 2 ativos" or
|
|
83
|
+
* "Categoria, Pago"; one filter opens a Drawer (never a popover on a phone). There is no screen prop.
|
|
84
|
+
*
|
|
85
|
+
* Tab order is the visual order: search → quick filters → filter trigger → view → action → active Chips → Limpar
|
|
86
|
+
* filtros. Escape closes the menu, Popover or Drawer and gives the focus back to the trigger.
|
|
68
87
|
* Styles: data-table-header.css.
|
|
69
88
|
*/
|
|
70
|
-
declare function DataTableHeader({ search, filters, quickFilters, onClear, view, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
|
|
89
|
+
declare function DataTableHeader({ search, filters, quickFilters, onClear, view, count, actions, className, mobileCollapse, }: DataTableHeaderProps): react.JSX.Element;
|
|
71
90
|
|
|
72
91
|
export { type DataTableFilterDef, type DataTableFilterOption, DataTableHeader, type DataTableHeaderProps, type DataTableHeaderSearch, FilterDropdown };
|
|
@@ -5,8 +5,7 @@ import {
|
|
|
5
5
|
__spreadValues
|
|
6
6
|
} from "../chunk-ORMEWXMH.js";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { useState } from "react";
|
|
9
|
-
import { Badge } from "./badge.js";
|
|
8
|
+
import { useRef, useState } from "react";
|
|
10
9
|
import { Button } from "./button.js";
|
|
11
10
|
import { Chip } from "./chip.js";
|
|
12
11
|
import { Drawer } from "./drawer.js";
|
|
@@ -14,18 +13,32 @@ import { DropdownMenu, DropdownMenuRadioGroup, DropdownMenuRadioItem } from "./d
|
|
|
14
13
|
import { FilterChip, FilterChipGroup } from "./filter-chip.js";
|
|
15
14
|
import { IconButton } from "./icon-button.js";
|
|
16
15
|
import { Input } from "./input.js";
|
|
17
|
-
import {
|
|
16
|
+
import { SearchIcon, SlidersIcon } from "./internal/icons.js";
|
|
18
17
|
import { Popover } from "./popover.js";
|
|
19
|
-
import { Separator } from "./separator.js";
|
|
20
18
|
import { Tooltip } from "./tooltip.js";
|
|
21
19
|
function optionLabel(filter) {
|
|
22
20
|
var _a, _b;
|
|
23
21
|
if (filter.value === "") return filter.label;
|
|
24
22
|
return (_b = (_a = filter.options.find((o) => o.value === filter.value)) == null ? void 0 : _a.label) != null ? _b : filter.label;
|
|
25
23
|
}
|
|
24
|
+
function chipLabel(filter) {
|
|
25
|
+
return `${filter.label}: ${optionLabel(filter)}`;
|
|
26
|
+
}
|
|
26
27
|
function FilterTrigger(_a) {
|
|
27
28
|
var _b = _a, { filter } = _b, rest = __objRest(_b, ["filter"]);
|
|
28
|
-
|
|
29
|
+
const on = filter.value !== "";
|
|
30
|
+
return /* @__PURE__ */ jsx(
|
|
31
|
+
Button,
|
|
32
|
+
__spreadProps(__spreadValues({}, rest), {
|
|
33
|
+
tone: "neutral",
|
|
34
|
+
variant: on ? "fill" : "outline",
|
|
35
|
+
icon: /* @__PURE__ */ jsx(SlidersIcon, {}),
|
|
36
|
+
iconPosition: "start",
|
|
37
|
+
"aria-label": on ? `${filter.label}, ${optionLabel(filter)}` : void 0,
|
|
38
|
+
"data-filter-toggle": "",
|
|
39
|
+
children: filter.label
|
|
40
|
+
})
|
|
41
|
+
);
|
|
29
42
|
}
|
|
30
43
|
function FilterDropdown({ f, placement = "bottom-start" }) {
|
|
31
44
|
return /* @__PURE__ */ jsx(DropdownMenu, { align: placement === "bottom-end" ? "end" : "start", "aria-label": f.label, trigger: /* @__PURE__ */ jsx(FilterTrigger, { filter: f }), children: /* @__PURE__ */ jsx(DropdownMenuRadioGroup, { value: f.value, onValueChange: f.onChange, children: f.options.map((opt) => /* @__PURE__ */ jsx(DropdownMenuRadioItem, { value: opt.value, textValue: opt.label, children: opt.count != null ? `${opt.label} \xB7 ${opt.count}` : opt.label }, opt.value)) }) });
|
|
@@ -44,26 +57,13 @@ function FiltersButton(_c) {
|
|
|
44
57
|
})
|
|
45
58
|
);
|
|
46
59
|
}
|
|
47
|
-
function FilterGroups({
|
|
48
|
-
filters,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}) {
|
|
53
|
-
return /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__groups", children: [
|
|
54
|
-
filters.map((f) => /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__group", children: [
|
|
55
|
-
/* @__PURE__ */ jsx("p", { className: "rds-data-table-header__group-label", "aria-hidden": "true", children: f.label }),
|
|
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)) })
|
|
57
|
-
] }, f.key)),
|
|
58
|
-
onClear && showClear && /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "ghost", onClick: onClear, children: "Limpar filtros" })
|
|
59
|
-
] });
|
|
60
|
+
function FilterGroups({ filters, onPick }) {
|
|
61
|
+
return /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__groups", children: filters.map((f) => /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__group", children: [
|
|
62
|
+
/* @__PURE__ */ jsx("p", { className: "rds-data-table-header__group-label", "aria-hidden": "true", children: f.label }),
|
|
63
|
+
/* @__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)) })
|
|
64
|
+
] }, f.key)) });
|
|
60
65
|
}
|
|
61
|
-
function FiltersPopover({
|
|
62
|
-
filters,
|
|
63
|
-
onClear,
|
|
64
|
-
showClear,
|
|
65
|
-
trigger
|
|
66
|
-
}) {
|
|
66
|
+
function FiltersPopover({ filters, trigger }) {
|
|
67
67
|
const [open, setOpen] = useState(false);
|
|
68
68
|
return /* @__PURE__ */ jsx(Popover, { trigger, "aria-label": "Filtros", side: "bottom", align: "end", open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__scroll", children: /* @__PURE__ */ jsx(
|
|
69
69
|
FilterGroups,
|
|
@@ -72,12 +72,7 @@ function FiltersPopover({
|
|
|
72
72
|
onPick: (f, v) => {
|
|
73
73
|
f.onChange(v);
|
|
74
74
|
setOpen(false);
|
|
75
|
-
}
|
|
76
|
-
onClear: onClear ? () => {
|
|
77
|
-
onClear();
|
|
78
|
-
setOpen(false);
|
|
79
|
-
} : void 0,
|
|
80
|
-
showClear
|
|
75
|
+
}
|
|
81
76
|
}
|
|
82
77
|
) }) });
|
|
83
78
|
}
|
|
@@ -85,45 +80,42 @@ function CompactFilterTrigger(_e) {
|
|
|
85
80
|
var _f = _e, {
|
|
86
81
|
label,
|
|
87
82
|
state,
|
|
88
|
-
|
|
83
|
+
active
|
|
89
84
|
} = _f, rest = __objRest(_f, [
|
|
90
85
|
"label",
|
|
91
86
|
"state",
|
|
92
|
-
"
|
|
87
|
+
"active"
|
|
93
88
|
]);
|
|
94
|
-
|
|
95
|
-
|
|
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
|
-
] });
|
|
89
|
+
const name = state ? `${label}, ${state}` : label;
|
|
90
|
+
return /* @__PURE__ */ jsx(Tooltip, { text: label, children: active > 0 ? /* @__PURE__ */ jsx(Button, __spreadProps(__spreadValues({}, rest), { tone: "neutral", variant: "fill", icon: /* @__PURE__ */ jsx(SlidersIcon, {}), iconPosition: "start", "aria-label": name, "data-filter-toggle": "", children: String(active) })) : /* @__PURE__ */ jsx(IconButton, __spreadProps(__spreadValues({}, rest), { icon: /* @__PURE__ */ jsx(SlidersIcon, {}), label: name, variant: "outline", tone: "neutral", size: "md", "data-filter-toggle": "" })) });
|
|
109
91
|
}
|
|
110
92
|
function activeState(count) {
|
|
111
93
|
if (count === 0) return void 0;
|
|
112
94
|
return count === 1 ? "1 ativo" : `${count} ativos`;
|
|
113
95
|
}
|
|
96
|
+
function useDrawer() {
|
|
97
|
+
const [open, setOpenState] = useState(false);
|
|
98
|
+
const triggerRef = useRef(null);
|
|
99
|
+
const setOpen = (next) => {
|
|
100
|
+
setOpenState(next);
|
|
101
|
+
if (!next) requestAnimationFrame(() => {
|
|
102
|
+
var _a;
|
|
103
|
+
return (_a = triggerRef.current) == null ? void 0 : _a.focus();
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
const triggerProps = {
|
|
107
|
+
ref: triggerRef,
|
|
108
|
+
"aria-haspopup": "dialog",
|
|
109
|
+
"aria-expanded": open,
|
|
110
|
+
onClick: () => setOpen(true)
|
|
111
|
+
};
|
|
112
|
+
return { open, setOpen, triggerProps };
|
|
113
|
+
}
|
|
114
114
|
function MobileSingleFilter({ f }) {
|
|
115
|
-
const
|
|
115
|
+
const { open, setOpen, triggerProps } = useDrawer();
|
|
116
116
|
const on = f.value !== "";
|
|
117
117
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
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
|
-
),
|
|
118
|
+
/* @__PURE__ */ jsx(CompactFilterTrigger, __spreadProps(__spreadValues({}, triggerProps), { label: f.label, state: on ? optionLabel(f) : void 0, active: on ? 1 : 0 })),
|
|
127
119
|
/* @__PURE__ */ jsx(Drawer, { open, onOpenChange: setOpen, title: f.label, children: /* @__PURE__ */ jsx(
|
|
128
120
|
FilterGroups,
|
|
129
121
|
{
|
|
@@ -131,111 +123,101 @@ function MobileSingleFilter({ f }) {
|
|
|
131
123
|
onPick: (_, v) => {
|
|
132
124
|
f.onChange(v);
|
|
133
125
|
setOpen(false);
|
|
134
|
-
}
|
|
135
|
-
showClear: false
|
|
126
|
+
}
|
|
136
127
|
}
|
|
137
128
|
) })
|
|
138
129
|
] });
|
|
139
130
|
}
|
|
131
|
+
function MobileCollapsedFilters({
|
|
132
|
+
filters,
|
|
133
|
+
actions,
|
|
134
|
+
activeCount
|
|
135
|
+
}) {
|
|
136
|
+
const { open, setOpen, triggerProps } = useDrawer();
|
|
137
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
+
/* @__PURE__ */ jsx(CompactFilterTrigger, __spreadProps(__spreadValues({}, triggerProps), { label: "Filtros", state: activeState(activeCount), active: activeCount })),
|
|
139
|
+
/* @__PURE__ */ jsx(Drawer, { open, onOpenChange: setOpen, title: "Filtros", children: /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__groups", children: [
|
|
140
|
+
/* @__PURE__ */ jsx(
|
|
141
|
+
FilterGroups,
|
|
142
|
+
{
|
|
143
|
+
filters,
|
|
144
|
+
onPick: (f, v) => {
|
|
145
|
+
f.onChange(v);
|
|
146
|
+
setOpen(false);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
actions && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__drawer-actions", children: actions })
|
|
151
|
+
] }) })
|
|
152
|
+
] });
|
|
153
|
+
}
|
|
140
154
|
function DataTableHeader({
|
|
141
155
|
search,
|
|
142
156
|
filters = [],
|
|
143
157
|
quickFilters,
|
|
144
158
|
onClear,
|
|
145
159
|
view,
|
|
160
|
+
count,
|
|
146
161
|
actions,
|
|
147
162
|
className,
|
|
148
163
|
mobileCollapse = false
|
|
149
164
|
}) {
|
|
150
|
-
var _a, _b;
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const collapseDesktop = filters.length >= 2;
|
|
165
|
+
var _a, _b, _c;
|
|
166
|
+
const searchRef = useRef(null);
|
|
167
|
+
const rootRef = useRef(null);
|
|
154
168
|
const activeFilters = filters.filter((f) => f.value !== "");
|
|
169
|
+
const activeFilterCount = activeFilters.length;
|
|
170
|
+
const collapseDesktop = filters.length >= 2;
|
|
155
171
|
const singleFilter = filters.length === 1 ? filters[0] : null;
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
singleFilter && !(mobileCollapse && actions) && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__narrow", children: /* @__PURE__ */ jsx(MobileSingleFilter, { f: singleFilter }) }),
|
|
191
|
-
!mobileCollapse && filters.length >= 2 && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__narrow", children: /* @__PURE__ */ jsx(
|
|
192
|
-
FiltersPopover,
|
|
193
|
-
{
|
|
194
|
-
filters,
|
|
195
|
-
onClear,
|
|
196
|
-
showClear: activeFilterCount > 0,
|
|
197
|
-
trigger: /* @__PURE__ */ jsx(
|
|
198
|
-
CompactFilterTrigger,
|
|
199
|
-
{
|
|
200
|
-
label: "Filtros",
|
|
201
|
-
state: activeState(activeFilterCount),
|
|
202
|
-
indicator: activeFilterCount > 0 ? activeFilterCount : void 0
|
|
203
|
-
}
|
|
204
|
-
)
|
|
205
|
-
}
|
|
206
|
-
) }),
|
|
207
|
-
mobileCollapse && (filters.length >= 2 || actions) && /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__narrow", children: [
|
|
208
|
-
/* @__PURE__ */ jsx(
|
|
209
|
-
CompactFilterTrigger,
|
|
172
|
+
const clear = () => {
|
|
173
|
+
onClear == null ? void 0 : onClear();
|
|
174
|
+
requestAnimationFrame(() => {
|
|
175
|
+
var _a2, _b2, _c2;
|
|
176
|
+
if (searchRef.current) {
|
|
177
|
+
searchRef.current.focus();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const toggles = (_b2 = (_a2 = rootRef.current) == null ? void 0 : _a2.querySelectorAll("[data-filter-toggle]")) != null ? _b2 : [];
|
|
181
|
+
(_c2 = [...toggles].find((t) => t.offsetParent !== null)) == null ? void 0 : _c2.focus();
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: ["rds-data-table-header", className].filter(Boolean).join(" "), children: [
|
|
185
|
+
/* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__row", children: [
|
|
186
|
+
/* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__tools", children: [
|
|
187
|
+
search && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__search", role: "search", "aria-label": (_a = search.label) != null ? _a : "Buscar", children: /* @__PURE__ */ jsx(
|
|
188
|
+
Input,
|
|
189
|
+
{
|
|
190
|
+
ref: searchRef,
|
|
191
|
+
type: "search",
|
|
192
|
+
"aria-label": (_b = search.label) != null ? _b : "Buscar",
|
|
193
|
+
placeholder: (_c = search.placeholder) != null ? _c : "Buscar\u2026",
|
|
194
|
+
leadingIcon: /* @__PURE__ */ jsx(SearchIcon, {}),
|
|
195
|
+
clearable: true,
|
|
196
|
+
clearLabel: "Limpar busca",
|
|
197
|
+
value: search.value,
|
|
198
|
+
onChange: (e) => search.onChange(e.target.value)
|
|
199
|
+
}
|
|
200
|
+
) }),
|
|
201
|
+
quickFilters && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__quick", role: "group", "aria-label": "Filtros r\xE1pidos", children: quickFilters }),
|
|
202
|
+
filters.length > 0 && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__wide", children: collapseDesktop ? /* @__PURE__ */ jsx(FiltersPopover, { filters, trigger: /* @__PURE__ */ jsx(FiltersButton, { count: activeFilterCount }) }) : filters.map((f) => /* @__PURE__ */ jsx(FilterDropdown, { f }, f.key)) }),
|
|
203
|
+
singleFilter && !(mobileCollapse && actions) && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__narrow", children: /* @__PURE__ */ jsx(MobileSingleFilter, { f: singleFilter }) }),
|
|
204
|
+
!mobileCollapse && filters.length >= 2 && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__narrow", children: /* @__PURE__ */ jsx(
|
|
205
|
+
FiltersPopover,
|
|
210
206
|
{
|
|
211
|
-
|
|
212
|
-
state: activeState(activeFilterCount),
|
|
213
|
-
indicator: activeFilterCount === 0 ? void 0 : filters.length === 1 ? "dot" : activeFilterCount,
|
|
214
|
-
onClick: () => setSheetOpen(true)
|
|
207
|
+
filters,
|
|
208
|
+
trigger: /* @__PURE__ */ jsx(CompactFilterTrigger, { label: "Filtros", state: activeState(activeFilterCount), active: activeFilterCount })
|
|
215
209
|
}
|
|
216
|
-
),
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
{
|
|
221
|
-
filters,
|
|
222
|
-
onPick: (f, v) => {
|
|
223
|
-
f.onChange(v);
|
|
224
|
-
setSheetOpen(false);
|
|
225
|
-
},
|
|
226
|
-
onClear: onClear ? () => {
|
|
227
|
-
onClear();
|
|
228
|
-
setSheetOpen(false);
|
|
229
|
-
} : void 0,
|
|
230
|
-
showClear: activeFilterCount > 0
|
|
231
|
-
}
|
|
232
|
-
),
|
|
233
|
-
actions && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__drawer-actions", children: actions })
|
|
234
|
-
] }) })
|
|
210
|
+
) }),
|
|
211
|
+
mobileCollapse && (filters.length >= 2 || actions) && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__narrow", children: /* @__PURE__ */ jsx(MobileCollapsedFilters, { filters, actions, activeCount: activeFilterCount }) }),
|
|
212
|
+
view && /* @__PURE__ */ jsx("div", { className: "rds-data-table-header__view", children: view }),
|
|
213
|
+
count != null && count !== false && /* @__PURE__ */ jsx("span", { className: "rds-data-table-header__count", "aria-live": "polite", children: count })
|
|
235
214
|
] }),
|
|
236
|
-
|
|
215
|
+
actions && /* @__PURE__ */ jsx("div", { className: ["rds-data-table-header__actions", mobileCollapse && "rds-data-table-header__wide"].filter(Boolean).join(" "), children: actions })
|
|
237
216
|
] }),
|
|
238
|
-
|
|
217
|
+
activeFilters.length > 0 && /* @__PURE__ */ jsxs("div", { className: "rds-data-table-header__active", children: [
|
|
218
|
+
/* @__PURE__ */ jsx("div", { className: "rds-data-table-header__chips", children: activeFilters.map((f) => /* @__PURE__ */ jsx(Chip, { onRemove: () => f.onChange(""), removeLabel: `Remover filtro ${chipLabel(f)}`, children: chipLabel(f) }, f.key)) }),
|
|
219
|
+
onClear && /* @__PURE__ */ jsx(Button, { tone: "neutral", variant: "ghost", size: "sm", onClick: clear, children: "Limpar filtros" })
|
|
220
|
+
] })
|
|
239
221
|
] });
|
|
240
222
|
}
|
|
241
223
|
export {
|
package/package.json
CHANGED
|
@@ -3582,35 +3582,57 @@ input:focus-visible + .rds-checkbox__box {
|
|
|
3582
3582
|
/* components/data-table-header.css */
|
|
3583
3583
|
/* @tokens data-table-header */
|
|
3584
3584
|
/*
|
|
3585
|
-
* DataTableHeader
|
|
3586
|
-
*
|
|
3587
|
-
*
|
|
3588
|
-
*
|
|
3589
|
-
*
|
|
3590
|
-
*
|
|
3591
|
-
*
|
|
3592
|
-
*
|
|
3593
|
-
*
|
|
3585
|
+
* DataTableHeader (Figma [RDS] DataTableHeader, no variants). One component token, local to this stylesheet:
|
|
3586
|
+
* --data-table-header-search-min, the search's minimum width (Figma `data-table-header/search-min`, viewport
|
|
3587
|
+
* collection of the Base Tokens, not published yet): 320 from lg 1024, 200 below it. Everything else comes from the
|
|
3588
|
+
* Input, FilterChip, Chip, Button, IconButton, Checkbox, DropdownMenu, Popover and Drawer; the count borrows the
|
|
3589
|
+
* table's muted label (--table-header-label, text/muted), the bar being the table's.
|
|
3590
|
+
*
|
|
3591
|
+
* The bar is a column, 8 apart, 12 above the table:
|
|
3592
|
+
* - `row`, which never wraps, aligned to the top: the `tools` group (the search, the quick filters, the filter
|
|
3593
|
+
* trigger, the view control, the count) takes the free width and is what wraps, packed to the start, the search
|
|
3594
|
+
* first taking the free width, at least search-min (never wider than the group); the action sits outside it,
|
|
3595
|
+
* fixed at the end of the FIRST line, on the right, and never goes down.
|
|
3596
|
+
* - `active`, only while a filter is on: the `chips` (wrapping, at least 280 before "Limpar filtros" goes down)
|
|
3597
|
+
* and "Limpar filtros" at the end.
|
|
3598
|
+
* Two arrangements, by the screen width, as the Figma viewport mode (layout/compact below lg 1024; the SavingBar's
|
|
3599
|
+
* cut): expanded from 1024 (the __wide parts: the trigger as a Button with its label); compact below it (the __narrow
|
|
3600
|
+
* parts: the trigger as an IconButton of 44, or a fill Button with the number while a filter is on).
|
|
3594
3601
|
* In the Popover and the Drawer the filters stack 16 apart, each one a caption-sized label over its chips.
|
|
3595
3602
|
*/
|
|
3596
3603
|
.rds-data-table-header {
|
|
3604
|
+
--data-table-header-search-min: 320px;
|
|
3605
|
+
|
|
3597
3606
|
box-sizing: border-box;
|
|
3598
3607
|
width: 100%;
|
|
3608
|
+
display: flex;
|
|
3609
|
+
flex-direction: column;
|
|
3610
|
+
gap: var(--space-8);
|
|
3611
|
+
margin-bottom: var(--space-12);
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
@media (max-width: 1023px) {
|
|
3615
|
+
.rds-data-table-header {
|
|
3616
|
+
--data-table-header-search-min: 200px;
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
|
|
3620
|
+
/* Figma `row`: tools + actions, never wraps. */
|
|
3621
|
+
.rds-data-table-header__row {
|
|
3599
3622
|
display: flex;
|
|
3600
3623
|
flex-wrap: nowrap;
|
|
3601
3624
|
align-items: flex-start;
|
|
3602
3625
|
gap: var(--space-8);
|
|
3603
|
-
margin-bottom: var(--space-12);
|
|
3604
3626
|
}
|
|
3605
3627
|
|
|
3606
|
-
/* Figma `tools`: horizontal, wrap, fill. */
|
|
3628
|
+
/* Figma `tools`: horizontal, wrap, fill, packed to the start. */
|
|
3607
3629
|
.rds-data-table-header__tools {
|
|
3608
3630
|
flex: 1 1 0;
|
|
3609
3631
|
min-width: 0;
|
|
3610
3632
|
display: flex;
|
|
3611
3633
|
flex-wrap: wrap;
|
|
3612
3634
|
align-items: center;
|
|
3613
|
-
justify-content: flex-
|
|
3635
|
+
justify-content: flex-start;
|
|
3614
3636
|
gap: var(--space-8);
|
|
3615
3637
|
}
|
|
3616
3638
|
|
|
@@ -3620,10 +3642,15 @@ input:focus-visible + .rds-checkbox__box {
|
|
|
3620
3642
|
align-self: flex-start;
|
|
3621
3643
|
}
|
|
3622
3644
|
|
|
3623
|
-
/*
|
|
3624
|
-
.rds-data-table-
|
|
3625
|
-
flex: 1 1
|
|
3626
|
-
min-width: min(
|
|
3645
|
+
/* The search takes the free width, at least search-min, never wider than the group: it wraps before it squeezes. */
|
|
3646
|
+
.rds-data-table-header__search {
|
|
3647
|
+
flex: 1 1 var(--data-table-header-search-min);
|
|
3648
|
+
min-width: min(var(--data-table-header-search-min), 100%);
|
|
3649
|
+
display: flex;
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3652
|
+
.rds-data-table-header__search > * {
|
|
3653
|
+
flex: 1 1 auto;
|
|
3627
3654
|
}
|
|
3628
3655
|
|
|
3629
3656
|
.rds-data-table-header__quick,
|
|
@@ -3649,44 +3676,33 @@ input:focus-visible + .rds-checkbox__box {
|
|
|
3649
3676
|
.rds-data-table-header__narrow {
|
|
3650
3677
|
display: flex;
|
|
3651
3678
|
}
|
|
3652
|
-
|
|
3653
|
-
/* Compact: the search accepts 200 (40 × 5), so it sits on one line with the filter and an IconButton at 390. */
|
|
3654
|
-
.rds-data-table-header .rds-data-table-header__search {
|
|
3655
|
-
flex-basis: calc(var(--space-40) * 5);
|
|
3656
|
-
min-width: min(calc(var(--space-40) * 5), 100%);
|
|
3657
|
-
}
|
|
3658
|
-
}
|
|
3659
|
-
|
|
3660
|
-
/* The compact filter: the IconButton with its indicator on the corner. */
|
|
3661
|
-
.rds-data-table-header__trigger {
|
|
3662
|
-
position: relative;
|
|
3663
|
-
display: inline-flex;
|
|
3664
3679
|
}
|
|
3665
3680
|
|
|
3666
|
-
.
|
|
3681
|
+
/* Figma `count`: "128 resultados", a live region at the end of the tools. */
|
|
3667
3682
|
.rds-data-table-header__count {
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
top: calc(var(--space-4) * 1.5);
|
|
3674
|
-
right: calc(var(--space-4) * 1.5);
|
|
3675
|
-
width: var(--space-8);
|
|
3676
|
-
height: var(--space-8);
|
|
3677
|
-
border-radius: var(--radius-full);
|
|
3678
|
-
background: var(--badge-neutral-fill-background);
|
|
3683
|
+
font-family: var(--type-font-stack);
|
|
3684
|
+
font-size: var(--type-small-size);
|
|
3685
|
+
line-height: var(--type-small-line);
|
|
3686
|
+
color: var(--table-header-label);
|
|
3687
|
+
white-space: nowrap;
|
|
3679
3688
|
}
|
|
3680
3689
|
|
|
3681
|
-
.
|
|
3682
|
-
|
|
3683
|
-
|
|
3690
|
+
/* Figma `activeFilters`: its own line, wrap, 8 apart. */
|
|
3691
|
+
.rds-data-table-header__active {
|
|
3692
|
+
display: flex;
|
|
3693
|
+
flex-wrap: wrap;
|
|
3694
|
+
align-items: center;
|
|
3695
|
+
gap: var(--space-8);
|
|
3684
3696
|
}
|
|
3685
3697
|
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3698
|
+
/* Figma `chips`: fill, wrap, at least 280 before "Limpar filtros" goes down. */
|
|
3699
|
+
.rds-data-table-header__chips {
|
|
3700
|
+
flex: 1 1 280px;
|
|
3701
|
+
min-width: 0;
|
|
3702
|
+
display: flex;
|
|
3703
|
+
flex-wrap: wrap;
|
|
3704
|
+
align-items: center;
|
|
3705
|
+
gap: var(--space-8);
|
|
3690
3706
|
}
|
|
3691
3707
|
|
|
3692
3708
|
.rds-data-table-header__scroll {
|