prime-ui-kit 0.18.0 → 0.20.0
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/README.md +1 -1
- package/dist/chunks/{chunk-OAXJWF3L.js → chunk-3PY52JP3.js} +1764 -1764
- package/dist/chunks/{chunk-X3JT5CLR.js → chunk-4KONMO7Z.js} +1 -1
- package/dist/chunks/{chunk-MB4CXSLL.js → chunk-W6EGTNG6.js} +3772 -2888
- package/dist/color-picker.js +2 -2
- package/dist/components/data-table/ColumnsMenu.d.ts +39 -17
- package/dist/components/data-table/DataTable.d.ts +41 -12
- package/dist/components/data-table/DataTableColumnsMenu.d.ts +45 -0
- package/dist/components/data-table/Head.d.ts +18 -5
- package/dist/components/data-table/Row.d.ts +10 -4
- package/dist/components/data-table/StateRows.d.ts +5 -3
- package/dist/components/data-table/columnOrder.d.ts +14 -0
- package/dist/components/data-table/reorder.d.ts +15 -5
- package/dist/components/data-table/types.d.ts +5 -0
- package/dist/components/data-table/useFrozenColumns.d.ts +6 -2
- package/dist/components/datepicker/DatepickerPanel.d.ts +1 -1
- package/dist/components/dnd/Dnd.d.ts +9 -5
- package/dist/components/dnd/inPlaceRow.d.ts +7 -0
- package/dist/components/dnd/useDragSource.d.ts +2 -0
- package/dist/components/dnd/useSortableList.d.ts +5 -0
- package/dist/components/field-list/FieldList.d.ts +37 -15
- package/dist/components/gantt/Gantt.d.ts +1 -1
- package/dist/components/index.d.ts +3 -1
- package/dist/components/kanban/Kanban.d.ts +4 -0
- package/dist/components/list/List.d.ts +9 -4
- package/dist/components/scroll-container/ScrollContainer.d.ts +1 -1
- package/dist/index.css +1 -1
- package/dist/index.js +4 -2
- package/dist/internal/ToolRow.d.ts +23 -0
- package/dist/internal/leaveGuard.d.ts +6 -0
- package/dist/internal/overlay/DialogGuard.d.ts +3 -2
- package/dist/internal/overlay/DialogParts.d.ts +14 -5
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/page/Page.d.ts +8 -14
- package/dist/skill/anti-slop.md +55 -1
- package/dist/skill/api-contract.md +2 -2
- package/dist/skill/cheatsheet.md +12 -4
- package/dist/skill/checklist.md +7 -0
- package/dist/skill/choosing.md +1 -0
- package/dist/skill/components.md +1 -1
- package/dist/skill/composition.md +196 -21
- package/dist/skill/layouts.md +1 -1
- package/dist/skill/reference/components/confirm-dialog/COMPONENT.md +1 -1
- package/dist/skill/reference/components/data-table/COMPONENT.md +110 -49
- package/dist/skill/reference/components/data-table/examples/actions-column.tsx +154 -0
- package/dist/skill/reference/components/data-table/examples/column-order.tsx +152 -0
- package/dist/skill/reference/components/data-table/examples/columns-visibility.tsx +18 -18
- package/dist/skill/reference/components/data-table/examples/controlled.tsx +32 -17
- package/dist/skill/reference/components/data-table/examples/examples.module.css +14 -36
- package/dist/skill/reference/components/data-table/examples/narrow.tsx +25 -19
- package/dist/skill/reference/components/data-table/examples/reorder.tsx +24 -2
- package/dist/skill/reference/components/data-table/examples/row-link.tsx +18 -22
- package/dist/skill/reference/components/data-table/examples/screen.tsx +12 -1
- package/dist/skill/reference/components/data-table/examples/selection.tsx +13 -18
- package/dist/skill/reference/components/data-table/examples/server.tsx +45 -31
- package/dist/skill/reference/components/data-table/examples/toolbar.tsx +22 -35
- package/dist/skill/reference/components/datepicker/COMPONENT.md +2 -2
- package/dist/skill/reference/components/dnd/COMPONENT.md +13 -7
- package/dist/skill/reference/components/dnd/examples/examples.module.css +4 -3
- package/dist/skill/reference/components/dnd/examples/handle.tsx +5 -5
- package/dist/skill/reference/components/dnd/examples/locked.tsx +1 -1
- package/dist/skill/reference/components/dnd/examples/table-columns.tsx +75 -0
- package/dist/skill/reference/components/dnd/examples/table.tsx +6 -6
- package/dist/skill/reference/components/drawer/COMPONENT.md +26 -10
- package/dist/skill/reference/components/drawer/examples/header-actions.tsx +1 -1
- package/dist/skill/reference/components/drawer/examples/loading.tsx +58 -0
- package/dist/skill/reference/components/field-list/COMPONENT.md +78 -47
- package/dist/skill/reference/components/field-list/examples/base-row.tsx +2 -1
- package/dist/skill/reference/components/field-list/examples/locked.tsx +11 -11
- package/dist/skill/reference/components/field-list/examples/narrow.tsx +108 -33
- package/dist/skill/reference/components/field-list/examples/reorder.tsx +1 -1
- package/dist/skill/reference/components/field-list/examples/row-menu.tsx +71 -0
- package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/field-list/examples/screen.tsx +169 -162
- package/dist/skill/reference/components/field-list/examples/totals.tsx +9 -8
- package/dist/skill/reference/components/field-list/examples/variants.tsx +51 -0
- package/dist/skill/reference/components/gantt/COMPONENT.md +4 -4
- package/dist/skill/reference/components/kanban/COMPONENT.md +6 -2
- package/dist/skill/reference/components/kanban/examples/states.tsx +7 -5
- package/dist/skill/reference/components/list/COMPONENT.md +21 -11
- package/dist/skill/reference/components/list/examples/reorder.tsx +42 -7
- package/dist/skill/reference/components/modal/COMPONENT.md +23 -10
- package/dist/skill/reference/components/scroll-container/COMPONENT.md +1 -1
- package/dist/skill/reference/components/segmented-control/COMPONENT.md +3 -2
- package/dist/skill/reference/components/sheet/COMPONENT.md +18 -7
- package/dist/skill/reference/components/smart-filter/COMPONENT.md +2 -2
- package/dist/skill/reference/layout/page/COMPONENT.md +13 -17
- package/dist/skill/reference/layout/page/examples/screen.module.css +1 -1
- package/dist/skill/reference/layout/page/examples/screen.tsx +93 -104
- package/dist/skill/reference/layout/page/examples/sections.tsx +2 -15
- package/dist/skill/responsive.md +14 -10
- package/dist/tokens/semantic.d.ts +2 -2
- package/dist/tokens/themes/dark.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/confirm-dialog/COMPONENT.md +1 -1
- package/src/components/data-table/COMPONENT.md +110 -49
- package/src/components/data-table/examples/actions-column.tsx +154 -0
- package/src/components/data-table/examples/column-order.tsx +152 -0
- package/src/components/data-table/examples/columns-visibility.tsx +18 -18
- package/src/components/data-table/examples/controlled.tsx +32 -17
- package/src/components/data-table/examples/examples.module.css +14 -36
- package/src/components/data-table/examples/narrow.tsx +25 -19
- package/src/components/data-table/examples/reorder.tsx +24 -2
- package/src/components/data-table/examples/row-link.tsx +18 -22
- package/src/components/data-table/examples/screen.tsx +12 -1
- package/src/components/data-table/examples/selection.tsx +13 -18
- package/src/components/data-table/examples/server.tsx +45 -31
- package/src/components/data-table/examples/toolbar.tsx +22 -35
- package/src/components/datepicker/COMPONENT.md +2 -2
- package/src/components/dnd/COMPONENT.md +13 -7
- package/src/components/dnd/examples/examples.module.css +4 -3
- package/src/components/dnd/examples/handle.tsx +5 -5
- package/src/components/dnd/examples/locked.tsx +1 -1
- package/src/components/dnd/examples/table-columns.tsx +75 -0
- package/src/components/dnd/examples/table.tsx +6 -6
- package/src/components/drawer/COMPONENT.md +26 -10
- package/src/components/drawer/examples/header-actions.tsx +1 -1
- package/src/components/drawer/examples/loading.tsx +58 -0
- package/src/components/field-list/COMPONENT.md +78 -47
- package/src/components/field-list/examples/base-row.tsx +2 -1
- package/src/components/field-list/examples/locked.tsx +11 -11
- package/src/components/field-list/examples/narrow.tsx +108 -33
- package/src/components/field-list/examples/reorder.tsx +1 -1
- package/src/components/field-list/examples/row-menu.tsx +71 -0
- package/src/components/field-list/examples/screen.module.css +1 -1
- package/src/components/field-list/examples/screen.tsx +169 -162
- package/src/components/field-list/examples/totals.tsx +9 -8
- package/src/components/field-list/examples/variants.tsx +51 -0
- package/src/components/gantt/COMPONENT.md +4 -4
- package/src/components/kanban/COMPONENT.md +6 -2
- package/src/components/kanban/examples/states.tsx +7 -5
- package/src/components/list/COMPONENT.md +21 -11
- package/src/components/list/examples/reorder.tsx +42 -7
- package/src/components/modal/COMPONENT.md +23 -10
- package/src/components/scroll-container/COMPONENT.md +1 -1
- package/src/components/segmented-control/COMPONENT.md +3 -2
- package/src/components/sheet/COMPONENT.md +18 -7
- package/src/components/smart-filter/COMPONENT.md +2 -2
- package/src/layout/page/COMPONENT.md +13 -17
- package/src/layout/page/examples/screen.module.css +1 -1
- package/src/layout/page/examples/screen.tsx +93 -104
- package/src/layout/page/examples/sections.tsx +2 -15
- package/src/styles/theme-dark.css +1 -1
- package/src/styles/theme-light.css +1 -1
- package/dist/components/data-table/context.d.ts +0 -14
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/** Orders whose columns a manager puts in place by dragging a header — it moves alone and the gap opens among the headers where it lands — or with Alt + ← / →, and shows, hides and reorders in the chooser over the row menu; the order number stays first and the row menu last, and the choice outlives a reload — `columnOrder`, `onColumnOrderChange`, `reorderable`, `columnsMenu`, `hiddenColumns`. */
|
|
2
|
+
import { Badge, Button, DataTable, type DataTableColumn, Dropdown, Icon } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
type Status = "paid" | "shipped" | "waiting";
|
|
6
|
+
type Order = {
|
|
7
|
+
id: string;
|
|
8
|
+
client: string;
|
|
9
|
+
manager: string;
|
|
10
|
+
city: string;
|
|
11
|
+
status: Status;
|
|
12
|
+
date: string;
|
|
13
|
+
total: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const STATUS: Record<Status, { label: string; color: "green" | "blue" | "orange" }> = {
|
|
17
|
+
paid: { label: "Оплачен", color: "green" },
|
|
18
|
+
shipped: { label: "Отгружен", color: "blue" },
|
|
19
|
+
waiting: { label: "Ждёт оплаты", color: "orange" },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const ORDERS: Order[] = [
|
|
23
|
+
{
|
|
24
|
+
id: "№ 1040",
|
|
25
|
+
client: "ООО «Северный ветер»",
|
|
26
|
+
manager: "Ольга Смирнова",
|
|
27
|
+
city: "Москва",
|
|
28
|
+
status: "paid",
|
|
29
|
+
date: "02.10.2026",
|
|
30
|
+
total: 184_500,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "№ 1041",
|
|
34
|
+
client: "ИП Козлов",
|
|
35
|
+
manager: "Игорь Волков",
|
|
36
|
+
city: "Казань",
|
|
37
|
+
status: "waiting",
|
|
38
|
+
date: "03.10.2026",
|
|
39
|
+
total: 27_900,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "№ 1042",
|
|
43
|
+
client: "АО «Технопарк»",
|
|
44
|
+
manager: "Ольга Смирнова",
|
|
45
|
+
city: "Санкт-Петербург",
|
|
46
|
+
status: "shipped",
|
|
47
|
+
date: "04.10.2026",
|
|
48
|
+
total: 612_000,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "№ 1043",
|
|
52
|
+
client: "ООО «Лето»",
|
|
53
|
+
manager: "Мария Орлова",
|
|
54
|
+
city: "Екатеринбург",
|
|
55
|
+
status: "paid",
|
|
56
|
+
date: "05.10.2026",
|
|
57
|
+
total: 58_350,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
const RUB = new Intl.NumberFormat("ru-RU", {
|
|
62
|
+
style: "currency",
|
|
63
|
+
currency: "RUB",
|
|
64
|
+
maximumFractionDigits: 0,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const COLUMNS: DataTableColumn<Order>[] = [
|
|
68
|
+
{ id: "id", header: "Заказ", accessor: "id", hideable: false, reorderable: false },
|
|
69
|
+
{ id: "client", header: "Клиент", accessor: "client", sortable: true },
|
|
70
|
+
{ id: "manager", header: "Менеджер", accessor: "manager" },
|
|
71
|
+
{ id: "city", header: "Город", accessor: "city" },
|
|
72
|
+
{
|
|
73
|
+
id: "status",
|
|
74
|
+
header: "Статус",
|
|
75
|
+
cell: (row) => (
|
|
76
|
+
<Badge.Root color={STATUS[row.status].color}>{STATUS[row.status].label}</Badge.Root>
|
|
77
|
+
),
|
|
78
|
+
},
|
|
79
|
+
{ id: "date", header: "Дата", accessor: "date", numeric: true },
|
|
80
|
+
{
|
|
81
|
+
id: "total",
|
|
82
|
+
header: "Сумма",
|
|
83
|
+
accessor: "total",
|
|
84
|
+
sortable: true,
|
|
85
|
+
numeric: true,
|
|
86
|
+
cell: (row) => RUB.format(row.total),
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "actions",
|
|
90
|
+
header: "Действия",
|
|
91
|
+
hideHeader: true,
|
|
92
|
+
hideable: false,
|
|
93
|
+
align: "end",
|
|
94
|
+
cell: (row) => (
|
|
95
|
+
<Dropdown.Root>
|
|
96
|
+
<Dropdown.Trigger>
|
|
97
|
+
<Button.Root variant="ghost" tone="neutral" aria-label={`Действия с заказом ${row.id}`}>
|
|
98
|
+
<Button.Icon>
|
|
99
|
+
<Icon name="action.more" />
|
|
100
|
+
</Button.Icon>
|
|
101
|
+
</Button.Root>
|
|
102
|
+
</Dropdown.Trigger>
|
|
103
|
+
<Dropdown.Content>
|
|
104
|
+
<Dropdown.Item>Открыть заказ</Dropdown.Item>
|
|
105
|
+
<Dropdown.Item>Скачать счёт</Dropdown.Item>
|
|
106
|
+
</Dropdown.Content>
|
|
107
|
+
</Dropdown.Root>
|
|
108
|
+
),
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
/** The kit keeps nothing: the app stores the order and the hidden columns where it likes. */
|
|
113
|
+
const STORAGE_KEY = "orders.columns";
|
|
114
|
+
type ColumnView = { order: string[]; hidden: string[] };
|
|
115
|
+
const DEFAULT_VIEW: ColumnView = { order: [], hidden: ["city"] };
|
|
116
|
+
|
|
117
|
+
function readView(): ColumnView {
|
|
118
|
+
try {
|
|
119
|
+
const saved = window.localStorage.getItem(STORAGE_KEY);
|
|
120
|
+
return saved
|
|
121
|
+
? { ...DEFAULT_VIEW, ...(JSON.parse(saved) as Partial<ColumnView>) }
|
|
122
|
+
: DEFAULT_VIEW;
|
|
123
|
+
} catch {
|
|
124
|
+
return DEFAULT_VIEW;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default function DataTableColumnOrderExample() {
|
|
129
|
+
const [view, setView] = React.useState(readView);
|
|
130
|
+
|
|
131
|
+
const changeView = (next: ColumnView) => {
|
|
132
|
+
setView(next);
|
|
133
|
+
try {
|
|
134
|
+
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
135
|
+
} catch {
|
|
136
|
+
// Private mode or a full storage: the choice lasts until the reload.
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<DataTable
|
|
142
|
+
columns={COLUMNS}
|
|
143
|
+
columnOrder={view.order}
|
|
144
|
+
onColumnOrderChange={(order) => changeView({ ...view, order })}
|
|
145
|
+
hiddenColumns={view.hidden}
|
|
146
|
+
onHiddenColumnsChange={(hidden) => changeView({ ...view, hidden })}
|
|
147
|
+
rows={ORDERS}
|
|
148
|
+
getRowKey={(row) => row.id}
|
|
149
|
+
columnsMenu
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** Orders
|
|
2
|
-
import { Badge, DataTable, type DataTableColumn,
|
|
1
|
+
/** Orders without a row-actions column: the column chooser stands in the tools above the table with the count of shown columns; the choice outlives a reload in local storage, the order number always stays — `DataTableColumnsMenu`, `hiddenColumns`, `onHiddenColumnsChange`, `hideable`. */
|
|
2
|
+
import { Badge, DataTable, type DataTableColumn, DataTableColumnsMenu } from "prime-ui-kit";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
import styles from "./examples.module.css";
|
|
@@ -131,21 +131,21 @@ export default function DataTableColumnsVisibilityExample() {
|
|
|
131
131
|
};
|
|
132
132
|
|
|
133
133
|
return (
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
134
|
+
<div className={styles.withTools}>
|
|
135
|
+
<div className={styles.tools}>
|
|
136
|
+
<DataTableColumnsMenu
|
|
137
|
+
columns={COLUMNS}
|
|
138
|
+
hiddenColumns={hidden}
|
|
139
|
+
onHiddenColumnsChange={changeHidden}
|
|
140
|
+
/>
|
|
141
|
+
</div>
|
|
142
|
+
<DataTable
|
|
143
|
+
columns={COLUMNS}
|
|
144
|
+
hiddenColumns={hidden}
|
|
145
|
+
rows={ORDERS}
|
|
146
|
+
getRowKey={(row) => row.id}
|
|
147
|
+
stickyFirstColumn
|
|
148
|
+
/>
|
|
149
|
+
</div>
|
|
150
150
|
);
|
|
151
151
|
}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/** Sort, page and the column choice owned by the parent (a URL or a store): a header click goes asc → desc → none, a new sort returns to page 1 — `sort`, `onSortChange`, `page`, `onPageChange`, `hiddenColumns`, `onHiddenColumnsChange`. */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DataTable,
|
|
4
|
+
type DataTableColumn,
|
|
5
|
+
DataTableColumnsMenu,
|
|
6
|
+
type DataTableSortState,
|
|
7
|
+
} from "prime-ui-kit";
|
|
3
8
|
import * as React from "react";
|
|
4
9
|
|
|
10
|
+
import styles from "./examples.module.css";
|
|
11
|
+
|
|
5
12
|
type Order = { id: number; customer: string; city: string; total: number };
|
|
6
13
|
|
|
7
14
|
const CUSTOMERS = ["Анна Соколова", "Борис Кравец", "Вера Львова", "Глеб Миронов", "Дарья Носова"];
|
|
@@ -48,21 +55,29 @@ export default function DataTableControlledExample() {
|
|
|
48
55
|
const [hiddenColumns, setHiddenColumns] = React.useState<string[]>(["city"]);
|
|
49
56
|
|
|
50
57
|
return (
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
<div className={styles.withTools}>
|
|
59
|
+
<div className={styles.tools}>
|
|
60
|
+
<DataTableColumnsMenu
|
|
61
|
+
columns={COLUMNS}
|
|
62
|
+
hiddenColumns={hiddenColumns}
|
|
63
|
+
onHiddenColumnsChange={setHiddenColumns}
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
<DataTable
|
|
67
|
+
columns={COLUMNS}
|
|
68
|
+
rows={ORDERS}
|
|
69
|
+
getRowKey={(row) => row.id}
|
|
70
|
+
hiddenColumns={hiddenColumns}
|
|
71
|
+
onHiddenColumnsChange={setHiddenColumns}
|
|
72
|
+
sort={sort}
|
|
73
|
+
onSortChange={(next) => {
|
|
74
|
+
setSort(next);
|
|
75
|
+
setPage(1);
|
|
76
|
+
}}
|
|
77
|
+
page={page}
|
|
78
|
+
onPageChange={setPage}
|
|
79
|
+
pageSize={5}
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
67
82
|
);
|
|
68
83
|
}
|
|
@@ -1,41 +1,5 @@
|
|
|
1
1
|
/* Layout of the DataTable scenarios: semantic tokens only. */
|
|
2
2
|
|
|
3
|
-
/* Toolbar content: two groups pushed to the edges; they wrap on narrow widths. */
|
|
4
|
-
.toolbar {
|
|
5
|
-
display: flex;
|
|
6
|
-
flex-wrap: wrap;
|
|
7
|
-
align-items: center;
|
|
8
|
-
justify-content: space-between;
|
|
9
|
-
gap: var(--prime-space-2);
|
|
10
|
-
width: 100%;
|
|
11
|
-
min-width: 0;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/* A SmartFilter in the toolbar: the search and filter row over the applied filters. */
|
|
15
|
-
.filterColumn {
|
|
16
|
-
display: flex;
|
|
17
|
-
flex: 1 1 auto;
|
|
18
|
-
flex-direction: column;
|
|
19
|
-
gap: var(--prime-space-3);
|
|
20
|
-
min-width: 0;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.filters {
|
|
24
|
-
display: flex;
|
|
25
|
-
flex: 1 1 auto;
|
|
26
|
-
flex-wrap: wrap;
|
|
27
|
-
align-items: center;
|
|
28
|
-
gap: var(--prime-space-2);
|
|
29
|
-
min-width: 0;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/* The search grows from 12rem, at most 20rem. */
|
|
33
|
-
.search {
|
|
34
|
-
flex: 1 1 calc(var(--prime-space-24) * 2);
|
|
35
|
-
min-width: 0;
|
|
36
|
-
max-width: calc(var(--prime-space-20) * 4);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
3
|
/* appearance / content-width: a table with its caption under it. */
|
|
40
4
|
.specimen {
|
|
41
5
|
display: flex;
|
|
@@ -73,3 +37,17 @@
|
|
|
73
37
|
min-width: 0;
|
|
74
38
|
margin-inline: auto;
|
|
75
39
|
}
|
|
40
|
+
|
|
41
|
+
/* A table under the tools of its page: the column chooser (`DataTableColumnsMenu`) at the end. */
|
|
42
|
+
.withTools {
|
|
43
|
+
display: grid;
|
|
44
|
+
grid-template-columns: minmax(0, 1fr);
|
|
45
|
+
gap: var(--prime-space-3);
|
|
46
|
+
min-width: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.tools {
|
|
50
|
+
display: flex;
|
|
51
|
+
justify-content: flex-end;
|
|
52
|
+
min-width: 0;
|
|
53
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/** A 320 px support queue: columns scroll inside the table with the first one pinned, the
|
|
2
|
-
import { Badge,
|
|
1
|
+
/** A 320 px support queue: columns scroll inside the table with the first one pinned, the column chooser stays in reach above it, the footer reflows and the pager turns compact — `stickyFirstColumn`, `DataTableColumnsMenu`, `size`. */
|
|
2
|
+
import { Badge, DataTable, type DataTableColumn, DataTableColumnsMenu } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
3
4
|
|
|
4
5
|
import styles from "./examples.module.css";
|
|
5
6
|
|
|
@@ -15,7 +16,7 @@ const TICKETS: Ticket[] = Array.from({ length: 36 }, (_, i) => ({
|
|
|
15
16
|
}));
|
|
16
17
|
|
|
17
18
|
const COLUMNS: DataTableColumn<Ticket>[] = [
|
|
18
|
-
{ id: "id", header: "Тикет", accessor: "id" },
|
|
19
|
+
{ id: "id", header: "Тикет", accessor: "id", hideable: false },
|
|
19
20
|
{ id: "subject", header: "Тема", accessor: "subject", truncate: true, maxWidth: "10rem" },
|
|
20
21
|
{
|
|
21
22
|
id: "priority",
|
|
@@ -31,24 +32,29 @@ const COLUMNS: DataTableColumn<Ticket>[] = [
|
|
|
31
32
|
];
|
|
32
33
|
|
|
33
34
|
export default function DataTableNarrowExample() {
|
|
35
|
+
const [hidden, setHidden] = React.useState<string[]>([]);
|
|
36
|
+
|
|
34
37
|
return (
|
|
35
38
|
<div className={styles.narrow}>
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
<div className={styles.withTools}>
|
|
40
|
+
<div className={styles.tools}>
|
|
41
|
+
<DataTableColumnsMenu
|
|
42
|
+
size="s"
|
|
43
|
+
columns={COLUMNS}
|
|
44
|
+
hiddenColumns={hidden}
|
|
45
|
+
onHiddenColumnsChange={setHidden}
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
<DataTable
|
|
49
|
+
size="s"
|
|
50
|
+
columns={COLUMNS}
|
|
51
|
+
hiddenColumns={hidden}
|
|
52
|
+
rows={TICKETS}
|
|
53
|
+
getRowKey={(row) => row.id}
|
|
54
|
+
stickyFirstColumn
|
|
55
|
+
pageSize={5}
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
52
58
|
</div>
|
|
53
59
|
);
|
|
54
60
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
/** Pipeline stages put in order by the
|
|
2
|
-
import { Badge, DataTable, type DataTableColumn, moveBefore } from "prime-ui-kit";
|
|
1
|
+
/** Pipeline stages put in order by a grip at the end of the row, at its start or by the whole row, or with Alt + ↑ / ↓; each move is saved with a spinner in its grip, and sorting by a column turns reordering off — `onReorder`, `reorderHandle`, `getRowLabel`. */
|
|
2
|
+
import { Badge, DataTable, type DataTableColumn, moveBefore, SegmentedControl } from "prime-ui-kit";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
type Stage = { id: string; name: string; owner: string; deals: number; probability: number };
|
|
6
|
+
type Handle = "end" | "start" | "row";
|
|
6
7
|
|
|
7
8
|
const STAGES: Stage[] = [
|
|
8
9
|
{ id: "lead", name: "Новый лид", owner: "Отдел продаж", deals: 48, probability: 10 },
|
|
@@ -19,6 +20,12 @@ const STAGES: Stage[] = [
|
|
|
19
20
|
{ id: "payment", name: "Оплата", owner: "Бухгалтерия", deals: 4, probability: 95 },
|
|
20
21
|
];
|
|
21
22
|
|
|
23
|
+
const HANDLES: { value: Handle; label: string }[] = [
|
|
24
|
+
{ value: "end", label: "Ручка в конце" },
|
|
25
|
+
{ value: "start", label: "Ручка в начале" },
|
|
26
|
+
{ value: "row", label: "Вся строка" },
|
|
27
|
+
];
|
|
28
|
+
|
|
22
29
|
const COLUMNS: DataTableColumn<Stage>[] = [
|
|
23
30
|
{ id: "name", header: "Этап", accessor: "name", hideable: false },
|
|
24
31
|
{ id: "owner", header: "Ответственный", accessor: "owner" },
|
|
@@ -38,6 +45,7 @@ const saveOrder = () => new Promise<void>((resolve) => setTimeout(resolve, 700))
|
|
|
38
45
|
|
|
39
46
|
export default function DataTableReorderExample() {
|
|
40
47
|
const [stages, setStages] = React.useState(STAGES);
|
|
48
|
+
const [handle, setHandle] = React.useState<Handle>("end");
|
|
41
49
|
return (
|
|
42
50
|
<DataTable
|
|
43
51
|
columns={COLUMNS}
|
|
@@ -45,6 +53,20 @@ export default function DataTableReorderExample() {
|
|
|
45
53
|
paging="none"
|
|
46
54
|
getRowKey={(row) => row.id}
|
|
47
55
|
getRowLabel={(row) => row.name}
|
|
56
|
+
reorderHandle={handle}
|
|
57
|
+
toolbar={
|
|
58
|
+
<SegmentedControl.Root
|
|
59
|
+
value={handle}
|
|
60
|
+
onValueChange={(next) => setHandle(next as Handle)}
|
|
61
|
+
aria-label="За что брать строку"
|
|
62
|
+
>
|
|
63
|
+
{HANDLES.map((item) => (
|
|
64
|
+
<SegmentedControl.Item key={item.value} value={item.value}>
|
|
65
|
+
{item.label}
|
|
66
|
+
</SegmentedControl.Item>
|
|
67
|
+
))}
|
|
68
|
+
</SegmentedControl.Root>
|
|
69
|
+
}
|
|
48
70
|
onReorder={async (id, beforeId) => {
|
|
49
71
|
await saveOrder();
|
|
50
72
|
setStages((current) =>
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
import { Button, DataTable, type DataTableColumn, Dropdown, Icon, Typography } from "prime-ui-kit";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
|
-
import styles from "./examples.module.css";
|
|
6
|
-
|
|
7
5
|
type Invoice = { id: string; client: string; due: string; amount: number; total?: boolean };
|
|
8
6
|
|
|
9
7
|
const INVOICES: Invoice[] = [
|
|
@@ -77,25 +75,23 @@ export default function DataTableRowLinkExample() {
|
|
|
77
75
|
];
|
|
78
76
|
|
|
79
77
|
return (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
/>
|
|
78
|
+
<>
|
|
79
|
+
<DataTable
|
|
80
|
+
columns={columns}
|
|
81
|
+
rows={ROWS}
|
|
82
|
+
getRowKey={(row) => row.id}
|
|
83
|
+
paging="none"
|
|
84
|
+
getRowHref={(row) => `/invoices/${row.id}`}
|
|
85
|
+
isRowClickable={(row) => !row.total}
|
|
86
|
+
onRowClick={(row, _index, event) => {
|
|
87
|
+
// A client-side router goes here (navigate(href)); the page itself never reloads.
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
setStatus(`Открыт ${row.id} · ${row.client}`);
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
<Typography as="span" variant="body-s" tone="secondary" aria-live="polite">
|
|
93
|
+
{status}
|
|
94
|
+
</Typography>
|
|
95
|
+
</>
|
|
100
96
|
);
|
|
101
97
|
}
|
|
@@ -177,7 +177,15 @@ const initials = (name: string) =>
|
|
|
177
177
|
.toUpperCase();
|
|
178
178
|
|
|
179
179
|
const COLUMNS: DataTableColumn<Invoice>[] = [
|
|
180
|
-
{
|
|
180
|
+
{
|
|
181
|
+
id: "id",
|
|
182
|
+
header: "Счёт",
|
|
183
|
+
accessor: "id",
|
|
184
|
+
sortable: true,
|
|
185
|
+
numeric: true,
|
|
186
|
+
align: "start",
|
|
187
|
+
hideable: false,
|
|
188
|
+
},
|
|
181
189
|
{
|
|
182
190
|
id: "client",
|
|
183
191
|
header: "Клиент",
|
|
@@ -230,6 +238,7 @@ const COLUMNS: DataTableColumn<Invoice>[] = [
|
|
|
230
238
|
id: "actions",
|
|
231
239
|
header: "Действия",
|
|
232
240
|
hideHeader: true,
|
|
241
|
+
hideable: false,
|
|
233
242
|
width: "3.5rem",
|
|
234
243
|
align: "end",
|
|
235
244
|
cell: (row) => (
|
|
@@ -320,6 +329,8 @@ export default function DataTableScreenExample() {
|
|
|
320
329
|
getRowLabel={(row) => `Счёт ${row.id}`}
|
|
321
330
|
pageSize={6}
|
|
322
331
|
stickyFirstColumn
|
|
332
|
+
stickyLastColumn
|
|
333
|
+
columnsMenu
|
|
323
334
|
defaultSort={{ columnId: "due", order: "desc" }}
|
|
324
335
|
empty={
|
|
325
336
|
<EmptyPage.Root size="s" role="status" aria-labelledby="invoices-empty">
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
import { Button, DataTable, type DataTableColumn, Typography } from "prime-ui-kit";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
|
-
import styles from "./examples.module.css";
|
|
6
|
-
|
|
7
5
|
type Member = { id: string; name: string; email: string; role: string };
|
|
8
6
|
|
|
9
7
|
const MEMBERS: Member[] = [
|
|
@@ -35,25 +33,22 @@ export default function DataTableSelectionExample() {
|
|
|
35
33
|
onSelectedChange={setSelected}
|
|
36
34
|
paging="none"
|
|
37
35
|
toolbar={
|
|
38
|
-
|
|
36
|
+
<>
|
|
39
37
|
<Typography as="span" variant="body-s" tone="secondary">
|
|
40
38
|
Выбрано: {selected.length} из {MEMBERS.length}
|
|
41
39
|
</Typography>
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
</Button.Root>
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
40
|
+
<Button.Root
|
|
41
|
+
variant="outline"
|
|
42
|
+
tone="neutral"
|
|
43
|
+
disabled={selected.length === 0}
|
|
44
|
+
onClick={() => setSelected([])}
|
|
45
|
+
>
|
|
46
|
+
Снять выбор
|
|
47
|
+
</Button.Root>
|
|
48
|
+
<Button.Root variant="soft" tone="danger" disabled={selected.length === 0}>
|
|
49
|
+
Удалить
|
|
50
|
+
</Button.Root>
|
|
51
|
+
</>
|
|
57
52
|
}
|
|
58
53
|
/>
|
|
59
54
|
);
|