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.
Files changed (145) hide show
  1. package/README.md +1 -1
  2. package/dist/chunks/{chunk-OAXJWF3L.js → chunk-3PY52JP3.js} +1764 -1764
  3. package/dist/chunks/{chunk-X3JT5CLR.js → chunk-4KONMO7Z.js} +1 -1
  4. package/dist/chunks/{chunk-MB4CXSLL.js → chunk-W6EGTNG6.js} +3772 -2888
  5. package/dist/color-picker.js +2 -2
  6. package/dist/components/data-table/ColumnsMenu.d.ts +39 -17
  7. package/dist/components/data-table/DataTable.d.ts +41 -12
  8. package/dist/components/data-table/DataTableColumnsMenu.d.ts +45 -0
  9. package/dist/components/data-table/Head.d.ts +18 -5
  10. package/dist/components/data-table/Row.d.ts +10 -4
  11. package/dist/components/data-table/StateRows.d.ts +5 -3
  12. package/dist/components/data-table/columnOrder.d.ts +14 -0
  13. package/dist/components/data-table/reorder.d.ts +15 -5
  14. package/dist/components/data-table/types.d.ts +5 -0
  15. package/dist/components/data-table/useFrozenColumns.d.ts +6 -2
  16. package/dist/components/datepicker/DatepickerPanel.d.ts +1 -1
  17. package/dist/components/dnd/Dnd.d.ts +9 -5
  18. package/dist/components/dnd/inPlaceRow.d.ts +7 -0
  19. package/dist/components/dnd/useDragSource.d.ts +2 -0
  20. package/dist/components/dnd/useSortableList.d.ts +5 -0
  21. package/dist/components/field-list/FieldList.d.ts +37 -15
  22. package/dist/components/gantt/Gantt.d.ts +1 -1
  23. package/dist/components/index.d.ts +3 -1
  24. package/dist/components/kanban/Kanban.d.ts +4 -0
  25. package/dist/components/list/List.d.ts +9 -4
  26. package/dist/components/scroll-container/ScrollContainer.d.ts +1 -1
  27. package/dist/index.css +1 -1
  28. package/dist/index.js +4 -2
  29. package/dist/internal/ToolRow.d.ts +23 -0
  30. package/dist/internal/leaveGuard.d.ts +6 -0
  31. package/dist/internal/overlay/DialogGuard.d.ts +3 -2
  32. package/dist/internal/overlay/DialogParts.d.ts +14 -5
  33. package/dist/layout/index.d.ts +1 -1
  34. package/dist/layout/page/Page.d.ts +8 -14
  35. package/dist/skill/anti-slop.md +55 -1
  36. package/dist/skill/api-contract.md +2 -2
  37. package/dist/skill/cheatsheet.md +12 -4
  38. package/dist/skill/checklist.md +7 -0
  39. package/dist/skill/choosing.md +1 -0
  40. package/dist/skill/components.md +1 -1
  41. package/dist/skill/composition.md +196 -21
  42. package/dist/skill/layouts.md +1 -1
  43. package/dist/skill/reference/components/confirm-dialog/COMPONENT.md +1 -1
  44. package/dist/skill/reference/components/data-table/COMPONENT.md +110 -49
  45. package/dist/skill/reference/components/data-table/examples/actions-column.tsx +154 -0
  46. package/dist/skill/reference/components/data-table/examples/column-order.tsx +152 -0
  47. package/dist/skill/reference/components/data-table/examples/columns-visibility.tsx +18 -18
  48. package/dist/skill/reference/components/data-table/examples/controlled.tsx +32 -17
  49. package/dist/skill/reference/components/data-table/examples/examples.module.css +14 -36
  50. package/dist/skill/reference/components/data-table/examples/narrow.tsx +25 -19
  51. package/dist/skill/reference/components/data-table/examples/reorder.tsx +24 -2
  52. package/dist/skill/reference/components/data-table/examples/row-link.tsx +18 -22
  53. package/dist/skill/reference/components/data-table/examples/screen.tsx +12 -1
  54. package/dist/skill/reference/components/data-table/examples/selection.tsx +13 -18
  55. package/dist/skill/reference/components/data-table/examples/server.tsx +45 -31
  56. package/dist/skill/reference/components/data-table/examples/toolbar.tsx +22 -35
  57. package/dist/skill/reference/components/datepicker/COMPONENT.md +2 -2
  58. package/dist/skill/reference/components/dnd/COMPONENT.md +13 -7
  59. package/dist/skill/reference/components/dnd/examples/examples.module.css +4 -3
  60. package/dist/skill/reference/components/dnd/examples/handle.tsx +5 -5
  61. package/dist/skill/reference/components/dnd/examples/locked.tsx +1 -1
  62. package/dist/skill/reference/components/dnd/examples/table-columns.tsx +75 -0
  63. package/dist/skill/reference/components/dnd/examples/table.tsx +6 -6
  64. package/dist/skill/reference/components/drawer/COMPONENT.md +26 -10
  65. package/dist/skill/reference/components/drawer/examples/header-actions.tsx +1 -1
  66. package/dist/skill/reference/components/drawer/examples/loading.tsx +58 -0
  67. package/dist/skill/reference/components/field-list/COMPONENT.md +78 -47
  68. package/dist/skill/reference/components/field-list/examples/base-row.tsx +2 -1
  69. package/dist/skill/reference/components/field-list/examples/locked.tsx +11 -11
  70. package/dist/skill/reference/components/field-list/examples/narrow.tsx +108 -33
  71. package/dist/skill/reference/components/field-list/examples/reorder.tsx +1 -1
  72. package/dist/skill/reference/components/field-list/examples/row-menu.tsx +71 -0
  73. package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
  74. package/dist/skill/reference/components/field-list/examples/screen.tsx +169 -162
  75. package/dist/skill/reference/components/field-list/examples/totals.tsx +9 -8
  76. package/dist/skill/reference/components/field-list/examples/variants.tsx +51 -0
  77. package/dist/skill/reference/components/gantt/COMPONENT.md +4 -4
  78. package/dist/skill/reference/components/kanban/COMPONENT.md +6 -2
  79. package/dist/skill/reference/components/kanban/examples/states.tsx +7 -5
  80. package/dist/skill/reference/components/list/COMPONENT.md +21 -11
  81. package/dist/skill/reference/components/list/examples/reorder.tsx +42 -7
  82. package/dist/skill/reference/components/modal/COMPONENT.md +23 -10
  83. package/dist/skill/reference/components/scroll-container/COMPONENT.md +1 -1
  84. package/dist/skill/reference/components/segmented-control/COMPONENT.md +3 -2
  85. package/dist/skill/reference/components/sheet/COMPONENT.md +18 -7
  86. package/dist/skill/reference/components/smart-filter/COMPONENT.md +2 -2
  87. package/dist/skill/reference/layout/page/COMPONENT.md +13 -17
  88. package/dist/skill/reference/layout/page/examples/screen.module.css +1 -1
  89. package/dist/skill/reference/layout/page/examples/screen.tsx +93 -104
  90. package/dist/skill/reference/layout/page/examples/sections.tsx +2 -15
  91. package/dist/skill/responsive.md +14 -10
  92. package/dist/tokens/semantic.d.ts +2 -2
  93. package/dist/tokens/themes/dark.d.ts +1 -1
  94. package/package.json +1 -1
  95. package/src/components/confirm-dialog/COMPONENT.md +1 -1
  96. package/src/components/data-table/COMPONENT.md +110 -49
  97. package/src/components/data-table/examples/actions-column.tsx +154 -0
  98. package/src/components/data-table/examples/column-order.tsx +152 -0
  99. package/src/components/data-table/examples/columns-visibility.tsx +18 -18
  100. package/src/components/data-table/examples/controlled.tsx +32 -17
  101. package/src/components/data-table/examples/examples.module.css +14 -36
  102. package/src/components/data-table/examples/narrow.tsx +25 -19
  103. package/src/components/data-table/examples/reorder.tsx +24 -2
  104. package/src/components/data-table/examples/row-link.tsx +18 -22
  105. package/src/components/data-table/examples/screen.tsx +12 -1
  106. package/src/components/data-table/examples/selection.tsx +13 -18
  107. package/src/components/data-table/examples/server.tsx +45 -31
  108. package/src/components/data-table/examples/toolbar.tsx +22 -35
  109. package/src/components/datepicker/COMPONENT.md +2 -2
  110. package/src/components/dnd/COMPONENT.md +13 -7
  111. package/src/components/dnd/examples/examples.module.css +4 -3
  112. package/src/components/dnd/examples/handle.tsx +5 -5
  113. package/src/components/dnd/examples/locked.tsx +1 -1
  114. package/src/components/dnd/examples/table-columns.tsx +75 -0
  115. package/src/components/dnd/examples/table.tsx +6 -6
  116. package/src/components/drawer/COMPONENT.md +26 -10
  117. package/src/components/drawer/examples/header-actions.tsx +1 -1
  118. package/src/components/drawer/examples/loading.tsx +58 -0
  119. package/src/components/field-list/COMPONENT.md +78 -47
  120. package/src/components/field-list/examples/base-row.tsx +2 -1
  121. package/src/components/field-list/examples/locked.tsx +11 -11
  122. package/src/components/field-list/examples/narrow.tsx +108 -33
  123. package/src/components/field-list/examples/reorder.tsx +1 -1
  124. package/src/components/field-list/examples/row-menu.tsx +71 -0
  125. package/src/components/field-list/examples/screen.module.css +1 -1
  126. package/src/components/field-list/examples/screen.tsx +169 -162
  127. package/src/components/field-list/examples/totals.tsx +9 -8
  128. package/src/components/field-list/examples/variants.tsx +51 -0
  129. package/src/components/gantt/COMPONENT.md +4 -4
  130. package/src/components/kanban/COMPONENT.md +6 -2
  131. package/src/components/kanban/examples/states.tsx +7 -5
  132. package/src/components/list/COMPONENT.md +21 -11
  133. package/src/components/list/examples/reorder.tsx +42 -7
  134. package/src/components/modal/COMPONENT.md +23 -10
  135. package/src/components/scroll-container/COMPONENT.md +1 -1
  136. package/src/components/segmented-control/COMPONENT.md +3 -2
  137. package/src/components/sheet/COMPONENT.md +18 -7
  138. package/src/components/smart-filter/COMPONENT.md +2 -2
  139. package/src/layout/page/COMPONENT.md +13 -17
  140. package/src/layout/page/examples/screen.module.css +1 -1
  141. package/src/layout/page/examples/screen.tsx +93 -104
  142. package/src/layout/page/examples/sections.tsx +2 -15
  143. package/src/styles/theme-dark.css +1 -1
  144. package/src/styles/theme-light.css +1 -1
  145. 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 with the column chooser in the toolbar; the choice outlives a reload in local storage, the order number always stays — `DataTable.ColumnsMenu`, `hiddenColumns`, `onHiddenColumnsChange`, `hideable`. */
