vxui-re 1.0.2

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 (173) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +159 -0
  3. package/README.zh.md +159 -0
  4. package/dist/.assetsignore +2 -0
  5. package/dist/404.html +18 -0
  6. package/dist/colorful_flat_icon.ico +0 -0
  7. package/dist/colorful_flat_icon.svg +46 -0
  8. package/dist/index.cjs +144 -0
  9. package/dist/index.css +1 -0
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.js +13289 -0
  12. package/dist/src/components/Accordion.d.ts +14 -0
  13. package/dist/src/components/Alert.d.ts +10 -0
  14. package/dist/src/components/AppShell.d.ts +33 -0
  15. package/dist/src/components/Article.d.ts +72 -0
  16. package/dist/src/components/Avatar.d.ts +12 -0
  17. package/dist/src/components/Badge.d.ts +7 -0
  18. package/dist/src/components/Breadcrumb.d.ts +12 -0
  19. package/dist/src/components/Button.d.ts +18 -0
  20. package/dist/src/components/Calendar.d.ts +10 -0
  21. package/dist/src/components/Card.d.ts +17 -0
  22. package/dist/src/components/Carousel.d.ts +15 -0
  23. package/dist/src/components/Checkbox.d.ts +7 -0
  24. package/dist/src/components/CodeBlock.d.ts +9 -0
  25. package/dist/src/components/ColorPicker.d.ts +13 -0
  26. package/dist/src/components/CommandPalette.d.ts +22 -0
  27. package/dist/src/components/ContextMenu.d.ts +20 -0
  28. package/dist/src/components/DatePicker.d.ts +15 -0
  29. package/dist/src/components/Descriptions.d.ts +29 -0
  30. package/dist/src/components/Dialog.d.ts +49 -0
  31. package/dist/src/components/DropdownMenu.d.ts +55 -0
  32. package/dist/src/components/EmptyState.d.ts +9 -0
  33. package/dist/src/components/FileUpload.d.ts +17 -0
  34. package/dist/src/components/Form.d.ts +28 -0
  35. package/dist/src/components/Heading.d.ts +13 -0
  36. package/dist/src/components/HoverCard.d.ts +11 -0
  37. package/dist/src/components/Image.d.ts +30 -0
  38. package/dist/src/components/Input.d.ts +18 -0
  39. package/dist/src/components/Label.d.ts +5 -0
  40. package/dist/src/components/LanguageSwitcher.d.ts +9 -0
  41. package/dist/src/components/Menubar.d.ts +24 -0
  42. package/dist/src/components/MultiSelect.d.ts +27 -0
  43. package/dist/src/components/NavigationMenu.d.ts +20 -0
  44. package/dist/src/components/Notification.d.ts +30 -0
  45. package/dist/src/components/NumberInput.d.ts +12 -0
  46. package/dist/src/components/Pagination.d.ts +9 -0
  47. package/dist/src/components/PinInput.d.ts +37 -0
  48. package/dist/src/components/Popover.d.ts +13 -0
  49. package/dist/src/components/Progress.d.ts +11 -0
  50. package/dist/src/components/Radio.d.ts +12 -0
  51. package/dist/src/components/Rating.d.ts +14 -0
  52. package/dist/src/components/Resizable.d.ts +35 -0
  53. package/dist/src/components/Responsive.d.ts +25 -0
  54. package/dist/src/components/Result.d.ts +18 -0
  55. package/dist/src/components/ScrollArea.d.ts +21 -0
  56. package/dist/src/components/SegmentedControl.d.ts +16 -0
  57. package/dist/src/components/Select.d.ts +31 -0
  58. package/dist/src/components/Separator.d.ts +6 -0
  59. package/dist/src/components/Sheet/Sheet.d.ts +30 -0
  60. package/dist/src/components/Sheet/SheetPanel.d.ts +44 -0
  61. package/dist/src/components/Sheet/index.d.ts +2 -0
  62. package/dist/src/components/Sheet/useSheetState.d.ts +34 -0
  63. package/dist/src/components/Shell.d.ts +88 -0
  64. package/dist/src/components/Skeleton.d.ts +8 -0
  65. package/dist/src/components/Slider.d.ts +7 -0
  66. package/dist/src/components/Spinner.d.ts +8 -0
  67. package/dist/src/components/Stepper.d.ts +14 -0
  68. package/dist/src/components/Switch.d.ts +7 -0
  69. package/dist/src/components/Table.d.ts +90 -0
  70. package/dist/src/components/Tabs.d.ts +5 -0
  71. package/dist/src/components/TagInput.d.ts +18 -0
  72. package/dist/src/components/Text.d.ts +14 -0
  73. package/dist/src/components/Textarea.d.ts +7 -0
  74. package/dist/src/components/ThemeProvider.d.ts +51 -0
  75. package/dist/src/components/TimePicker.d.ts +14 -0
  76. package/dist/src/components/Timeline.d.ts +14 -0
  77. package/dist/src/components/Toast.d.ts +15 -0
  78. package/dist/src/components/Toggle.d.ts +24 -0
  79. package/dist/src/components/Tooltip.d.ts +11 -0
  80. package/dist/src/components/TreeView.d.ts +20 -0
  81. package/dist/src/components/__tests__/Accordion.test.d.ts +1 -0
  82. package/dist/src/components/__tests__/ActionSheet.test.d.ts +1 -0
  83. package/dist/src/components/__tests__/Alert.test.d.ts +1 -0
  84. package/dist/src/components/__tests__/AlertDialog.test.d.ts +1 -0
  85. package/dist/src/components/__tests__/AppShell.test.d.ts +1 -0
  86. package/dist/src/components/__tests__/Avatar.test.d.ts +1 -0
  87. package/dist/src/components/__tests__/Badge.test.d.ts +1 -0
  88. package/dist/src/components/__tests__/BottomNav.test.d.ts +1 -0
  89. package/dist/src/components/__tests__/Breadcrumb.test.d.ts +1 -0
  90. package/dist/src/components/__tests__/Button.test.d.ts +1 -0
  91. package/dist/src/components/__tests__/Calendar.test.d.ts +1 -0
  92. package/dist/src/components/__tests__/Card.test.d.ts +1 -0
  93. package/dist/src/components/__tests__/Carousel.test.d.ts +1 -0
  94. package/dist/src/components/__tests__/Checkbox.test.d.ts +1 -0
  95. package/dist/src/components/__tests__/CodeBlock.test.d.ts +1 -0
  96. package/dist/src/components/__tests__/ColorPicker.test.d.ts +1 -0
  97. package/dist/src/components/__tests__/CommandPalette.test.d.ts +1 -0
  98. package/dist/src/components/__tests__/ContextMenu.test.d.ts +1 -0
  99. package/dist/src/components/__tests__/DatePicker.test.d.ts +1 -0
  100. package/dist/src/components/__tests__/Dialog.test.d.ts +1 -0
  101. package/dist/src/components/__tests__/DialogFormControls.test.d.ts +1 -0
  102. package/dist/src/components/__tests__/DropdownMenu.test.d.ts +1 -0
  103. package/dist/src/components/__tests__/EmptyState.test.d.ts +1 -0
  104. package/dist/src/components/__tests__/FileUpload.test.d.ts +1 -0
  105. package/dist/src/components/__tests__/Form.test.d.ts +1 -0
  106. package/dist/src/components/__tests__/Heading.test.d.ts +1 -0
  107. package/dist/src/components/__tests__/HoverCard.test.d.ts +1 -0
  108. package/dist/src/components/__tests__/Input.test.d.ts +1 -0
  109. package/dist/src/components/__tests__/Label.test.d.ts +1 -0
  110. package/dist/src/components/__tests__/LanguageSwitcher.test.d.ts +1 -0
  111. package/dist/src/components/__tests__/Menubar.test.d.ts +1 -0
  112. package/dist/src/components/__tests__/MobileDrawer.test.d.ts +1 -0
  113. package/dist/src/components/__tests__/MobileList.test.d.ts +1 -0
  114. package/dist/src/components/__tests__/MultiSelect.test.d.ts +1 -0
  115. package/dist/src/components/__tests__/NavigationMenu.test.d.ts +1 -0
  116. package/dist/src/components/__tests__/NumberInput.test.d.ts +1 -0
  117. package/dist/src/components/__tests__/Pagination.test.d.ts +1 -0
  118. package/dist/src/components/__tests__/Popover.test.d.ts +1 -0
  119. package/dist/src/components/__tests__/Progress.test.d.ts +1 -0
  120. package/dist/src/components/__tests__/Radio.test.d.ts +1 -0
  121. package/dist/src/components/__tests__/Rating.test.d.ts +1 -0
  122. package/dist/src/components/__tests__/Resizable.test.d.ts +1 -0
  123. package/dist/src/components/__tests__/Responsive.test.d.ts +1 -0
  124. package/dist/src/components/__tests__/ScrollArea.test.d.ts +1 -0
  125. package/dist/src/components/__tests__/SegmentedControl.test.d.ts +1 -0
  126. package/dist/src/components/__tests__/Select.test.d.ts +1 -0
  127. package/dist/src/components/__tests__/Separator.test.d.ts +1 -0
  128. package/dist/src/components/__tests__/Sheet.test.d.ts +1 -0
  129. package/dist/src/components/__tests__/Shell.test.d.ts +1 -0
  130. package/dist/src/components/__tests__/Skeleton.test.d.ts +1 -0
  131. package/dist/src/components/__tests__/Slider.test.d.ts +1 -0
  132. package/dist/src/components/__tests__/Spinner.test.d.ts +1 -0
  133. package/dist/src/components/__tests__/Stepper.test.d.ts +1 -0
  134. package/dist/src/components/__tests__/Switch.test.d.ts +1 -0
  135. package/dist/src/components/__tests__/Table.test.d.ts +1 -0
  136. package/dist/src/components/__tests__/Tabs.test.d.ts +1 -0
  137. package/dist/src/components/__tests__/TagInput.test.d.ts +1 -0
  138. package/dist/src/components/__tests__/Text.test.d.ts +1 -0
  139. package/dist/src/components/__tests__/Textarea.test.d.ts +1 -0
  140. package/dist/src/components/__tests__/ThemeProvider.test.d.ts +1 -0
  141. package/dist/src/components/__tests__/TimePicker.test.d.ts +1 -0
  142. package/dist/src/components/__tests__/Timeline.test.d.ts +1 -0
  143. package/dist/src/components/__tests__/Toast.test.d.ts +1 -0
  144. package/dist/src/components/__tests__/Toggle.test.d.ts +1 -0
  145. package/dist/src/components/__tests__/Tooltip.test.d.ts +1 -0
  146. package/dist/src/components/__tests__/TreeView.test.d.ts +1 -0
  147. package/dist/src/components/mobile/ActionSheet.d.ts +15 -0
  148. package/dist/src/components/mobile/BottomNav.d.ts +23 -0
  149. package/dist/src/components/mobile/MobileApp.d.ts +1 -0
  150. package/dist/src/components/mobile/MobileDrawer.d.ts +31 -0
  151. package/dist/src/components/mobile/MobileList.d.ts +24 -0
  152. package/dist/src/components/mobile/MobilePreviewPage.d.ts +5 -0
  153. package/dist/src/components/mobile/MobileShell.d.ts +24 -0
  154. package/dist/src/components/pages/ErrorPage.d.ts +9 -0
  155. package/dist/src/components/pages/HomePage.d.ts +10 -0
  156. package/dist/src/components/pages/LoginPage.d.ts +12 -0
  157. package/dist/src/components/pages/PrivacyPolicyPage.d.ts +5 -0
  158. package/dist/src/components/pages/RegisterPage.d.ts +14 -0
  159. package/dist/src/components/pages/TermsOfServicePage.d.ts +5 -0
  160. package/dist/src/components/pages/homePageContent.d.ts +25 -0
  161. package/dist/src/components/pages/legalPageContent.d.ts +15 -0
  162. package/dist/src/lib/VXUIProvider.d.ts +29 -0
  163. package/dist/src/lib/__tests__/cx.test.d.ts +1 -0
  164. package/dist/src/lib/__tests__/viewport.test.d.ts +1 -0
  165. package/dist/src/lib/breakpoints.d.ts +63 -0
  166. package/dist/src/lib/cx.d.ts +1 -0
  167. package/dist/src/lib/dialogPopover.d.ts +30 -0
  168. package/dist/src/lib/index.d.ts +152 -0
  169. package/dist/src/lib/version.d.ts +1 -0
  170. package/dist/src/lib/viewport.d.ts +21 -0
  171. package/dist/wrangler.json +1 -0
  172. package/llms.txt +672 -0
  173. package/package.json +86 -0
