pixelize-design-library 2.2.191 → 3.0.1-beta.1
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/.claude/settings.local.json +9 -0
- package/MIGRATION.md +562 -0
- package/coverage/clover.xml +638 -0
- package/coverage/coverage-final.json +20 -0
- package/coverage/lcov-report/Table/CompactSelect.tsx.html +379 -0
- package/coverage/lcov-report/Table/Components/ActiveFilters.tsx.html +514 -0
- package/coverage/lcov-report/Table/Components/HeaderActions.tsx.html +373 -0
- package/coverage/lcov-report/Table/Components/Pagination.tsx.html +574 -0
- package/coverage/lcov-report/Table/Components/TableActions.tsx.html +574 -0
- package/coverage/lcov-report/Table/Components/TableBody.tsx.html +1027 -0
- package/coverage/lcov-report/Table/Components/TableFilters.tsx.html +397 -0
- package/coverage/lcov-report/Table/Components/TableHeader.tsx.html +1060 -0
- package/coverage/lcov-report/Table/Components/TableLoading.tsx.html +361 -0
- package/coverage/lcov-report/Table/Components/TableSearch.tsx.html +337 -0
- package/coverage/lcov-report/Table/Components/index.html +266 -0
- package/coverage/lcov-report/Table/Components/useDebounce.ts.html +178 -0
- package/coverage/lcov-report/Table/Components/useTable.ts.html +778 -0
- package/coverage/lcov-report/Table/LeftFilterPane.tsx.html +1810 -0
- package/coverage/lcov-report/Table/SelectOperationControls.tsx.html +178 -0
- package/coverage/lcov-report/Table/Table.tsx.html +1567 -0
- package/coverage/lcov-report/Table/TableProps.tsx.html +658 -0
- package/coverage/lcov-report/Table/TableSettings/ManageColumns.tsx.html +619 -0
- package/coverage/lcov-report/Table/TableSettings/TableFilters.tsx.html +229 -0
- package/coverage/lcov-report/Table/TableSettings/TableSettings.tsx.html +532 -0
- package/coverage/lcov-report/Table/TableSettings/index.html +146 -0
- package/coverage/lcov-report/Table/TableToDo.tsx.html +973 -0
- package/coverage/lcov-report/Table/TextOperationControls.tsx.html +271 -0
- package/coverage/lcov-report/Table/filterTypes.ts.html +97 -0
- package/coverage/lcov-report/Table/index.html +176 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +146 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +1836 -0
- package/dist/Assets/defaultLogo.tsx +31 -0
- package/dist/Components/Editor/Editor.d.ts +2 -1
- package/dist/Components/Editor/Editor.js +39 -5
- package/dist/Components/KanbanBoard/AccountCard.d.ts +2 -2
- package/dist/Components/KanbanBoard/AccountCard.js +37 -4
- package/dist/Components/KanbanBoard/KanbanBoard.js +72 -35
- package/dist/Components/MultiSelect/MultiSelect.js +10 -19
- package/dist/Components/SearchSelect/SearchSelect.js +23 -16
- package/dist/Components/Table/Components/ActiveFilters.js +66 -25
- package/dist/Components/Table/Components/Pagination.d.ts +1 -1
- package/dist/Components/Table/Components/Pagination.js +41 -9
- package/dist/Components/Table/Components/TableFilters.js +11 -5
- package/dist/Components/Table/Components/useTable.js +36 -24
- package/dist/Theme/Dark/palette.d.ts +370 -0
- package/dist/Theme/Dark/palette.js +372 -0
- package/dist/components-v2/AlertDialog/AlertDialog.d.ts +23 -0
- package/dist/components-v2/AlertDialog/AlertDialog.js +98 -0
- package/dist/components-v2/Breadcrumbs/Breadcrumbs.d.ts +14 -0
- package/dist/components-v2/Breadcrumbs/Breadcrumbs.js +66 -0
- package/dist/components-v2/Charts/AreaChart.d.ts +23 -0
- package/dist/components-v2/Charts/AreaChart.js +63 -0
- package/dist/components-v2/Charts/BarChart.d.ts +25 -0
- package/dist/components-v2/Charts/BarChart.js +57 -0
- package/dist/components-v2/Charts/LineChart.d.ts +23 -0
- package/dist/components-v2/Charts/LineChart.js +55 -0
- package/dist/components-v2/Charts/PieChart.d.ts +15 -0
- package/dist/components-v2/Charts/PieChart.js +54 -0
- package/dist/components-v2/Charts/PolarChart.d.ts +14 -0
- package/dist/components-v2/Charts/PolarChart.js +54 -0
- package/dist/components-v2/Charts/chartOptions.d.ts +7 -0
- package/dist/components-v2/Charts/chartOptions.js +41 -0
- package/dist/components-v2/Charts/useChartTheme.d.ts +22 -0
- package/dist/components-v2/Charts/useChartTheme.js +106 -0
- package/dist/components-v2/ContactForm/ContactForm.d.ts +25 -0
- package/dist/components-v2/ContactForm/ContactForm.js +116 -0
- package/dist/components-v2/DatePicker/Calendar.d.ts +19 -0
- package/dist/components-v2/DatePicker/Calendar.js +212 -0
- package/dist/components-v2/DatePicker/DatePicker.d.ts +46 -0
- package/dist/components-v2/DatePicker/DatePicker.js +189 -0
- package/dist/components-v2/DatePicker/TimePicker.d.ts +12 -0
- package/dist/components-v2/DatePicker/TimePicker.js +105 -0
- package/dist/components-v2/DatePicker/utils.d.ts +31 -0
- package/dist/components-v2/DatePicker/utils.js +109 -0
- package/dist/components-v2/Drawer/Drawer.d.ts +27 -0
- package/dist/components-v2/Drawer/Drawer.js +132 -0
- package/dist/components-v2/FeedbackForm/FeedbackForm.d.ts +26 -0
- package/dist/components-v2/FeedbackForm/FeedbackForm.js +112 -0
- package/dist/components-v2/FileUploader/FileUploader.d.ts +28 -0
- package/dist/components-v2/FileUploader/FileUploader.js +127 -0
- package/dist/components-v2/Input/TextInput.d.ts +41 -0
- package/dist/components-v2/Input/TextInput.js +169 -0
- package/dist/components-v2/KanbanBoard/KanbanBoard.d.ts +39 -0
- package/dist/components-v2/KanbanBoard/KanbanBoard.js +101 -0
- package/dist/components-v2/Layout/AppLayout.d.ts +22 -0
- package/dist/components-v2/Layout/AppLayout.js +53 -0
- package/dist/components-v2/Loading/Loading.d.ts +19 -0
- package/dist/components-v2/Loading/Loading.js +55 -0
- package/dist/components-v2/Modal/Modal.d.ts +30 -0
- package/dist/components-v2/Modal/Modal.js +82 -0
- package/dist/components-v2/NavigationBar/NavigationBar.d.ts +47 -0
- package/dist/components-v2/NavigationBar/NavigationBar.js +148 -0
- package/dist/components-v2/Notification/Notification.d.ts +22 -0
- package/dist/components-v2/Notification/Notification.js +113 -0
- package/dist/components-v2/NumberInput/NumberInput.d.ts +37 -0
- package/dist/components-v2/NumberInput/NumberInput.js +210 -0
- package/dist/components-v2/PinInput/PinInput.d.ts +26 -0
- package/dist/components-v2/PinInput/PinInput.js +138 -0
- package/dist/components-v2/ProfilePhotoViewer/ProfilePhotoViewer.d.ts +18 -0
- package/dist/components-v2/ProfilePhotoViewer/ProfilePhotoViewer.js +91 -0
- package/dist/components-v2/Select/Select.d.ts +41 -0
- package/dist/components-v2/Select/Select.js +284 -0
- package/dist/components-v2/Sidebar/Sidebar.d.ts +41 -0
- package/dist/components-v2/Sidebar/Sidebar.js +182 -0
- package/dist/components-v2/Slider/Slider.d.ts +18 -0
- package/dist/components-v2/Slider/Slider.js +101 -0
- package/dist/components-v2/Table/Table.d.ts +7 -0
- package/dist/components-v2/Table/Table.js +172 -0
- package/dist/components-v2/Table/TableProps.d.ts +139 -0
- package/dist/components-v2/Table/TableProps.js +9 -0
- package/dist/components-v2/Table/components/ActiveFilters.d.ts +10 -0
- package/dist/components-v2/Table/components/ActiveFilters.js +70 -0
- package/dist/components-v2/Table/components/BulkActionBar.d.ts +11 -0
- package/dist/components-v2/Table/components/BulkActionBar.js +92 -0
- package/dist/components-v2/Table/components/ColumnResizeHandle.d.ts +7 -0
- package/dist/components-v2/Table/components/ColumnResizeHandle.js +41 -0
- package/dist/components-v2/Table/components/Pagination.d.ts +11 -0
- package/dist/components-v2/Table/components/Pagination.js +92 -0
- package/dist/components-v2/Table/components/TableBody.d.ts +23 -0
- package/dist/components-v2/Table/components/TableBody.js +69 -0
- package/dist/components-v2/Table/components/TableCell.d.ts +14 -0
- package/dist/components-v2/Table/components/TableCell.js +63 -0
- package/dist/components-v2/Table/components/TableEmptyState.d.ts +12 -0
- package/dist/components-v2/Table/components/TableEmptyState.js +55 -0
- package/dist/components-v2/Table/components/TableErrorState.d.ts +6 -0
- package/dist/components-v2/Table/components/TableErrorState.js +52 -0
- package/dist/components-v2/Table/components/TableHeader.d.ts +21 -0
- package/dist/components-v2/Table/components/TableHeader.js +94 -0
- package/dist/components-v2/Table/components/TableRow.d.ts +20 -0
- package/dist/components-v2/Table/components/TableRow.js +64 -0
- package/dist/components-v2/Table/components/TableSearch.d.ts +8 -0
- package/dist/components-v2/Table/components/TableSearch.js +47 -0
- package/dist/components-v2/Table/filters/FilterChips.d.ts +6 -0
- package/dist/components-v2/Table/filters/FilterChips.js +9 -0
- package/dist/components-v2/Table/filters/LeftFilterPane.d.ts +17 -0
- package/dist/components-v2/Table/filters/LeftFilterPane.js +105 -0
- package/dist/components-v2/Table/filters/TableFilters.d.ts +12 -0
- package/dist/components-v2/Table/filters/TableFilters.js +127 -0
- package/dist/components-v2/Table/hooks/useColumnResize.d.ts +15 -0
- package/dist/components-v2/Table/hooks/useColumnResize.js +104 -0
- package/dist/components-v2/Table/hooks/useTable.d.ts +58 -0
- package/dist/components-v2/Table/hooks/useTable.js +254 -0
- package/dist/components-v2/Table/hooks/useTableKeyboard.d.ts +25 -0
- package/dist/components-v2/Table/hooks/useTableKeyboard.js +112 -0
- package/dist/components-v2/Table/hooks/useVirtualScroll.d.ts +29 -0
- package/dist/components-v2/Table/hooks/useVirtualScroll.js +83 -0
- package/dist/components-v2/Table/settings/ManageColumns.d.ts +12 -0
- package/dist/components-v2/Table/settings/ManageColumns.js +59 -0
- package/dist/components-v2/Table/settings/TableSettings.d.ts +12 -0
- package/dist/components-v2/Table/settings/TableSettings.js +57 -0
- package/dist/components-v2/Table/utils/filterUtils.d.ts +7 -0
- package/dist/components-v2/Table/utils/filterUtils.js +149 -0
- package/dist/components-v2/Table/utils/sortUtils.d.ts +6 -0
- package/dist/components-v2/Table/utils/sortUtils.js +65 -0
- package/dist/components-v2/Tag/Tag.d.ts +15 -0
- package/dist/components-v2/Tag/Tag.js +87 -0
- package/dist/components-v2/Timeline/Timeline.d.ts +18 -0
- package/dist/components-v2/Timeline/Timeline.js +76 -0
- package/dist/components-v2/Toaster/Toaster.d.ts +61 -0
- package/dist/components-v2/Toaster/Toaster.js +63 -0
- package/dist/components-v2/Toggle/Toggle.d.ts +28 -0
- package/dist/components-v2/Toggle/Toggle.js +90 -0
- package/dist/components-v2/ui/accordion.d.ts +12 -0
- package/dist/components-v2/ui/accordion.js +104 -0
- package/dist/components-v2/ui/alert.d.ts +18 -0
- package/dist/components-v2/ui/alert.js +99 -0
- package/dist/components-v2/ui/avatar.d.ts +12 -0
- package/dist/components-v2/ui/avatar.js +80 -0
- package/dist/components-v2/ui/badge.d.ts +10 -0
- package/dist/components-v2/ui/badge.js +76 -0
- package/dist/components-v2/ui/button.d.ts +18 -0
- package/dist/components-v2/ui/button.js +97 -0
- package/dist/components-v2/ui/checkbox.d.ts +15 -0
- package/dist/components-v2/ui/checkbox.js +86 -0
- package/dist/components-v2/ui/dialog.d.ts +30 -0
- package/dist/components-v2/ui/dialog.js +115 -0
- package/dist/components-v2/ui/dropdown-menu.d.ts +26 -0
- package/dist/components-v2/ui/dropdown-menu.js +121 -0
- package/dist/components-v2/ui/field.d.ts +32 -0
- package/dist/components-v2/ui/field.js +62 -0
- package/dist/components-v2/ui/form-field.d.ts +25 -0
- package/dist/components-v2/ui/form-field.js +96 -0
- package/dist/components-v2/ui/input.d.ts +9 -0
- package/dist/components-v2/ui/input.js +73 -0
- package/dist/components-v2/ui/label.d.ts +10 -0
- package/dist/components-v2/ui/label.js +70 -0
- package/dist/components-v2/ui/popover.d.ts +9 -0
- package/dist/components-v2/ui/popover.js +60 -0
- package/dist/components-v2/ui/progress.d.ts +12 -0
- package/dist/components-v2/ui/progress.js +75 -0
- package/dist/components-v2/ui/radio-group.d.ts +17 -0
- package/dist/components-v2/ui/radio-group.js +91 -0
- package/dist/components-v2/ui/select.d.ts +24 -0
- package/dist/components-v2/ui/select.js +122 -0
- package/dist/components-v2/ui/separator.d.ts +5 -0
- package/dist/components-v2/ui/separator.js +55 -0
- package/dist/components-v2/ui/skeleton.d.ts +9 -0
- package/dist/components-v2/ui/skeleton.js +68 -0
- package/dist/components-v2/ui/spinner.d.ts +16 -0
- package/dist/components-v2/ui/spinner.js +64 -0
- package/dist/components-v2/ui/switch.d.ts +10 -0
- package/dist/components-v2/ui/switch.js +81 -0
- package/dist/components-v2/ui/tabs.d.ts +13 -0
- package/dist/components-v2/ui/tabs.js +95 -0
- package/dist/components-v2/ui/textarea.d.ts +10 -0
- package/dist/components-v2/ui/textarea.js +96 -0
- package/dist/components-v2/ui/tooltip.d.ts +17 -0
- package/dist/components-v2/ui/tooltip.js +75 -0
- package/dist/index.d.ts +128 -64
- package/dist/index.js +246 -173
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/theme-v2/ThemeProvider.d.ts +19 -0
- package/dist/theme-v2/ThemeProvider.js +149 -0
- package/dist/theme-v2/dark.css +47 -0
- package/dist/theme-v2/tokens.css +72 -0
- package/package.json +41 -20
- package/tailwind.config.ts +91 -0
- package/vite.config.ts +49 -10
- package/index.html +0 -13
package/MIGRATION.md
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
# Pixelize v3 migration guide
|
|
2
|
+
|
|
3
|
+
This guide covers upgrading from the Chakra UI–based v2 to the Tailwind + Radix v3.
|
|
4
|
+
|
|
5
|
+
> **TL;DR** — replace Chakra props with the new shadcn-style props, import the v3 CSS once at app root, swap `ThemeProvider`/`useCustomTheme()` for the new `ThemeProvider`/`useTheme()`, and treat `Select` consolidation + `Modal → Dialog` as the two biggest API changes.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Installation
|
|
10
|
+
|
|
11
|
+
### Remove
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm uninstall @chakra-ui/react @emotion/react @emotion/styled
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Add (already present after `npm install`)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Runtime
|
|
21
|
+
npm install \
|
|
22
|
+
class-variance-authority clsx tailwind-merge \
|
|
23
|
+
@radix-ui/react-accordion @radix-ui/react-alert-dialog \
|
|
24
|
+
@radix-ui/react-avatar @radix-ui/react-checkbox \
|
|
25
|
+
@radix-ui/react-dialog @radix-ui/react-dropdown-menu \
|
|
26
|
+
@radix-ui/react-label @radix-ui/react-popover \
|
|
27
|
+
@radix-ui/react-progress @radix-ui/react-radio-group \
|
|
28
|
+
@radix-ui/react-select @radix-ui/react-separator \
|
|
29
|
+
@radix-ui/react-slider @radix-ui/react-slot \
|
|
30
|
+
@radix-ui/react-switch @radix-ui/react-tabs \
|
|
31
|
+
@radix-ui/react-tooltip \
|
|
32
|
+
cmdk date-fns sonner
|
|
33
|
+
|
|
34
|
+
# Dev
|
|
35
|
+
npm install -D tailwindcss @tailwindcss/typography tailwindcss-animate autoprefixer postcss
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Tailwind config
|
|
39
|
+
|
|
40
|
+
Copy the library's `tailwind.config.ts` settings (or extend your own) so the CSS variables map to color utility classes:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// tailwind.config.ts
|
|
44
|
+
import type { Config } from "tailwindcss";
|
|
45
|
+
|
|
46
|
+
export default {
|
|
47
|
+
darkMode: "class",
|
|
48
|
+
content: ["./src/**/*.{ts,tsx}"],
|
|
49
|
+
theme: {
|
|
50
|
+
extend: {
|
|
51
|
+
colors: {
|
|
52
|
+
primary: {
|
|
53
|
+
DEFAULT: "hsl(var(--color-primary) / <alpha-value>)",
|
|
54
|
+
foreground: "hsl(var(--color-primary-foreground) / <alpha-value>)",
|
|
55
|
+
},
|
|
56
|
+
// … repeat for secondary, background, foreground, card, muted, accent, destructive, success, warning, border, input, ring
|
|
57
|
+
},
|
|
58
|
+
borderRadius: { lg: "var(--radius)" },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
plugins: [require("tailwindcss-animate")],
|
|
62
|
+
} satisfies Config;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 2. Required CSS imports
|
|
68
|
+
|
|
69
|
+
Import once in your app entry (e.g. `main.tsx`):
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
// Tailwind directives
|
|
73
|
+
import "./index.css"; // contains @tailwind base; components; utilities;
|
|
74
|
+
|
|
75
|
+
// Library tokens
|
|
76
|
+
import "pixelize-design-library/src/theme-v2/tokens.css";
|
|
77
|
+
import "pixelize-design-library/src/theme-v2/dark.css";
|
|
78
|
+
|
|
79
|
+
// Optional preset (pick one)
|
|
80
|
+
import "pixelize-design-library/src/theme-v2/presets/default.css";
|
|
81
|
+
// or "meadow", "rosewood", "skyline", "slate", "emerald", "radiant"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The dark-mode tokens activate automatically when `<html>` has the `.dark` class. Preset tokens activate when `<html>` has the matching `data-theme="..."` attribute. **`ThemeProvider` writes both for you** — you don't toggle them by hand.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 3. ThemeProvider setup
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// app entry
|
|
92
|
+
import {
|
|
93
|
+
ThemeProvider,
|
|
94
|
+
Toaster,
|
|
95
|
+
} from "pixelize-design-library";
|
|
96
|
+
|
|
97
|
+
import "./index.css";
|
|
98
|
+
import "pixelize-design-library/src/theme-v2/tokens.css";
|
|
99
|
+
import "pixelize-design-library/src/theme-v2/dark.css";
|
|
100
|
+
import "pixelize-design-library/src/theme-v2/presets/default.css";
|
|
101
|
+
|
|
102
|
+
createRoot(document.getElementById("root")!).render(
|
|
103
|
+
<ThemeProvider defaultTheme="default" defaultMode="system">
|
|
104
|
+
<App />
|
|
105
|
+
<Toaster />
|
|
106
|
+
</ThemeProvider>,
|
|
107
|
+
);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`ThemeProvider` already mounts a global `TooltipProvider`, so you do not need to wrap separately.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 4. Component mapping table
|
|
115
|
+
|
|
116
|
+
| Old (v2 / Chakra) | New (v3) | Notes |
|
|
117
|
+
| ------------------------ | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `Modal` | `Dialog` (`Modal` still works as a compat shim) | See §6. |
|
|
119
|
+
| `Drawer` (old Chakra) | `Drawer` | API is now `side` + `size` (sm/md/lg/full). |
|
|
120
|
+
| `AlertDialog` | `AlertDialog` | Cannot dismiss via outside-click (matches Radix semantics). |
|
|
121
|
+
| `Select` | `Select` | See §5 — consolidated. |
|
|
122
|
+
| `SearchSelect` | `Select searchable` | Same component, set `searchable`. |
|
|
123
|
+
| `SelectSearch` | `Select searchable creatable` | Same component, add `creatable + onCreateOption`. |
|
|
124
|
+
| `MultiSelect` | `Select multiple` | Same component, set `multiple`. |
|
|
125
|
+
| `Checkbox` | `Checkbox` | Now uses `checked` / `onCheckedChange` (Radix). Boolean `checked` or `"indeterminate"`. |
|
|
126
|
+
| `RadioButton(Group)` | `RadioGroup` / `RadioGroupItem` | Use `value` + `onValueChange`. |
|
|
127
|
+
| `Switch` | `Switch` | Use `checked` + `onCheckedChange`. |
|
|
128
|
+
| `Button` | `Button` | `colorScheme` → `variant`. `isLoading` retained. `leftIcon` / `rightIcon` accept any ReactNode (Lucide icons work). |
|
|
129
|
+
| `TextInput` | `TextInput` | Props largely retained. `error` is now boolean + `errorMessage`. Floating label via `variant="floating"`. `isInformation` → `informationMessage`. |
|
|
130
|
+
| `InputTextArea` | `Textarea` (primitive) or `Field` + `Textarea` | `Textarea` supports `autoResize`, `minRows`, `maxRows`. |
|
|
131
|
+
| `NumberInput` | `NumberInput` | Now type=text + inputmode=decimal under the hood; arrows + clamp on blur. |
|
|
132
|
+
| `DatePicker` | `DatePicker` | Full rewrite (date-fns, fully a11y-correct calendar grid). |
|
|
133
|
+
| `PinInput` | `PinInput` | Auto-advance, paste-to-fill, `mask` for OTP. |
|
|
134
|
+
| `Slider` | `Slider` | Single value OR range (pass an array). `marks` + `showTooltip`. |
|
|
135
|
+
| `FileUploader` | `FileUploader` | Built on react-dropzone with theme-aware drag/error states. |
|
|
136
|
+
| `ContactForm` | `ContactForm` | Built-in validation, isLoading state, success state. |
|
|
137
|
+
| `FeedbackForm` | `FeedbackForm` | 5-star rating + optional comment. |
|
|
138
|
+
| `Table` | `Table` | Generic-typed (`<Table<MyRow>>`). New unified API — see §4a. |
|
|
139
|
+
| `Sidebar` (`SideBar`) | `Sidebar` | Collapsed + mobile drawer modes; pure CSS responsive (no JS sizing). |
|
|
140
|
+
| `NavigationBar` | `NavigationBar` | New `globalSearch`, `notificationCount`, `userMenuItems`, `showThemeSwitcher` props. |
|
|
141
|
+
| `Breadcrumbs` | `Breadcrumbs` | `items` is now `{ label, href?, onClick? }[]`, `maxItems` collapses middle. |
|
|
142
|
+
| `Toaster` + `useToaster` | `Toaster` + `toast` | Now built on `sonner`. `toast.success(...)` etc. No more `useToaster()` hook. |
|
|
143
|
+
| `ProgressBar` | `Progress` | `value` is the percentage. `size` controls thickness. |
|
|
144
|
+
| `ProfileCard` | _Removed_ — compose from `Avatar`, `Badge`, `Card` | The old composite was rarely a clean fit; assemble what you need. |
|
|
145
|
+
| `Card` (Chakra) | Plain `<div className="rounded-lg border border-border bg-card p-4">` | No need for a component wrapper — use the token classes. |
|
|
146
|
+
| `Tag` | `Tag` | `label`, `onRemove`, `variant`, `size`, `icon`. |
|
|
147
|
+
| `TableToggle` / `Toggle` | `TableToggle` / `Toggle` | Now an ARIA toggle button, not a `Switch`. |
|
|
148
|
+
| `Notification` | `Notification` | Card item for feeds — unread border, dismiss button, action slot. |
|
|
149
|
+
| `Timeline` | `Timeline` | `items` with `variant` per item, `state: 'past' \| 'current' \| 'future'` for dashed connector. |
|
|
150
|
+
| `KanbanBoard` | `KanbanBoard` | Kept `@hello-pangea/dnd`. Now typed; `onCardMove` receives `{ cardId, fromColumnId, toColumnId, newIndex }`. |
|
|
151
|
+
| Apex chart components | `BarChart` / `LineChart` / `AreaChart` / `PieChart` / `PolarChart` | Theme-aware via `useChartTheme()`. |
|
|
152
|
+
| `Loading` | `Loading` | Variants: `spinner` (inline), `overlay` (full screen), `skeleton`. |
|
|
153
|
+
| `Skeletons` | `Skeleton` | Variants: `text`, `circle`, `rectangle`. |
|
|
154
|
+
| `withTheme` HOC | `ThemeProvider` | Drop the HOC — wrap once at app root. |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 4a. Table prop renames
|
|
159
|
+
|
|
160
|
+
The Table is generic-typed and has a new prop surface. Every consumer using `<Table>` will get TypeScript errors. Use this table to translate.
|
|
161
|
+
|
|
162
|
+
### Data shape
|
|
163
|
+
|
|
164
|
+
| Old | New |
|
|
165
|
+
| --- | --- |
|
|
166
|
+
| `data: DataObject[]` (untyped, used `id` + `content` + per-row callbacks) | `data: T[]` (your own row type) + `rowKey: keyof T \| (row: T) => string \| number` |
|
|
167
|
+
| `columns: TableHeaderProps[]` with `label` / `key` / `render` | `columns: ColumnDef<T>[]` with `id` / `header` / `accessorKey` / `accessorFn` / `cell` |
|
|
168
|
+
|
|
169
|
+
### Prop renames
|
|
170
|
+
|
|
171
|
+
| Old prop | New prop |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `isPagination` | `pagination` |
|
|
174
|
+
| `noOfRowsPerPage` | `defaultPageSize` |
|
|
175
|
+
| `paginationSelectOptions` | `pageSizeOptions` |
|
|
176
|
+
| `totalRecords` | `totalCount` |
|
|
177
|
+
| `onPagination(page, rows, record, direction)` | `onPageChange(page, pageSize)` |
|
|
178
|
+
| `onNoOfRowsPerPageChange` | folded into `onPageChange` |
|
|
179
|
+
| `isCheckbox` | `selectable` |
|
|
180
|
+
| `selections` | `selectedRows` |
|
|
181
|
+
| `onSelection(keys)` | `onSelectionChange(keys)` |
|
|
182
|
+
| `onGlobalSearch(query)` | `onSearchChange(query)` (set `isServerSearch` to disable client filter) |
|
|
183
|
+
| `onColumnFilter(filters)` | `onFilterChange(filters)` |
|
|
184
|
+
| `isLoading` | same |
|
|
185
|
+
| `loadingSkeletonRows` | `loadingRowCount` |
|
|
186
|
+
| `headerBgColor` / `freezedBgColor` / `headerTextColor` / `freezedTextColor` / `tableBorderColor` | _removed_ — restyle via the `className` prop or by overriding the relevant CSS variables |
|
|
187
|
+
| `noBorders` | same |
|
|
188
|
+
| `tableMaxHeight` | `maxHeight` |
|
|
189
|
+
| `minVisibleRows` / `maxVisibleRows` / `autoFitViewport` | _removed_ — set `maxHeight` and let the table scroll internally |
|
|
190
|
+
| `defaultVisibleColumns: number` | `defaultHiddenColumns: string[]` (list of column ids) |
|
|
191
|
+
| `isVisiblity` | `showColumnToggle` |
|
|
192
|
+
| `isActionFreeze` | _removed_ — use `column.sticky: 'left' \| 'right'` per-column |
|
|
193
|
+
| `headerActions` (Chakra-shaped object) | `headerActions: ReactNode` (compose your own toolbar slot) + `bulkActions` for selection-driven actions |
|
|
194
|
+
| `tableSettings` | `showColumnToggle` + `preferences` |
|
|
195
|
+
| `filterSidebar.isFilterSidebar` | `filterSidebar.enabled` |
|
|
196
|
+
| `filterSidebar.handleSidebarFilterClick` | `filterSidebar.onApply` |
|
|
197
|
+
| `filterSidebar.isApplyLoading` | `filterSidebar.isLoading` |
|
|
198
|
+
| `preferences: { url, token, key, … }` (server-side) | `preferences: { storageKey }` (localStorage only — wire your own server sync via `onSortChange` / `onFilterChange` / `onPageChange`) |
|
|
199
|
+
| `onRowClick(row, header)` | `onRowClick(row, event)` |
|
|
200
|
+
| Row-level `onLink` / `onEdit` / `onDelete` callbacks on individual data rows | _removed_ — add an "Actions" column with `cell: (_, row) => <DropdownMenu>…</DropdownMenu>` |
|
|
201
|
+
| `loadingType` / `loadingContaxt` / `loadingBoxStyle` | _removed_ — `isLoading` now renders skeleton rows; for custom states pass `emptyState` |
|
|
202
|
+
|
|
203
|
+
### Before / after
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
// before
|
|
207
|
+
<Table
|
|
208
|
+
data={users}
|
|
209
|
+
columns={[
|
|
210
|
+
{ key: "name", label: "Name" },
|
|
211
|
+
{ key: "email", label: "Email" },
|
|
212
|
+
]}
|
|
213
|
+
isPagination
|
|
214
|
+
paginationMode="client"
|
|
215
|
+
noOfRowsPerPage={25}
|
|
216
|
+
paginationSelectOptions={[10, 25, 50]}
|
|
217
|
+
isCheckbox
|
|
218
|
+
selections={selected}
|
|
219
|
+
onSelection={setSelected}
|
|
220
|
+
onGlobalSearch={(q) => fetch(q)}
|
|
221
|
+
isLoading={loading}
|
|
222
|
+
loadingSkeletonRows={5}
|
|
223
|
+
/>;
|
|
224
|
+
|
|
225
|
+
// after
|
|
226
|
+
<Table<User>
|
|
227
|
+
data={users}
|
|
228
|
+
columns={[
|
|
229
|
+
{ id: "name", header: "Name", accessorKey: "name", sortable: true },
|
|
230
|
+
{ id: "email", header: "Email", accessorKey: "email" },
|
|
231
|
+
]}
|
|
232
|
+
rowKey="id"
|
|
233
|
+
pagination
|
|
234
|
+
paginationMode="client"
|
|
235
|
+
defaultPageSize={25}
|
|
236
|
+
pageSizeOptions={[10, 25, 50]}
|
|
237
|
+
selectable
|
|
238
|
+
selectedRows={selected}
|
|
239
|
+
onSelectionChange={setSelected}
|
|
240
|
+
onSearchChange={(q) => fetch(q)}
|
|
241
|
+
isServerSearch
|
|
242
|
+
isLoading={loading}
|
|
243
|
+
loadingRowCount={5}
|
|
244
|
+
/>;
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## 4b. Tailwind class migration
|
|
250
|
+
|
|
251
|
+
The old config exposed **per-shade** tokens (`primary-50…900`, `gray-50…900`, semantic palettes). The new config exposes **semantic** tokens that automatically swap on dark mode and on preset theme changes. There is no `gray-700` anymore — use `muted-foreground` instead.
|
|
252
|
+
|
|
253
|
+
> **Important**: Tailwind silently drops unknown utility classes. After upgrading, classes like `bg-primary-500` produce **no styles** — not an error. Search-and-replace before deploying.
|
|
254
|
+
|
|
255
|
+
### Brand
|
|
256
|
+
|
|
257
|
+
| Old | New | Notes |
|
|
258
|
+
| --- | --- | --- |
|
|
259
|
+
| `bg-primary-50` … `bg-primary-100` | `bg-primary/10` | very light tint |
|
|
260
|
+
| `bg-primary-200` … `bg-primary-400` | `bg-primary/30` … `bg-primary/50` | tints via opacity |
|
|
261
|
+
| `bg-primary-500` / `bg-primary-600` | `bg-primary` | the base brand color |
|
|
262
|
+
| `bg-primary-700` … `bg-primary-900` | `bg-primary` + custom darken via `dark:` if needed | shades collapse |
|
|
263
|
+
| `text-primary-*` | `text-primary` | foreground equivalent: `text-primary-foreground` (the readable color on top of primary) |
|
|
264
|
+
| `border-primary-*` | `border-primary` | |
|
|
265
|
+
| `bg-primary-opacity-{8,16,24,28,32,40}` | `bg-primary/{8,16,24,28,32,40}` | Tailwind opacity modifier |
|
|
266
|
+
|
|
267
|
+
### Surfaces & text
|
|
268
|
+
|
|
269
|
+
| Old | New |
|
|
270
|
+
| --- | --- |
|
|
271
|
+
| `bg-background-main` | `bg-background` |
|
|
272
|
+
| `bg-background-secondary` / `bg-background-tertiary` / `bg-background-quaternary` | `bg-card` / `bg-muted` (pick by intent) |
|
|
273
|
+
| `bg-background-light` / `bg-background-medium` | `bg-muted` |
|
|
274
|
+
| `bg-background-accent` / `bg-background-subtle` | `bg-accent` / `bg-muted` |
|
|
275
|
+
| `bg-background-muted` / `bg-background-neutral` | `bg-muted` |
|
|
276
|
+
| `bg-background-base` | `bg-background` |
|
|
277
|
+
| `bg-background-tableHeader` | `bg-muted/50` |
|
|
278
|
+
| `text-text-heading` | `text-foreground` |
|
|
279
|
+
| `text-text-body` | `text-foreground` |
|
|
280
|
+
| `text-text-subtle` | `text-muted-foreground` |
|
|
281
|
+
| `text-text-input` | `text-foreground` |
|
|
282
|
+
| `text-text-headingOpacity-{4,8}` | `text-foreground/{4,8}` |
|
|
283
|
+
|
|
284
|
+
### Borders
|
|
285
|
+
|
|
286
|
+
| Old | New |
|
|
287
|
+
| --- | --- |
|
|
288
|
+
| `border-border-default` | `border-border` |
|
|
289
|
+
| `border-border-light` | `border-border/60` |
|
|
290
|
+
| `border-border-dark` | `border-border` (use `dark:` for dark mode tuning) |
|
|
291
|
+
| `border-border-input` | `border-input` |
|
|
292
|
+
| `border-border-error` | `border-destructive` |
|
|
293
|
+
| `border-border-success` | `border-success` |
|
|
294
|
+
| `border-border-warning` | `border-warning` |
|
|
295
|
+
| `border-border-info` | `border-primary` |
|
|
296
|
+
|
|
297
|
+
### Semantic palettes
|
|
298
|
+
|
|
299
|
+
| Old | New |
|
|
300
|
+
| --- | --- |
|
|
301
|
+
| `bg-semantic-success-*` | `bg-success` (foreground: `text-success-foreground`) |
|
|
302
|
+
| `bg-semantic-error-*` | `bg-destructive` (foreground: `text-destructive-foreground`) |
|
|
303
|
+
| `bg-semantic-warning-*` | `bg-warning` (foreground: `text-warning-foreground`) |
|
|
304
|
+
| `bg-semantic-info-*` | `bg-primary` (foreground: `text-primary-foreground`) |
|
|
305
|
+
|
|
306
|
+
### Generic palette (`gray`, `red`, `blue`, etc.)
|
|
307
|
+
|
|
308
|
+
The new config does **not** redefine `gray`, `red`, `blue`, `green`, `teal`, `cyan`, `purple`, `pink`, `orange`, `yellow`. Tailwind's built-in palette is still available, so `bg-gray-700` continues to resolve to Tailwind's stock gray.
|
|
309
|
+
|
|
310
|
+
**However**, the old library overrode `gray` with CSS-var-based shades that responded to dark mode. The new approach is to use semantic tokens (`muted`, `muted-foreground`, `accent`, `card`) so colors flip automatically. Migrate `bg-gray-100 → bg-muted` and `text-gray-700 → text-muted-foreground` for theme-aware styling. Leave plain `gray-*` only where you genuinely want a fixed gray that ignores the theme.
|
|
311
|
+
|
|
312
|
+
### JS-side theme access
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
// before
|
|
316
|
+
import { useCustomTheme } from "pixelize-design-library";
|
|
317
|
+
const theme = useCustomTheme();
|
|
318
|
+
const color = theme.colors.primary[500];
|
|
319
|
+
const bg = theme.colors.background.main;
|
|
320
|
+
|
|
321
|
+
// after — JS access is no longer needed for colors. If you must read the
|
|
322
|
+
// computed color at runtime (e.g. for canvas/chart libraries), use:
|
|
323
|
+
import { useChartTheme } from "pixelize-design-library";
|
|
324
|
+
const { primary, foreground, background, palette } = useChartTheme();
|
|
325
|
+
// or for arbitrary CSS vars:
|
|
326
|
+
getComputedStyle(document.documentElement).getPropertyValue("--color-primary").trim();
|
|
327
|
+
// (returns the raw "221 83% 53%" HSL channels — wrap in `hsl(...)` to use)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Quick sed migration script
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Run from your consumer app root. Review the diff before committing.
|
|
334
|
+
git ls-files '*.tsx' '*.ts' '*.jsx' '*.js' '*.css' | xargs sed -i.bak -E \
|
|
335
|
+
-e 's/(bg|text|border|ring|fill|stroke)-primary-[0-9]+/\1-primary/g' \
|
|
336
|
+
-e 's/(bg|text|border)-background-main/\1-background/g' \
|
|
337
|
+
-e 's/(bg|text|border)-background-(secondary|tertiary|quaternary|light|medium)/\1-card/g' \
|
|
338
|
+
-e 's/(bg|text|border)-background-(subtle|muted|neutral)/\1-muted/g' \
|
|
339
|
+
-e 's/(bg|text|border)-background-accent/\1-accent/g' \
|
|
340
|
+
-e 's/(bg|text|border)-text-heading/\1-foreground/g' \
|
|
341
|
+
-e 's/(bg|text|border)-text-(body|input)/\1-foreground/g' \
|
|
342
|
+
-e 's/(bg|text|border)-text-subtle/\1-muted-foreground/g' \
|
|
343
|
+
-e 's/(bg|text|border)-border-default/\1-border/g' \
|
|
344
|
+
-e 's/(bg|text|border)-border-error/\1-destructive/g' \
|
|
345
|
+
-e 's/(bg|text|border)-border-success/\1-success/g' \
|
|
346
|
+
-e 's/(bg|text|border)-border-warning/\1-warning/g' \
|
|
347
|
+
-e 's/(bg|text|border)-border-info/\1-primary/g' \
|
|
348
|
+
-e 's/(bg|text|border)-semantic-error-[0-9]+/\1-destructive/g' \
|
|
349
|
+
-e 's/(bg|text|border)-semantic-success-[0-9]+/\1-success/g' \
|
|
350
|
+
-e 's/(bg|text|border)-semantic-warning-[0-9]+/\1-warning/g' \
|
|
351
|
+
-e 's/(bg|text|border)-semantic-info-[0-9]+/\1-primary/g' \
|
|
352
|
+
-e 's/(bg|text|border)-primary-opacity-([0-9]+)/\1-primary\/\2/g'
|
|
353
|
+
|
|
354
|
+
# Then visually QA. Leftovers to fix by hand:
|
|
355
|
+
git grep -E '\-(primary|background|text|border|semantic)-[0-9]+'
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 5. Select consolidation (4 → 1)
|
|
361
|
+
|
|
362
|
+
Old:
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
<Select options={…} value={v} onChange={setV} />
|
|
366
|
+
<SearchSelect options={…} value={v} onChange={setV} />
|
|
367
|
+
<SelectSearch options={…} value={v} onChange={setV} onCreate={addNew} />
|
|
368
|
+
<MultiSelect options={…} value={vs} onChange={setVs} />
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
New — one component, additive props:
|
|
372
|
+
|
|
373
|
+
```tsx
|
|
374
|
+
import { Select } from "pixelize-design-library";
|
|
375
|
+
|
|
376
|
+
<Select options={…} value={v} onChange={setV} /> // plain
|
|
377
|
+
<Select options={…} value={v} onChange={setV} searchable /> // searchable
|
|
378
|
+
<Select options={…} value={v} onChange={setV} searchable creatable
|
|
379
|
+
onCreateOption={addNew} /> // create-on-search
|
|
380
|
+
<Select options={…} value={vs} onChange={setVs} multiple searchable
|
|
381
|
+
clearable maxDisplayed={3} /> // multi
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Options are typed and groupable:
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
const options: SelectOption[] = [
|
|
388
|
+
{ value: "us", label: "United States", group: "Americas", icon: <Flag /> },
|
|
389
|
+
{ value: "uk", label: "United Kingdom", group: "Europe", description: "GBP" },
|
|
390
|
+
];
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Async search:
|
|
394
|
+
|
|
395
|
+
```tsx
|
|
396
|
+
<Select
|
|
397
|
+
options={remoteOptions}
|
|
398
|
+
onSearch={(q) => fetchOptions(q)} // called on every keystroke; no client filter
|
|
399
|
+
searchable
|
|
400
|
+
isLoading={isFetching}
|
|
401
|
+
/>
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## 6. Modal → Dialog
|
|
407
|
+
|
|
408
|
+
The `Modal` export still works as a thin compatibility shim, but new code should use `Dialog`.
|
|
409
|
+
|
|
410
|
+
Before:
|
|
411
|
+
|
|
412
|
+
```tsx
|
|
413
|
+
import { Modal, ModalHeader, ModalBody, ModalFooter } from "pixelize-design-library";
|
|
414
|
+
|
|
415
|
+
<Modal isOpen={open} onClose={() => setOpen(false)}>
|
|
416
|
+
<ModalHeader>Delete project</ModalHeader>
|
|
417
|
+
<ModalBody>This cannot be undone.</ModalBody>
|
|
418
|
+
<ModalFooter>
|
|
419
|
+
<Button onClick={() => setOpen(false)}>Cancel</Button>
|
|
420
|
+
<Button colorScheme="red" onClick={remove}>Delete</Button>
|
|
421
|
+
</ModalFooter>
|
|
422
|
+
</Modal>
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
After:
|
|
426
|
+
|
|
427
|
+
```tsx
|
|
428
|
+
import {
|
|
429
|
+
Dialog,
|
|
430
|
+
DialogClose,
|
|
431
|
+
DialogContent,
|
|
432
|
+
DialogDescription,
|
|
433
|
+
DialogFooter,
|
|
434
|
+
DialogHeader,
|
|
435
|
+
DialogTitle,
|
|
436
|
+
Button,
|
|
437
|
+
} from "pixelize-design-library";
|
|
438
|
+
|
|
439
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
440
|
+
<DialogContent size="sm">
|
|
441
|
+
<DialogHeader>
|
|
442
|
+
<DialogTitle>Delete project</DialogTitle>
|
|
443
|
+
<DialogDescription>This cannot be undone.</DialogDescription>
|
|
444
|
+
</DialogHeader>
|
|
445
|
+
<DialogFooter>
|
|
446
|
+
<DialogClose asChild>
|
|
447
|
+
<Button variant="outline">Cancel</Button>
|
|
448
|
+
</DialogClose>
|
|
449
|
+
<Button variant="destructive" onClick={remove}>Delete</Button>
|
|
450
|
+
</DialogFooter>
|
|
451
|
+
</DialogContent>
|
|
452
|
+
</Dialog>;
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
For destructive flows where outside-click dismissal would be a foot-gun, use `AlertDialog` instead.
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## 7. Theming: `useCustomTheme()` → `useTheme()` + CSS variables
|
|
460
|
+
|
|
461
|
+
The old per-color tokens (e.g. `theme.colors.primary[500]`) are replaced by **CSS variables**. Read them via Tailwind utility classes — never via JS.
|
|
462
|
+
|
|
463
|
+
Before:
|
|
464
|
+
|
|
465
|
+
```tsx
|
|
466
|
+
import { useCustomTheme } from "pixelize-design-library";
|
|
467
|
+
|
|
468
|
+
function MyBadge() {
|
|
469
|
+
const theme = useCustomTheme();
|
|
470
|
+
return <span style={{ background: theme.colors.primary[500] }}>Hi</span>;
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
After:
|
|
475
|
+
|
|
476
|
+
```tsx
|
|
477
|
+
function MyBadge() {
|
|
478
|
+
return <span className="bg-primary text-primary-foreground">Hi</span>;
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Need to read or set the *theme* (preset) or *mode* (light/dark)? Use `useTheme()`:
|
|
483
|
+
|
|
484
|
+
```tsx
|
|
485
|
+
import { useTheme } from "pixelize-design-library";
|
|
486
|
+
|
|
487
|
+
function ThemePicker() {
|
|
488
|
+
const { theme, setTheme, mode, setMode, resolvedMode } = useTheme();
|
|
489
|
+
return (
|
|
490
|
+
<button onClick={() => setMode(resolvedMode === "dark" ? "light" : "dark")}>
|
|
491
|
+
Toggle (current: {resolvedMode})
|
|
492
|
+
</button>
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Need to override one color globally? Set the CSS variable on `:root`:
|
|
498
|
+
|
|
499
|
+
```css
|
|
500
|
+
/* in your app's css */
|
|
501
|
+
:root {
|
|
502
|
+
--color-primary: 280 80% 55%; /* HSL channels, no hsl() wrapper */
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## 8. Dark mode setup
|
|
509
|
+
|
|
510
|
+
The library is dark-mode-ready out of the box — you just need to ensure your Tailwind config has `darkMode: "class"` (mirroring the library's) so utility classes like `dark:bg-card` resolve to your own components too.
|
|
511
|
+
|
|
512
|
+
`ThemeProvider` toggles the `.dark` class for you based on `mode`:
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
<ThemeProvider defaultMode="system">{children}</ThemeProvider>
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
To let users override:
|
|
519
|
+
|
|
520
|
+
```tsx
|
|
521
|
+
const { mode, setMode } = useTheme();
|
|
522
|
+
// setMode("light" | "dark" | "system")
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
The library persists the choice to `localStorage` under `px-ui-theme` (configurable via `storageKey` on `ThemeProvider`).
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
## 9. Removed / replaced APIs
|
|
530
|
+
|
|
531
|
+
| Removed | Use instead |
|
|
532
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
533
|
+
| `useToaster()` hook | `toast.success("…")` / `toast.error("…")` from `sonner`-backed `toast` export. |
|
|
534
|
+
| `useCustomTheme()` | `useTheme()` for theme/mode state, Tailwind classes for color tokens. |
|
|
535
|
+
| `withTheme` HOC | Wrap app in `<ThemeProvider>`. |
|
|
536
|
+
| `loadingType`/`loadingContext` props on Table | `isLoading` + `loadingRowCount` (skeleton rows). |
|
|
537
|
+
| `colorScheme` on Button | `variant` (`default` / `secondary` / `outline` / `ghost` / `destructive` / `link`). |
|
|
538
|
+
| Chakra-style `as` prop | `asChild` (Radix Slot) on Button and a few others; otherwise just render the right element. |
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## 10. Storybook
|
|
543
|
+
|
|
544
|
+
The repo ships a Storybook 8 setup ([.storybook/main.ts](.storybook/main.ts), [.storybook/preview.tsx](.storybook/preview.tsx)) wired to the v3 `ThemeProvider`. The toolbar offers two controls driven by Storybook globals:
|
|
545
|
+
|
|
546
|
+
- **Mode** — Light / Dark / System (drives `setMode` on the in-story `ThemeProvider`).
|
|
547
|
+
- **Theme** — 7 presets (drives `setTheme`).
|
|
548
|
+
|
|
549
|
+
Run with `npm run storybook` → http://localhost:6006.
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## 11. Common gotchas
|
|
554
|
+
|
|
555
|
+
- **`useTheme()` outside `ThemeProvider`** throws. Always mount the provider at app root (including in tests — wrap with `<ThemeProvider>` in your render helper).
|
|
556
|
+
- **CSS variables not visible** — make sure `tokens.css` is imported *before* component render. If colors look wrong/transparent, the variables aren't defined.
|
|
557
|
+
- **Dark mode doesn't kick in** — confirm Tailwind config has `darkMode: "class"` (not `"media"`), and the html element gets `.dark` (DevTools → Elements pane).
|
|
558
|
+
- **Boolean Chakra props** — Chakra used `isOpen`, `isDisabled`, `isLoading`. The new components mostly keep the `is*` form on form components for consistency (`isDisabled`, `isReadOnly`, `isRequired`), but Radix-derived primitives use the standard React names (`disabled`, `open`, `onOpenChange`). When in doubt, check the component's TypeScript props in your editor.
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
Questions or migration friction? Open an issue or ping `#design-system` in Slack.
|