velocis 1.0.0 → 1.1.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/AGENTS.md +29 -0
- package/README.md +33 -0
- package/dist/card.d.cts +3 -0
- package/dist/card.d.ts +3 -0
- package/dist/dialog1.cjs +24 -0
- package/dist/dialog1.d.cts +1 -0
- package/dist/dialog1.d.ts +1 -0
- package/dist/dialog1.js +2 -0
- package/dist/dropdown1.cjs +24 -0
- package/dist/dropdown1.d.cts +1 -0
- package/dist/dropdown1.d.ts +1 -0
- package/dist/dropdown1.js +2 -0
- package/dist/table2.cjs +24 -0
- package/dist/table2.d.cts +1 -0
- package/dist/table2.d.ts +1 -0
- package/dist/table2.js +2 -0
- package/dist/tailwind-v4.css +37 -0
- package/docs/README.md +89 -0
- package/docs/card.md +77 -0
- package/docs/core.md +75 -0
- package/docs/dialog1.md +180 -0
- package/docs/dropdown1.md +154 -0
- package/docs/feedback.md +90 -0
- package/docs/forms.md +78 -0
- package/docs/hero.md +84 -0
- package/docs/list.md +73 -0
- package/docs/navigation.md +102 -0
- package/docs/table.md +111 -0
- package/docs/table2.md +265 -0
- package/docs/theme.md +66 -0
- package/package.json +36 -9
package/docs/table2.md
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Table2 (`velocis/table2`)
|
|
2
|
+
|
|
3
|
+
Highly flexible data tables with render-prop columns, optional row selection, client-side pagination hooks, and full styling control at every layer.
|
|
4
|
+
|
|
5
|
+
Use **Table2** when you need a custom UI table (card rows, bespoke cells, selection column). Use [`velocis/table`](./table.md) when you need sorting, filtering, virtualization, or tree data via the table engine.
|
|
6
|
+
|
|
7
|
+
## Import
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
'use client';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
Table2,
|
|
14
|
+
useTable2Pagination,
|
|
15
|
+
useTable2Selection,
|
|
16
|
+
cardRowStyles,
|
|
17
|
+
} from 'velocis/table2';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## When to use
|
|
21
|
+
|
|
22
|
+
| Scenario | Use |
|
|
23
|
+
|----------|-----|
|
|
24
|
+
| Custom cell renderers per column | `Table2` with `columns[].cell` |
|
|
25
|
+
| Card-style separated rows | `appearance="card"` or `cardRowStyles` |
|
|
26
|
+
| Bulk row selection | `useTable2Selection` + `selection` prop |
|
|
27
|
+
| Client-side paging | `useTable2Pagination` |
|
|
28
|
+
| Server-side paging | Pass your own `pagination` prop |
|
|
29
|
+
| Sort / filter / virtual scroll | [`velocis/table`](./table.md) instead |
|
|
30
|
+
|
|
31
|
+
## Basic usage
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
type Customer = { id: string; name: string; phone: string };
|
|
35
|
+
|
|
36
|
+
const columns = [
|
|
37
|
+
{
|
|
38
|
+
id: 'name',
|
|
39
|
+
header: 'Name',
|
|
40
|
+
cell: (row: Customer) => <span className="font-medium">{row.name}</span>,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'phone',
|
|
44
|
+
header: 'Phone',
|
|
45
|
+
cell: (row: Customer) => row.phone || '—',
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
<Table2 rows={customers} columns={columns} />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Compound API (`Table2`)
|
|
53
|
+
|
|
54
|
+
| Property | Component | Use when |
|
|
55
|
+
|----------|-----------|----------|
|
|
56
|
+
| `Table2` | `Table2Root` | Main table |
|
|
57
|
+
| `Table2.Pagination` | `Table2Pagination` | Standalone pagination bar |
|
|
58
|
+
| `Table2.Checkbox` | `Table2Checkbox` | Custom selection UI |
|
|
59
|
+
|
|
60
|
+
## Column definition
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
const columns: Table2Column<Customer>[] = [
|
|
64
|
+
{
|
|
65
|
+
id: 'name',
|
|
66
|
+
header: 'Customer',
|
|
67
|
+
headClassName: 'bg-velocis-background',
|
|
68
|
+
cellClassName: 'max-w-[200px]',
|
|
69
|
+
hidden: false,
|
|
70
|
+
cell: (row) => row.name,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| Field | Type | Description |
|
|
76
|
+
|-------|------|-------------|
|
|
77
|
+
| `id` | `string` | Unique column id |
|
|
78
|
+
| `header` | `ReactNode` | Header content |
|
|
79
|
+
| `cell` | `(row) => ReactNode` | Cell renderer |
|
|
80
|
+
| `headClassName` | `string` | Header cell classes |
|
|
81
|
+
| `cellClassName` | `string` | Body cell classes |
|
|
82
|
+
| `hidden` | `boolean` | Hide column |
|
|
83
|
+
|
|
84
|
+
## Selection
|
|
85
|
+
|
|
86
|
+
Pass a `selection` object or use `useTable2Selection` for a ready-made config:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
const { pageRows, page, totalPages, nextPage, prevPage } = useTable2Pagination({
|
|
90
|
+
rows: customers,
|
|
91
|
+
pageSize: 10,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const { selectionColumn, selectedIds } = useTable2Selection({
|
|
95
|
+
pageIds: pageRows.map((c) => c.id),
|
|
96
|
+
getRowId: (c) => c.id,
|
|
97
|
+
// controlled (optional):
|
|
98
|
+
// selectedIds,
|
|
99
|
+
// onSelectedIdsChange: setSelectedIds,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
<Table2
|
|
103
|
+
rows={pageRows}
|
|
104
|
+
columns={columns}
|
|
105
|
+
selection={selectionColumn}
|
|
106
|
+
pagination={{
|
|
107
|
+
currentPage: page,
|
|
108
|
+
totalPages,
|
|
109
|
+
onNext: nextPage,
|
|
110
|
+
onPrev: prevPage,
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`useTable2Selection` returns:
|
|
116
|
+
|
|
117
|
+
| Field | Description |
|
|
118
|
+
|-------|-------------|
|
|
119
|
+
| `selectedIds` | Currently selected row ids |
|
|
120
|
+
| `setSelectedIds` | Update selection (supports updater fn) |
|
|
121
|
+
| `toggleOne` | Toggle a single id |
|
|
122
|
+
| `togglePage` | Select/deselect all rows on current page |
|
|
123
|
+
| `isPageAllSelected` | All page rows selected |
|
|
124
|
+
| `isPageSomeSelected` | Partial page selection (indeterminate header) |
|
|
125
|
+
| `selectionColumn` | Ready to pass as `Table2.selection` |
|
|
126
|
+
|
|
127
|
+
## Pagination
|
|
128
|
+
|
|
129
|
+
Built-in pagination renders when `pagination.totalPages > 1`:
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<Table2
|
|
133
|
+
rows={pageRows}
|
|
134
|
+
columns={columns}
|
|
135
|
+
pagination={{
|
|
136
|
+
currentPage: page,
|
|
137
|
+
totalPages,
|
|
138
|
+
onNext: nextPage,
|
|
139
|
+
onPrev: prevPage,
|
|
140
|
+
labelRenderer: ({ currentPage, totalPages }) => (
|
|
141
|
+
<span>Page {currentPage} of {totalPages}</span>
|
|
142
|
+
),
|
|
143
|
+
prevLabel: 'Previous',
|
|
144
|
+
nextLabel: 'Next',
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- `pagination={false}` — hide pagination
|
|
150
|
+
- `pagination={<CustomPager />}` — fully custom footer
|
|
151
|
+
|
|
152
|
+
## Card appearance
|
|
153
|
+
|
|
154
|
+
`appearance="card"` applies the card-row preset (borders on `<td>`, separated rows):
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
<Table2 rows={rows} columns={columns} appearance="card" />
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Or use `cardRowStyles` manually for finer control:
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { cardRowStyles } from 'velocis/table2';
|
|
164
|
+
|
|
165
|
+
<Table2
|
|
166
|
+
rows={rows}
|
|
167
|
+
columns={columns}
|
|
168
|
+
tableClassName={cardRowStyles.tableClassName}
|
|
169
|
+
cellClassName={cardRowStyles.cellClassName}
|
|
170
|
+
rowClassName={cardRowStyles.rowClassName}
|
|
171
|
+
/>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Full example (customers-style)
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
'use client';
|
|
178
|
+
|
|
179
|
+
import { Table2, useTable2Pagination, useTable2Selection } from 'velocis/table2';
|
|
180
|
+
import type { Table2Column } from 'velocis/table2';
|
|
181
|
+
|
|
182
|
+
type Row = { id: string; name: string; email: string; status: string };
|
|
183
|
+
|
|
184
|
+
const data: Row[] = [/* ... */];
|
|
185
|
+
|
|
186
|
+
const columns: Table2Column<Row>[] = [
|
|
187
|
+
{ id: 'name', header: 'Name', cell: (r) => r.name },
|
|
188
|
+
{ id: 'email', header: 'Email', cell: (r) => r.email },
|
|
189
|
+
{
|
|
190
|
+
id: 'status',
|
|
191
|
+
header: 'Status',
|
|
192
|
+
cell: (r) => (
|
|
193
|
+
<span className="rounded-full bg-velocis-border/40 px-3 py-1 text-xs">
|
|
194
|
+
{r.status}
|
|
195
|
+
</span>
|
|
196
|
+
),
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
|
|
200
|
+
export function CustomersTable() {
|
|
201
|
+
const { pageRows, page, totalPages, nextPage, prevPage } = useTable2Pagination({
|
|
202
|
+
rows: data,
|
|
203
|
+
pageSize: 10,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const { selectionColumn } = useTable2Selection({
|
|
207
|
+
pageIds: pageRows.map((r) => r.id),
|
|
208
|
+
getRowId: (r) => r.id,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<div className="overflow-x-auto rounded-3xl bg-velocis-background px-5">
|
|
213
|
+
<Table2
|
|
214
|
+
rows={pageRows}
|
|
215
|
+
columns={columns}
|
|
216
|
+
appearance="card"
|
|
217
|
+
selection={selectionColumn}
|
|
218
|
+
getRowProps={(row) => ({
|
|
219
|
+
className: 'shadow-sm hover:shadow-md',
|
|
220
|
+
key: row.id,
|
|
221
|
+
})}
|
|
222
|
+
pagination={{
|
|
223
|
+
currentPage: page,
|
|
224
|
+
totalPages,
|
|
225
|
+
onNext: nextPage,
|
|
226
|
+
onPrev: prevPage,
|
|
227
|
+
}}
|
|
228
|
+
/>
|
|
229
|
+
</div>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Styling props
|
|
235
|
+
|
|
236
|
+
| Prop | Applied to |
|
|
237
|
+
|------|------------|
|
|
238
|
+
| `containerClassName` | Outer wrapper |
|
|
239
|
+
| `tableClassName` | `<table>` |
|
|
240
|
+
| `headerClassName` | `<thead>` |
|
|
241
|
+
| `headerRowClassName` | Header `<tr>` |
|
|
242
|
+
| `bodyClassName` | `<tbody>` |
|
|
243
|
+
| `rowClassName` | Each data `<tr>` |
|
|
244
|
+
| `cellClassName` | All body cells |
|
|
245
|
+
| `getRowProps` | Per-row `<tr>` props (merge className) |
|
|
246
|
+
| `toolbar` | Slot above table |
|
|
247
|
+
| `footer` | Slot below table (above pagination) |
|
|
248
|
+
| `emptyState` | Shown when `rows` is empty |
|
|
249
|
+
| `dir` | Override text direction (`rtl` / `ltr`; defaults from `DirectionProvider`) |
|
|
250
|
+
|
|
251
|
+
## Primitives
|
|
252
|
+
|
|
253
|
+
Low-level table elements are exported for fully custom layouts:
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from 'velocis/table2';
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## vs `velocis/table`
|
|
260
|
+
|
|
261
|
+
| | `velocis/table` | `velocis/table2` |
|
|
262
|
+
|--|-----------------|------------------|
|
|
263
|
+
| Columns | `accessor` + optional `sortable` | `cell: (row) => ReactNode` |
|
|
264
|
+
| State | `useTableEngine`, URL sync, persistence | `useTable2Pagination`, `useTable2Selection` |
|
|
265
|
+
| Best for | Data grids, trees, virtualization | Custom UI tables, card rows, bulk actions |
|
package/docs/theme.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Theme (`velocis/theme`)
|
|
2
|
+
|
|
3
|
+
Design tokens, i18n messages, and global providers.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
VelocisProvider,
|
|
10
|
+
DirectionProvider,
|
|
11
|
+
useTheme,
|
|
12
|
+
useMessages,
|
|
13
|
+
defaultMessages,
|
|
14
|
+
} from 'velocis/theme';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Components
|
|
18
|
+
|
|
19
|
+
### `VelocisProvider`
|
|
20
|
+
|
|
21
|
+
Wraps the app. Handles light/dark/system theme, optional persistence, and error logging.
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
<VelocisProvider theme="system" persistTheme storageKey="velocis-theme">
|
|
25
|
+
{children}
|
|
26
|
+
</VelocisProvider>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Default | Description |
|
|
30
|
+
|------|------|---------|-------------|
|
|
31
|
+
| `theme` | `'light' \| 'dark' \| 'system'` | `'system'` | Color scheme |
|
|
32
|
+
| `messages` | `Partial<VelocisMessages>` | — | Override built-in strings |
|
|
33
|
+
| `persistTheme` | `boolean` | `true` | Save theme to localStorage |
|
|
34
|
+
| `storageKey` | `string` | `'velocis-theme'` | localStorage key |
|
|
35
|
+
| `onError` | `Logger['error']` | — | Custom error handler |
|
|
36
|
+
|
|
37
|
+
### `DirectionProvider`
|
|
38
|
+
|
|
39
|
+
Sets document direction for RTL/LTR layouts.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<DirectionProvider direction="rtl">{children}</DirectionProvider>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default |
|
|
46
|
+
|------|------|---------|
|
|
47
|
+
| `direction` | `'ltr' \| 'rtl'` | `'ltr'` |
|
|
48
|
+
|
|
49
|
+
## Hooks
|
|
50
|
+
|
|
51
|
+
| Hook | Returns |
|
|
52
|
+
|------|---------|
|
|
53
|
+
| `useTheme()` | `{ theme, resolvedTheme, setTheme }` |
|
|
54
|
+
| `useMessages()` | Merged `VelocisMessages` object |
|
|
55
|
+
|
|
56
|
+
## Design tokens
|
|
57
|
+
|
|
58
|
+
Re-exported from `velocis/theme`:
|
|
59
|
+
|
|
60
|
+
`colors`, `spacing`, `radius`, `typography`, `shadows`, `zIndex`, `animation`, `breakpoints`, `opacity`, `borders`, `gradients`, `iconSizes`
|
|
61
|
+
|
|
62
|
+
## When to use
|
|
63
|
+
|
|
64
|
+
- **Always** wrap your app with `VelocisProvider` + `DirectionProvider` before using any Velocis component.
|
|
65
|
+
- Use `direction="rtl"` for Arabic, Hebrew, etc.
|
|
66
|
+
- Use `theme="system"` for automatic dark mode.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "velocis",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Extremely dynamic RTL/LTR React UI component library",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,6 +36,21 @@
|
|
|
36
36
|
"import": "./dist/table.js",
|
|
37
37
|
"require": "./dist/table.cjs"
|
|
38
38
|
},
|
|
39
|
+
"./table2": {
|
|
40
|
+
"types": "./dist/table2.d.ts",
|
|
41
|
+
"import": "./dist/table2.js",
|
|
42
|
+
"require": "./dist/table2.cjs"
|
|
43
|
+
},
|
|
44
|
+
"./dialog1": {
|
|
45
|
+
"types": "./dist/dialog1.d.ts",
|
|
46
|
+
"import": "./dist/dialog1.js",
|
|
47
|
+
"require": "./dist/dialog1.cjs"
|
|
48
|
+
},
|
|
49
|
+
"./dropdown1": {
|
|
50
|
+
"types": "./dist/dropdown1.d.ts",
|
|
51
|
+
"import": "./dist/dropdown1.js",
|
|
52
|
+
"require": "./dist/dropdown1.cjs"
|
|
53
|
+
},
|
|
39
54
|
"./list": {
|
|
40
55
|
"types": "./dist/list.d.ts",
|
|
41
56
|
"import": "./dist/list.js",
|
|
@@ -62,6 +77,7 @@
|
|
|
62
77
|
"require": "./dist/navigation.cjs"
|
|
63
78
|
},
|
|
64
79
|
"./styles.css": "./dist/velocis.css",
|
|
80
|
+
"./tailwind-v4.css": "./dist/tailwind-v4.css",
|
|
65
81
|
"./tailwind-preset": {
|
|
66
82
|
"types": "./dist/tailwind-preset.d.ts",
|
|
67
83
|
"import": "./dist/tailwind-preset.js",
|
|
@@ -69,23 +85,34 @@
|
|
|
69
85
|
}
|
|
70
86
|
},
|
|
71
87
|
"files": [
|
|
72
|
-
"dist"
|
|
88
|
+
"dist",
|
|
89
|
+
"docs",
|
|
90
|
+
"README.md",
|
|
91
|
+
"AGENTS.md"
|
|
73
92
|
],
|
|
74
93
|
"peerDependencies": {
|
|
75
94
|
"react": "^18.2.0 || ^19.0.0",
|
|
76
95
|
"react-dom": "^18.2.0 || ^19.0.0",
|
|
77
|
-
"tailwindcss": "
|
|
96
|
+
"tailwindcss": ">=3.4.0"
|
|
97
|
+
},
|
|
98
|
+
"peerDependenciesMeta": {
|
|
99
|
+
"tailwindcss": {
|
|
100
|
+
"optional": true
|
|
101
|
+
}
|
|
78
102
|
},
|
|
79
103
|
"dependencies": {
|
|
80
104
|
"@velocis/card": "0.1.0",
|
|
81
|
-
"@velocis/feedback": "0.1.0",
|
|
82
|
-
"@velocis/core": "0.1.0",
|
|
83
|
-
"@velocis/navigation": "0.1.0",
|
|
84
105
|
"@velocis/forms": "0.1.0",
|
|
106
|
+
"@velocis/navigation": "0.1.1",
|
|
107
|
+
"@velocis/core": "0.1.0",
|
|
108
|
+
"@velocis/feedback": "0.1.1",
|
|
85
109
|
"@velocis/hero": "0.1.0",
|
|
86
|
-
"@velocis/
|
|
87
|
-
"@velocis/
|
|
88
|
-
"@velocis/
|
|
110
|
+
"@velocis/table": "0.1.1",
|
|
111
|
+
"@velocis/list": "0.1.1",
|
|
112
|
+
"@velocis/table2": "0.2.0",
|
|
113
|
+
"@velocis/theme": "0.1.1",
|
|
114
|
+
"@velocis/dialog1": "0.2.0",
|
|
115
|
+
"@velocis/dropdown1": "0.2.0"
|
|
89
116
|
},
|
|
90
117
|
"devDependencies": {
|
|
91
118
|
"tsup": "^8.3.5",
|