2
- import { Badge, DataTable, type DataTableColumn, Typography } from "prime-ui-kit";
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
- <DataTable
135
- columns={COLUMNS}
136
- hiddenColumns={hidden}
137
- onHiddenColumnsChange={changeHidden}
138
- rows={ORDERS}
139
- getRowKey={(row) => row.id}
140
- stickyFirstColumn
141
- toolbar={
142
- <div className={styles.toolbar}>
143
- <Typography as="span" variant="body-s" tone="secondary">
144
- Заказы за неделю: {ORDERS.length}
145
- </Typography>
146
- <DataTable.ColumnsMenu />
147
- </div>
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 { DataTable, type DataTableColumn, type DataTableSortState } from "prime-ui-kit";
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
- <DataTable
52
- columns={COLUMNS}
53
- rows={ORDERS}
54
- getRowKey={(row) => row.id}
55
- toolbar={<DataTable.ColumnsMenu />}
56
- hiddenColumns={hiddenColumns}
57
- onHiddenColumnsChange={setHiddenColumns}
58
- sort={sort}
59
- onSortChange={(next) => {
60
- setSort(next);
61
- setPage(1);
62
- }}
63
- page={page}
64
- onPageChange={setPage}
65
- pageSize={5}
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 toolbar and footer reflow and the pager turns compact — `stickyFirstColumn`, `size`. */
2
- import { Badge, Button, DataTable, type DataTableColumn, Typography } from "prime-ui-kit";
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
- <DataTable
37
- size="s"
38
- columns={COLUMNS}
39
- rows={TICKETS}
40
- getRowKey={(row) => row.id}
41
- stickyFirstColumn
42
- pageSize={5}
43
- toolbar={
44
- <div className={styles.toolbar}>
45
- <Typography as="span" variant="body-s" tone="secondary">
46
- Открытые: {TICKETS.length}
47
- </Typography>
48
- <Button.Root size="xs">Новый тикет</Button.Root>
49
- </div>
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 handle or Alt + ↑ / ↓; each move is saved with a spinner in its handle, and sorting by a column turns the handles off — `onReorder`, `getRowLabel`. */
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
- <DataTable
81
- columns={columns}
82
- rows={ROWS}
83
- getRowKey={(row) => row.id}
84
- paging="none"
85
- getRowHref={(row) => `/invoices/${row.id}`}
86
- isRowClickable={(row) => !row.total}
87
- onRowClick={(row, _index, event) => {
88
- // A client-side router goes here (navigate(href)); the page itself never reloads.
89
- event.preventDefault();
90
- setStatus(`Открыт ${row.id} · ${row.client}`);
91
- }}
92
- toolbar={
93
- <div className={styles.toolbar}>
94
- <Typography as="span" variant="body-s" tone="secondary" aria-live="polite">
95
- {status}
96
- </Typography>
97
- </div>
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
- { id: "id", header: "Счёт", accessor: "id", sortable: true, numeric: true, align: "start" },
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
- <div className={styles.toolbar}>
36
+ <>
39
37
  <Typography as="span" variant="body-s" tone="secondary">
40
38
  Выбрано: {selected.length} из {MEMBERS.length}
41
39
  </Typography>
42
- <div className={styles.filters}>
43
- <Button.Root
44
- variant="outline"
45
- tone="neutral"
46
- size="s"
47
- disabled={selected.length === 0}
48
- onClick={() => setSelected([])}
49
- >
50
- Снять выбор
51
- </Button.Root>
52
- <Button.Root variant="soft" tone="danger" size="s" disabled={selected.length === 0}>
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
  );