package/llms.txt ADDED
@@ -0,0 +1,672 @@
1
+ # VXUI 2
2
+
3
+ > A pure-CSS, React UI component library for building admin dashboards and operator interfaces. v1.0.0.
4
+
5
+ > ℹ️ This file (`llms.txt`) is included in the npm package. AI tools can read it directly to obtain component documentation and usage guides.
6
+
7
+ VXUI 2 provides layout shells, navigation, form controls, data display, overlays, and mobile components. It relies solely on CSS custom properties (design tokens) for theming — no Tailwind, no CSS-in-JS. Radix UI primitives are used for accessibility-critical components (dialogs, menus, tooltips, etc.).
8
+
9
+ > **Security**: 1.0.0 is a clean release after removing a supply-chain attack vector discovered in git history. The package name was changed from `vxui-re` to `vxui-re`.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install vxui-re
15
+ ```
16
+
17
+ Import the base stylesheet once at your app entry:
18
+
19
+ ```tsx
20
+ import 'vxui-re/styles';
21
+ ```
22
+
23
+ ## Core Layout: AppShell
24
+
25
+ `AppShell` is the top-level layout component. It composes a collapsible sidebar, sticky topbar, and scrollable content area.
26
+
27
+ ```tsx
28
+ import { AppShell } from 'vxui-re';
29
+
30
+ <AppShell
31
+ brand="My App"
32
+ brandIcon={<img src="/logo.svg" alt="" />}
33
+ title="Dashboard"
34
+ navSections={[
35
+ {
36
+ key: 'main',
37
+ items: [
38
+ { key: 'home', label: 'Home', icon: <HomeIcon />, href: '/' },
39
+ { key: 'reports', label: 'Reports', icon: <ChartIcon />, href: '/reports' },
40
+ ],
41
+ },
42
+ ]}
43
+ headerActions={<UserMenu />}
44
+ sidebarWidth={280}
45
+ >
46
+ <p>Page content</p>
47
+ </AppShell>
48
+ ```
49
+
50
+ ### AppShell Props
51
+
52
+ | Prop | Type | Default | Description |
53
+ |------|------|---------|-------------|
54
+ | brand | string | "VXUI" | Brand/product name shown in the sidebar header |
55
+ | brandCaption | string | — | Secondary subtitle below the brand name |
56
+ | brandIcon | ReactNode | — | Logo element rendered in the sidebar header |
57
+ | title | string | — | Page title shown in the topbar |
58
+ | description | string | — | Page subtitle shown below the topbar title |
59
+ | breadcrumb | ReactNode | — | Breadcrumb element rendered in the topbar |
60
+ | navSections | AppShellNavSection[] | — | Structured nav tree grouped by sections. Preferred over navItems |
61
+ | navItems | AppShellNavItem[] | — | Flat nav list, auto-wrapped in a single unnamed section |
62
+ | sidebarCollapsed | boolean | false | Collapse sidebar to icon-only rail mode |
63
+ | sidebarWidth | number \| string | 240px | Custom sidebar width. Number = px (e.g. 280), string = CSS value (e.g. "18rem") |
64
+ | density | "comfortable" \| "compact" | — | Layout density. "compact" tightens vertical rhythm for high-density UIs |
65
+ | headerActions | ReactNode | — | Slot for right-aligned topbar actions |
66
+ | sidebarFooter | ReactNode | — | Slot rendered at the bottom of the sidebar |
67
+ | mobileNavOpen | boolean | false | Controls whether the mobile nav overlay is visible |
68
+ | onSidebarToggle | () => void | — | Called when the collapse/expand button is clicked |
69
+ | onMobileNavToggle | () => void | — | Called when the mobile overlay toggle is clicked |
70
+ | children | ReactNode | **required** | Main content area rendered inside ShellContent |
71
+
72
+ ### AppShellNavSection
73
+
74
+ ```ts
75
+ interface AppShellNavSection {
76
+ key: string;
77
+ label?: string; // section heading text
78
+ items: AppShellNavItem[];
79
+ }
80
+ ```
81
+
82
+ ### AppShellNavItem
83
+
84
+ ```ts
85
+ interface AppShellNavItem {
86
+ key: string;
87
+ label: string;
88
+ icon?: ReactNode;
89
+ href?: string;
90
+ active?: boolean;
91
+ disabled?: boolean;
92
+ defaultOpen?: boolean; // for expandable items with children
93
+ children?: AppShellNavItem[]; // nest to create expandable sub-menus
94
+ onClick?: (e: React.MouseEvent) => void;
95
+ }
96
+ ```
97
+
98
+ ## Shell (low-level)
99
+
100
+ `Shell` is the underlying layout primitive used by AppShell. Use it for fully custom layouts.
101
+
102
+ ```tsx
103
+ import { Shell, ShellSidebar, ShellContent } from 'vxui-re';
104
+
105
+ <Shell sidebarWidth={300} density="compact">
106
+ <ShellSidebar>{/* nav content */}</ShellSidebar>
107
+ <ShellContent>{/* page content */}</ShellContent>
108
+ </Shell>
109
+ ```
110
+
111
+ ### Shell Props
112
+
113
+ | Prop | Type | Default | Description |
114
+ |------|------|---------|-------------|
115
+ | collapsed | boolean | false | Collapse sidebar to rail mode |
116
+ | mobileNavOpen | boolean | false | Show mobile nav overlay |
117
+ | density | "comfortable" \| "compact" | — | Layout density |
118
+ | sidebarWidth | number \| string | 240px | Custom sidebar width |
119
+ | className | string | — | Additional CSS class |
120
+ | children | ReactNode | **required** | Layout children |
121
+
122
+ ## Dialog
123
+
124
+ Modal dialog component built on Radix UI. Supports size presets, placement options, and fullscreen mode for mobile devices.
125
+
126
+ ```tsx
127
+ import { Dialog, DialogClose } from 'vxui-re';
128
+ import { Button } from 'vxui-re';
129
+
130
+ <Dialog
131
+ trigger={<Button>Open Dialog</Button>}
132
+ title="Dialog Title"
133
+ description="Optional description text."
134
+ size="md" // 'sm' | 'md' | 'lg' | 'xl' | 'full'
135
+ placement="center" // 'center' | 'top' | 'bottom' | etc.
136
+ fullscreen={false} // Enable fullscreen on mobile devices
137
+ scrollable={true}
138
+ closable={true}
139
+ >
140
+ <p>Dialog content goes here.</p>
141
+ {{/* footer */}}
142
+ <DialogClose asChild><Button variant="outline">Close</Button></DialogClose>
143
+ </Dialog>
144
+ ```
145
+
146
+ ### Dialog Props
147
+
148
+ | Prop | Type | Default | Description |
149
+ |------|------|---------|-------------|
150
+ | trigger | ReactNode | **required** | Element that opens the dialog |
151
+ | title | string | **required** | Dialog title |
152
+ | description | string | — | Optional description below the title |
153
+ | children | ReactNode | **required** | Dialog body content |
154
+ | footer | ReactNode | — | Footer content (e.g., action buttons) |
155
+ | size | 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full' | 'md' | Width preset |
156
+ | placement | 'center' \| 'top' \| 'right' \| 'bottom' \| 'left' \| 'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right' \| 'top-half' \| 'right-half' \| 'bottom-half' \| 'left-half' | 'center' | Position on screen (desktop only) |
157
+ | padding | 'none' \| 'sm' \| 'md' \| 'lg' | 'md' | Inner padding preset |
158
+ | scrollable | boolean | true | Enable body scroll when content overflows |
159
+ | closable | boolean | true | Show the close (×) button |
160
+ | fullscreen | boolean | false | When true, the dialog occupies the full viewport (ideal for mobile) |
161
+ | className | string | — | Additional CSS class |
162
+ | defaultOpen | boolean | false | Whether the dialog is open by default |
163
+ | open | boolean | — | Controlled open state |
164
+ | onOpenChange | (open: boolean) => void | — | Open state change handler |
165
+ | onConfirm | () => void | — | Callback when confirm button is clicked; enables confirm/cancel footer |
166
+ | onCancel | () => void | — | Callback when cancel button is clicked |
167
+ | confirmLabel | string | "Confirm" | Label for the confirm button |
168
+ | cancelLabel | string | "Cancel" | Label for the cancel button |
169
+ | confirmVariant | 'solid' \| 'danger' | 'solid' | Visual variant of the confirm button |
170
+
171
+ ## Component Index
172
+
173
+ ### Layout & Navigation
174
+ - **AppShell** — Full-featured app shell with sidebar, topbar, and content area
175
+ - **Shell / ShellSidebar / ShellContent** — Low-level layout primitives
176
+ - **NavigationMenu** — Horizontal navigation bar with dropdown menus
177
+ - **Breadcrumb** — Breadcrumb trail with separator support
178
+ - **Pagination** — Page navigation with first/last/prev/next controls
179
+ - **Tabs** — Horizontal tab strip with panel content
180
+ - **Menubar** — Desktop-style menu bar
181
+ - **Stepper** — Multi-step wizard indicator
182
+
183
+ ### Buttons & Actions
184
+ - **Button** — Primary action button with variants (default, outline, ghost, destructive) and sizes (sm, md, lg)
185
+ - **Toggle** — Two-state toggle button
186
+ - **SegmentedControl** — Mutually exclusive option group
187
+ - **DropdownMenu** — Trigger + popover menu list (Radix UI)
188
+ - **ContextMenu** — Right-click context menu (Radix UI)
189
+
190
+ ### Forms & Inputs
191
+ - **Input** — Text input with label, error, and description support
192
+ - **Textarea** — Multi-line text input
193
+ - **Checkbox** — Single checkbox or checkbox group
194
+ - **Radio** — Radio button group
195
+ - **Switch** — Toggle switch
196
+ - **Slider** — Range slider
197
+ - **NumberInput** — Numeric input with increment/decrement controls
198
+ - **TagInput** — Multi-tag token input
199
+ - **Rating** — Star rating input
200
+ - **DatePicker** — Calendar-based date picker
201
+ - **ColorPicker** — Color swatch/hex picker
202
+ - **Select** — Searchable single-select dropdown with custom overlay behavior; supports ReactNode labels with searchLabel for custom UI
203
+ - **MultiSelect** — Searchable multi-select with tag display, "+N more" badge; supports ReactNode labels with searchLabel for custom UI
204
+ - **PinInput** — PIN / OTP code input with auto-advance, paste support, and mask mode
205
+ - **TimePicker** — Time selection with hours, minutes, and optional seconds columns
206
+ - **Form** — Form wrapper with validation helpers
207
+
208
+ ### Overlays & Popovers
209
+ - **Dialog** — Modal dialog (Radix UI)
210
+ - **Sheet** — Slide-in panel (drawer) from any edge
211
+ - **Popover** — Floating content anchored to a trigger (Radix UI)
212
+ - **Tooltip** — Short contextual hover label (Radix UI)
213
+ - **HoverCard** — Rich hover preview card (Radix UI)
214
+
215
+ ### Feedback & Status
216
+ - **Toast** — Ephemeral notification (info / success / warning / danger tones)
217
+ - **Notification** — Global notification stack with provider/hook pattern, auto-dismiss, and placement options
218
+ - **Alert** — Inline alert banner (info / success / warning / danger)
219
+ - **Progress** — Linear progress bar (determinate and indeterminate)
220
+ - **Spinner** — Loading spinner
221
+ - **Skeleton** — Placeholder loading skeleton
222
+
223
+ ### Data Display
224
+ - **Descriptions** — Key-value pair display in horizontal/vertical table layout
225
+ - **Table** — Sortable, filterable data table with horizontal scroll on mobile, sticky filter bar, and search; supports searchValue for ReactNode cells
226
+ - **Badge** — Inline status label with tone variants
227
+ - **Avatar** — User avatar with fallback initials
228
+ - **Card** — Content container card
229
+ - **Accordion** — Collapsible content sections (Radix UI)
230
+ - **Calendar** — Month calendar view
231
+ - **Image** — Lazy-loading image with placeholder, fallback, radius presets, and click-to-preview lightbox
232
+ - **Carousel** — Horizontal content carousel
233
+ - **TreeView** — Hierarchical tree list
234
+ - **Timeline** — Vertical timeline list
235
+ - **ScrollArea** — Custom-styled scrollable container (Radix UI)
236
+ - **Resizable** — Resizable panel layout
237
+
238
+ ### Utility
239
+ - **CodeBlock** — Syntax-highlighted code block (Prism.js)
240
+ - **CommandPalette** — Global keyboard command search
241
+ - **Result** — Status result page with icon, title, description, and actions (success / error / warning / info / forbidden / not-found / server-error)
242
+ - **EmptyState** — Empty content placeholder with action
243
+ - **FileUpload** — Drag-and-drop file upload area
244
+ - **LanguageSwitcher** — Locale toggle button
245
+ - **ThemeProvider** — Theme context provider with light/dark mode, custom token overrides, and localStorage persistence
246
+ - **Responsive** — Conditional rendering based on viewport breakpoint (desktop / tablet / mobile)
247
+ - **Article** — Structured article layout with header, body, sections, props table, pager, and stats grid
248
+ - **Separator** — Horizontal or vertical rule
249
+ - **Heading / Text / Label** — Typography primitives
250
+
251
+ ### Mobile-specific (vxui-re/mobile)
252
+ - **MobileApp** — Root mobile layout
253
+ - **MobileShell** — Mobile screen wrapper
254
+ - **MobileDrawer** — Bottom-sheet style drawer
255
+ - **BottomNav** — Mobile tab bar
256
+ - **MobileList** — List with dividers optimized for touch
257
+ - **ActionSheet** — iOS-style action sheet
258
+
259
+ ## Theming (CSS Custom Properties)
260
+
261
+ Override any token in your own stylesheet or via a `<style>` block:
262
+
263
+ ```css
264
+ :root {
265
+ --vx-primary: #7c3aed; /* primary action color */
266
+ --vx-primary-strong: #6d28d9; /* hover/pressed state */
267
+ --vx-primary-soft: rgba(124, 58, 237, 0.1);
268
+
269
+ --vx-secondary: #64748b; /* secondary/muted color */
270
+ --vx-success: #10b981;
271
+ --vx-warning: #f59e0b;
272
+ --vx-danger: #ef4444;
273
+
274
+ --vx-bg: #f8fafc; /* page background */
275
+ --vx-bg-accent: #f1f5f9; /* subtle accent background */
276
+ --vx-surface: #ffffff; /* card/panel surfaces */
277
+ --vx-border: #e2e8f0; /* default border */
278
+ --vx-border-strong: #cbd5e1;
279
+
280
+ --vx-text: #0f172a; /* primary text */
281
+ --vx-text-secondary: #64748b;
282
+ --vx-text-muted: #94a3b8;
283
+
284
+ --vx-radius-sm: 8px;
285
+ --vx-radius: 10px;
286
+ --vx-radius-lg: 14px;
287
+
288
+ --vx-sidebar-width: 240px; /* sidebar width (default) */
289
+ --vx-sidebar-width-collapsed: 72px;
290
+ --vx-header-height: 92px;
291
+ }
292
+ ```
293
+
294
+ Dark mode tokens are applied automatically when `<html>` has `class="dark"` or `data-theme="dark"`.
295
+
296
+ ## Key Design Principles
297
+
298
+ 1. **No global side-effects** — CSS is scoped to `.vx-*` class names. VXUI will not override your existing styles.
299
+ 2. **Token-first theming** — All visual decisions (color, radius, spacing) are CSS variables. Override any of them to rebrand in minutes.
300
+ 3. **Accessible by default** — Overlay and interactive components are built on Radix UI primitives, providing keyboard navigation and ARIA semantics out of the box.
301
+ 4. **Mobile-first responsive** — Sidebar collapses to an overlay on narrow viewports. Mobile-specific components live in a separate import path.
302
+ 5. **No runtime CSS injection** — Styles ship as a single static stylesheet. No flash-of-unstyled-content from runtime injection.
303
+
304
+ ## Descriptions
305
+
306
+ Display key-value pairs in a structured table layout. Supports horizontal (label left, value right) and vertical (label top, value bottom) modes.
307
+
308
+ ```tsx
309
+ import { Descriptions } from 'vxui-re';
310
+
311
+ <Descriptions
312
+ title="User Info"
313
+ layout="horizontal"
314
+ column={3}
315
+ size="md"
316
+ bordered
317
+ items={[
318
+ { label: 'Name', children: 'Alice' },
319
+ { label: 'Email', children: 'alice@example.com' },
320
+ { label: 'Role', children: 'Admin', span: 1 },
321
+ ]}
322
+ />
323
+ ```
324
+
325
+ ### Descriptions Props
326
+
327
+ | Prop | Type | Default | Description |
328
+ |------|------|---------|-------------|
329
+ | items | DescriptionsItem[] | **required** | List of description items |
330
+ | layout | 'horizontal' \| 'vertical' | 'horizontal' | Layout direction |
331
+ | column | number | 3 (h) / 1 (v) | Number of columns per row |
332
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | Size preset controlling spacing and font-size |
333
+ | bordered | boolean | true | Show border around the descriptions |
334
+ | title | ReactNode | — | Title shown above the descriptions |
335
+ | extra | ReactNode | — | Extra content rendered next to the title |
336
+
337
+ ## Image
338
+
339
+ Lazy-loading image component with placeholder, error fallback, radius presets, and optional click-to-preview lightbox.
340
+
341
+ ```tsx
342
+ import { Image } from 'vxui-re';
343
+
344
+ <Image
345
+ src="/photo.jpg"
346
+ alt="Landscape"
347
+ width={400}
348
+ height={300}
349
+ radius="md"
350
+ fit="cover"
351
+ preview
352
+ caption="A beautiful landscape"
353
+ />
354
+ ```
355
+
356
+ ### Image Props
357
+
358
+ | Prop | Type | Default | Description |
359
+ |------|------|---------|-------------|
360
+ | src | string | **required** | Image source URL |
361
+ | alt | string | '' | Alt text |
362
+ | width | string \| number | — | Fixed width (CSS value or px number) |
363
+ | height | string \| number | — | Fixed height (CSS value or px number) |
364
+ | radius | 'none' \| 'sm' \| 'md' \| 'lg' \| 'full' | 'md' | Border radius preset |
365
+ | fit | 'cover' \| 'contain' \| 'fill' \| 'none' | 'cover' | CSS object-fit value |
366
+ | lazy | boolean | true | Enable lazy loading via IntersectionObserver |
367
+ | placeholder | ReactNode | — | Content shown while loading |
368
+ | fallback | ReactNode | — | Content shown on error |
369
+ | preview | boolean | false | Enable click-to-preview lightbox |
370
+ | caption | ReactNode | — | Caption text below the image |
371
+
372
+ ## Notification
373
+
374
+ Global notification system using provider/hook pattern. Notifications stack in a fixed position with auto-dismiss and manual dismiss support.
375
+
376
+ ```tsx
377
+ import { NotificationProvider, useNotification } from 'vxui-re';
378
+
379
+ function App() {
380
+ return (
381
+ <NotificationProvider placement="top-right" maxCount={5}>
382
+ <MyApp />
383
+ </NotificationProvider>
384
+ );
385
+ }
386
+
387
+ function MyApp() {
388
+ const { push, dismiss, clear } = useNotification();
389
+ return (
390
+ <button onClick={() => push({ title: 'Saved', description: 'Changes saved.', tone: 'success', duration: 3000 })}>
391
+ Save
392
+ </button>
393
+ );
394
+ }
395
+ ```
396
+
397
+ ### NotificationProvider Props
398
+
399
+ | Prop | Type | Default | Description |
400
+ |------|------|---------|-------------|
401
+ | children | ReactNode | **required** | App content |
402
+ | placement | 'top-right' \| 'top-left' \| 'top-center' \| 'bottom-right' \| 'bottom-left' \| 'bottom-center' | 'top-right' | Placement of the notification stack |
403
+ | maxCount | number | 5 | Maximum number of visible notifications |
404
+
405
+ ### useNotification() API
406
+
407
+ | Method | Signature | Description |
408
+ |--------|-----------|-------------|
409
+ | push | (notification: NotificationInput) => number | Push a notification, returns its id |
410
+ | dismiss | (id: number) => void | Dismiss a notification by id |
411
+ | clear | () => void | Dismiss all notifications |
412
+
413
+ ### NotificationInput
414
+
415
+ ```ts
416
+ interface NotificationInput {
417
+ title: string;
418
+ description?: string;
419
+ tone?: 'info' | 'success' | 'warning' | 'danger';
420
+ duration?: number; // auto-dismiss ms; 0 = persistent
421
+ action?: ReactNode; // custom action node
422
+ }
423
+ ```
424
+
425
+ ## PinInput
426
+
427
+ PIN / OTP code input with auto-advance, paste support, numeric/alphanumeric modes, and optional mask.
428
+
429
+ ```tsx
430
+ import { PinInput } from 'vxui-re';
431
+
432
+ <PinInput
433
+ length={6}
434
+ type="numeric"
435
+ size="md"
436
+ mask={false}
437
+ label="Verification Code"
438
+ onComplete={(value) => console.log('Code:', value)}
439
+ />
440
+ ```
441
+
442
+ ### PinInput Props
443
+
444
+ | Prop | Type | Default | Description |
445
+ |------|------|---------|-------------|
446
+ | length | number | 6 | Number of input fields |
447
+ | value | string | — | Controlled value |
448
+ | defaultValue | string | '' | Default value for uncontrolled mode |
449
+ | onChange | (value: string) => void | — | Callback on value change |
450
+ | onComplete | (value: string) => void | — | Callback when all fields are filled |
451
+ | type | 'numeric' \| 'alphanumeric' | 'numeric' | Input type |
452
+ | size | 'sm' \| 'md' \| 'lg' | 'md' | Size preset |
453
+ | placeholder | string | '○' | Placeholder character in empty fields |
454
+ | disabled | boolean | false | Disable all inputs |
455
+ | error | string | — | Error message |
456
+ | label | string | — | Label above the input group |
457
+ | hint | string | — | Hint text below the input group |
458
+ | mask | boolean | false | Mask input (show dots) |
459
+ | autoFocus | boolean | false | Auto-focus the first input on mount |
460
+
461
+ ## Result
462
+
463
+ Status result page component for success, error, warning, and other outcomes. Includes default icons per status.
464
+
465
+ ```tsx
466
+ import { Result } from 'vxui-re';
467
+ import { Button } from 'vxui-re';
468
+
469
+ <Result
470
+ status="success"
471
+ title="Order Placed"
472
+ description="Your order has been placed successfully."
473
+ actions={<Button>Continue Shopping</Button>}
474
+ />
475
+ ```
476
+
477
+ ### Result Props
478
+
479
+ | Prop | Type | Default | Description |
480
+ |------|------|---------|-------------|
481
+ | status | 'success' \| 'error' \| 'warning' \| 'info' \| 'forbidden' \| 'not-found' \| 'server-error' | **required** | Pre-built status with default icon and color |
482
+ | title | string | **required** | Title text |
483
+ | description | string | — | Description text below the title |
484
+ | icon | ReactNode | — | Custom icon (overrides the default status icon) |
485
+ | actions | ReactNode | — | Action area: buttons, links, etc. |
486
+ | extra | ReactNode | — | Extra content area below actions |
487
+
488
+ ## MultiSelect
489
+
490
+ Searchable multi-select dropdown with tag display, clearable selection, and a "+N more" badge when tags overflow.
491
+
492
+ ```tsx
493
+ import { MultiSelect } from 'vxui-re';
494
+
495
+ <MultiSelect
496
+ options={[
497
+ { value: 'react', label: 'React' },
498
+ { value: 'vue', label: 'Vue' },
499
+ { value: 'angular', label: 'Angular' },
500
+ ]}
501
+ placeholder="Select frameworks"
502
+ maxDisplay={3}
503
+ onChange={(selected) => console.log(selected)}
504
+ />
505
+ ```
506
+
507
+ ### MultiSelect Props
508
+
509
+ | Prop | Type | Default | Description |
510
+ |------|------|---------|-------------|
511
+ | options | MultiSelectOption[] | **required** | Available options |
512
+ | value | string[] | — | Controlled selected values |
513
+ | defaultValue | string[] | — | Default values for uncontrolled mode |
514
+ | onChange | (value: string[]) => void | — | Callback on selection change |
515
+ | placeholder | string | — | Placeholder text |
516
+ | searchPlaceholder | string | — | Search input placeholder |
517
+ | label | string | — | Label above the select |
518
+ | hint | string | — | Hint text |
519
+ | error | string | — | Error message |
520
+ | disabled | boolean | false | Disable the select |
521
+ | clearable | boolean | — | Show clear button |
522
+ | emptyText | string | — | Text when no options match |
523
+ | maxDisplay | number | — | Max visible tags before "+N more" badge |
524
+
525
+ ## TimePicker
526
+
527
+ Time selection component with hours and minutes columns, optional seconds, and a dropdown overlay.
528
+
529
+ ```tsx
530
+ import { TimePicker } from 'vxui-re';
531
+
532
+ <TimePicker
533
+ label="Meeting Time"
534
+ seconds={false}
535
+ onChange={(value) => console.log('Time:', value)}
536
+ />
537
+ ```
538
+
539
+ ### TimePicker Props
540
+
541
+ | Prop | Type | Default | Description |
542
+ |------|------|---------|-------------|
543
+ | value | string | — | Controlled value (HH:MM or HH:MM:SS) |
544
+ | defaultValue | string | — | Default value for uncontrolled mode |
545
+ | onChange | (value: string) => void | — | Callback on value change |
546
+ | placeholder | string | 'Select time' | Placeholder text |
547
+ | label | string | — | Label above the input |
548
+ | hint | string | — | Hint text |
549
+ | error | string | — | Error message |
550
+ | disabled | boolean | false | Disable the input |
551
+ | seconds | boolean | false | Show seconds column |
552
+
553
+ ## ThemeProvider
554
+
555
+ Theme context provider that manages light/dark mode switching, custom CSS token overrides, and persists the selection to localStorage.
556
+
557
+ ```tsx
558
+ import { ThemeProvider, useTheme, createTheme } from 'vxui-re';
559
+
560
+ const themes = {
561
+ light: createTheme('light', { label: 'Light' }),
562
+ dark: createTheme('dark', { label: 'Dark' }),
563
+ brand: createTheme('light', {
564
+ label: 'Brand',
565
+ tokens: { '--vx-primary': '#7c3aed' },
566
+ }),
567
+ };
568
+
569
+ function App() {
570
+ return (
571
+ <ThemeProvider defaultTheme="light" themes={themes}>
572
+ <MyApp />
573
+ </ThemeProvider>
574
+ );
575
+ }
576
+
577
+ function MyApp() {
578
+ const { theme, setTheme, availableThemes } = useTheme();
579
+ return <select value={theme} onChange={(e) => setTheme(e.target.value)}>...</select>;
580
+ }
581
+ ```
582
+
583
+ ### ThemeProvider Props
584
+
585
+ | Prop | Type | Default | Description |
586
+ |------|------|---------|-------------|
587
+ | children | ReactNode | **required** | App content |
588
+ | defaultTheme | string | 'light' | Default theme name |
589
+ | storageKey | string | 'vxui-re-theme' | localStorage key for persistence |
590
+ | themes | ThemeRegistry | { light, dark } | Registry of named themes |
591
+
592
+ ### useTheme() API
593
+
594
+ | Property | Type | Description |
595
+ |----------|------|-------------|
596
+ | theme | string | Active theme name |
597
+ | setTheme | (name: string) => void | Switch to a named theme |
598
+ | availableThemes | string[] | List of registered theme names |
599
+
600
+ ## Responsive
601
+
602
+ Conditionally render different nodes based on the current viewport breakpoint (desktop ≥1024px, tablet 768–1023px, mobile ≤767px).
603
+
604
+ ```tsx
605
+ import { Responsive } from 'vxui-re';
606
+
607
+ <Responsive
608
+ desktop={<DesktopLayout />}
609
+ tablet={<TabletLayout />}
610
+ mobile={<MobileLayout />}
611
+ />
612
+ ```
613
+
614
+ ### Responsive Props
615
+
616
+ | Prop | Type | Default | Description |
617
+ |------|------|---------|-------------|
618
+ | desktop | ReactNode | **required** | Rendered on desktop (≥1024px) and tablet when tablet is omitted |
619
+ | mobile | ReactNode | **required** | Rendered on phone (≤767px) |
620
+ | tablet | ReactNode | — | Rendered on tablet (768–1023px); falls back to desktop |
621
+
622
+ ## Article
623
+
624
+ Structured article layout component for documentation and long-form content. Includes sub-components for header, title, body, sections, props table, pager navigation, stats grid, and empty states.
625
+
626
+ ```tsx
627
+ import { Article, ArticleHeader, ArticleTitle, ArticleBody, Section, SectionHeading } from 'vxui-re';
628
+
629
+ <Article>
630
+ <ArticleHeader>
631
+ <ArticleTitle>Getting Started</ArticleTitle>
632
+ </ArticleHeader>
633
+ <ArticleBody>
634
+ <Section sectionId="intro">
635
+ <SectionHeading anchor="#intro">Introduction</SectionHeading>
636
+ <p>Welcome to VXUI.</p>
637
+ </Section>
638
+ </ArticleBody>
639
+ </Article>
640
+ ```
641
+
642
+ ### Article Sub-components
643
+
644
+ | Component | Description |
645
+ |-----------|-------------|
646
+ | Article | Root `<article>` wrapper |
647
+ | ArticleHeader | Header area with title and metadata |
648
+ | ArticleTitle | Main `<h1>` title |
649
+ | ArticleBody | Body wrapper with content area |
650
+ | Section | Content section with optional anchor id |
651
+ | SectionHeading | Section `<h2>` heading with optional anchor link |
652
+ | Pager | Previous / Next page navigation |
653
+ | PropsTable | Component props documentation table |
654
+ | StatsGrid | Grid of stat cards with label, value, hint, and icon |
655
+ | ArticleEmptyState | Empty state placeholder for articles |
656
+
657
+ ## File Structure (library source)
658
+
659
+ ```
660
+ src/
661
+ components/ # All React components
662
+ mobile/ # Mobile-specific components
663
+ pages/ # Full-page template components
664
+ styles/
665
+ base.css # All CSS (design tokens + component styles)
666
+ i18n/
667
+ index.tsx # English & Chinese translations
668
+ lib/
669
+ cx.ts # className utility
670
+ version.ts # library version
671
+ VXUIProvider.tsx # top-level provider combining ThemeProvider + i18n
672
+ ```