trust-ui-react 0.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/README.md +654 -0
- package/dist/components/Avatar/Avatar.d.ts +17 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Badge/Badge.d.ts +16 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Button/Button.d.ts +18 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Checkbox/Checkbox.d.ts +22 -0
- package/dist/components/Checkbox/index.d.ts +2 -0
- package/dist/components/Chip/Chip.d.ts +22 -0
- package/dist/components/Chip/index.d.ts +2 -0
- package/dist/components/DatePicker/Calendar.d.ts +20 -0
- package/dist/components/DatePicker/DatePicker.d.ts +36 -0
- package/dist/components/DatePicker/index.d.ts +4 -0
- package/dist/components/DatePicker/utils.d.ts +20 -0
- package/dist/components/DateRangePicker/DateRangePicker.d.ts +45 -0
- package/dist/components/DateRangePicker/index.d.ts +2 -0
- package/dist/components/Dialog/Dialog.d.ts +59 -0
- package/dist/components/Dialog/index.d.ts +2 -0
- package/dist/components/Expander/Expander.d.ts +63 -0
- package/dist/components/Expander/index.d.ts +2 -0
- package/dist/components/Menu/Menu.d.ts +60 -0
- package/dist/components/Menu/index.d.ts +2 -0
- package/dist/components/Pagination/Pagination.d.ts +25 -0
- package/dist/components/Pagination/index.d.ts +2 -0
- package/dist/components/Progress/Progress.d.ts +17 -0
- package/dist/components/Progress/index.d.ts +2 -0
- package/dist/components/Radio/Radio.d.ts +14 -0
- package/dist/components/Radio/RadioContext.d.ts +9 -0
- package/dist/components/Radio/RadioGroup.d.ts +27 -0
- package/dist/components/Radio/index.d.ts +4 -0
- package/dist/components/Select/Select.d.ts +38 -0
- package/dist/components/Select/index.d.ts +2 -0
- package/dist/components/Slider/Slider.d.ts +27 -0
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Switch/Switch.d.ts +21 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Table/Table.d.ts +43 -0
- package/dist/components/Table/index.d.ts +2 -0
- package/dist/components/Tabs/Tabs.d.ts +63 -0
- package/dist/components/Tabs/index.d.ts +2 -0
- package/dist/components/TextField/TextField.d.ts +46 -0
- package/dist/components/TextField/formatters.d.ts +31 -0
- package/dist/components/TextField/index.d.ts +2 -0
- package/dist/components/Toast/Toast.d.ts +24 -0
- package/dist/components/Toast/index.d.ts +2 -0
- package/dist/components/Tooltip/Tooltip.d.ts +21 -0
- package/dist/components/Tooltip/index.d.ts +2 -0
- package/dist/hooks/useTheme.d.ts +2 -0
- package/dist/hooks/useToast.d.ts +2 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.es.js +3029 -0
- package/dist/providers/ThemeProvider.d.ts +14 -0
- package/dist/providers/ToastProvider.d.ts +24 -0
- package/dist/styles.css +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
# trust-ui-react
|
|
2
|
+
|
|
3
|
+
A lightweight, themeable React UI component library built with TypeScript and CSS Modules.
|
|
4
|
+
|
|
5
|
+
`trust-ui-react` provides 21 production-ready components with built-in dark/light mode support, CSS Custom Properties for easy theming, and full TypeScript type definitions. Every component is designed with accessibility in mind and follows consistent API patterns.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **21 ready-to-use components** -- buttons, forms, data display, dialogs, date pickers, and more
|
|
12
|
+
- **Dark / Light mode** -- toggle themes via `data-theme` attribute with `ThemeProvider`
|
|
13
|
+
- **CSS Custom Properties** -- all visual tokens (`--tui-*`) are overridable for full brand customization
|
|
14
|
+
- **TypeScript first** -- every component exports its prop types for a great DX
|
|
15
|
+
- **CSS Modules** -- scoped styles with zero global side effects
|
|
16
|
+
- **Controlled & uncontrolled** -- all form components support both patterns
|
|
17
|
+
- **Compound components** -- Dialog, Tabs, Menu, and Expander use the compound component pattern for maximum flexibility
|
|
18
|
+
- **Auto-formatting inputs** -- TextField supports automatic telephone, currency, and decimal formatting
|
|
19
|
+
- **Lightweight** -- no runtime CSS-in-JS, no heavy dependencies
|
|
20
|
+
- **Dual format** -- ships as ESM and CJS via Vite library mode build
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install trust-ui-react
|
|
28
|
+
# or
|
|
29
|
+
pnpm add trust-ui-react
|
|
30
|
+
# or
|
|
31
|
+
yarn add trust-ui-react
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Peer dependencies
|
|
35
|
+
|
|
36
|
+
React 18 or later is required:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install react react-dom
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
Import the stylesheet **once** at the root of your application, wrap your app with `ThemeProvider` (and optionally `ToastProvider`), then start using components.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { ThemeProvider, ToastProvider, Button } from 'trust-ui-react';
|
|
50
|
+
import 'trust-ui-react/styles.css';
|
|
51
|
+
|
|
52
|
+
function App() {
|
|
53
|
+
return (
|
|
54
|
+
<ThemeProvider defaultTheme="light">
|
|
55
|
+
<ToastProvider position="top-right">
|
|
56
|
+
<main>
|
|
57
|
+
<h1>Hello Trust UI</h1>
|
|
58
|
+
<Button variant="primary" size="md">
|
|
59
|
+
Get Started
|
|
60
|
+
</Button>
|
|
61
|
+
</main>
|
|
62
|
+
</ToastProvider>
|
|
63
|
+
</ThemeProvider>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default App;
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Components
|
|
73
|
+
|
|
74
|
+
### Basic
|
|
75
|
+
|
|
76
|
+
| Component | Description |
|
|
77
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
78
|
+
| `Button` | Clickable button with variants, sizes, loading spinner, and icons |
|
|
79
|
+
| `Badge` | Small status indicator label or colored dot |
|
|
80
|
+
| `Avatar` | User image with initials fallback and circle/square shape |
|
|
81
|
+
| `Chip` | Compact tag element with optional delete button and click handler |
|
|
82
|
+
| `Progress` | Determinate or indeterminate progress bar with percentage label |
|
|
83
|
+
| `Tooltip` | Floating tooltip that appears on hover/focus around a trigger |
|
|
84
|
+
|
|
85
|
+
### Form
|
|
86
|
+
|
|
87
|
+
| Component | Description |
|
|
88
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
89
|
+
| `TextField` | Text/password/tel/number input with auto-formatting, labels, and character counter |
|
|
90
|
+
| `Checkbox` | Checkbox with indeterminate state support and label |
|
|
91
|
+
| `Radio` | Single radio input, used inside `RadioGroup` |
|
|
92
|
+
| `RadioGroup` | Groups `Radio` components with controlled/uncontrolled value |
|
|
93
|
+
| `Switch` | Toggle switch with label and size options |
|
|
94
|
+
| `Select` | Dropdown select with searchable and multi-select modes |
|
|
95
|
+
| `Slider` | Range input with value label, min/max/step support |
|
|
96
|
+
|
|
97
|
+
### Feedback
|
|
98
|
+
|
|
99
|
+
| Component | Description |
|
|
100
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
101
|
+
| `Toast` | Notification alert with variants (success, danger, warning, info) |
|
|
102
|
+
| `Dialog` | Modal dialog with compound sub-components (Title, Content, Actions)|
|
|
103
|
+
| `Menu` | Dropdown menu with compound Trigger, Content, Item, and Divider |
|
|
104
|
+
|
|
105
|
+
### Data
|
|
106
|
+
|
|
107
|
+
| Component | Description |
|
|
108
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
109
|
+
| `Table` | Data table with sortable columns, custom cell renderers, and row click |
|
|
110
|
+
| `Pagination` | Page navigation with ellipsis, sibling count control, and simple variant |
|
|
111
|
+
|
|
112
|
+
### Date
|
|
113
|
+
|
|
114
|
+
| Component | Description |
|
|
115
|
+
| ----------------- | ------------------------------------------------------------- |
|
|
116
|
+
| `DatePicker` | Single date picker with calendar popup and year grid |
|
|
117
|
+
| `DateRangePicker` | Date range selection with dual calendar, presets, and hover preview |
|
|
118
|
+
| `Calendar` | Standalone calendar grid (also used internally by pickers) |
|
|
119
|
+
|
|
120
|
+
### Layout
|
|
121
|
+
|
|
122
|
+
| Component | Description |
|
|
123
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
124
|
+
| `Tabs` | Tabbed interface with compound List, Trigger, and Content |
|
|
125
|
+
| `Expander` | Accordion / collapsible sections with single or multiple open mode |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Theming
|
|
130
|
+
|
|
131
|
+
### ThemeProvider
|
|
132
|
+
|
|
133
|
+
Wrap your application with `ThemeProvider` to enable dark/light mode. It sets the `data-theme` attribute on `<html>` and auto-detects the user's system preference when no `defaultTheme` is provided.
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { ThemeProvider } from 'trust-ui-react';
|
|
137
|
+
|
|
138
|
+
<ThemeProvider defaultTheme="light">
|
|
139
|
+
{/* your app */}
|
|
140
|
+
</ThemeProvider>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### useTheme hook
|
|
144
|
+
|
|
145
|
+
Access and control the current theme from any component:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { useTheme } from 'trust-ui-react';
|
|
149
|
+
|
|
150
|
+
function ThemeToggle() {
|
|
151
|
+
const { theme, setTheme, toggleTheme } = useTheme();
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<button onClick={toggleTheme}>
|
|
155
|
+
Current theme: {theme}
|
|
156
|
+
</button>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### How dark/light mode works
|
|
162
|
+
|
|
163
|
+
The library ships two CSS files -- `theme-light.css` and `theme-dark.css` -- that define color tokens under `[data-theme='light']` and `[data-theme='dark']` selectors respectively. `ThemeProvider` sets `data-theme` on `document.documentElement`, and all component styles reference `--tui-*` variables so they automatically adapt.
|
|
164
|
+
|
|
165
|
+
### Customizing CSS variables
|
|
166
|
+
|
|
167
|
+
Override any `--tui-*` token at the root or on a specific selector to match your brand:
|
|
168
|
+
|
|
169
|
+
```css
|
|
170
|
+
/* Override globally */
|
|
171
|
+
:root {
|
|
172
|
+
--tui-primary: #7c3aed;
|
|
173
|
+
--tui-primary-hover: #6d28d9;
|
|
174
|
+
--tui-primary-active: #5b21b6;
|
|
175
|
+
--tui-radius-md: 8px;
|
|
176
|
+
--tui-font-family: 'Pretendard', sans-serif;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Override only for dark mode */
|
|
180
|
+
[data-theme='dark'] {
|
|
181
|
+
--tui-primary: #a78bfa;
|
|
182
|
+
--tui-primary-hover: #c4b5fd;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Available token categories include:
|
|
187
|
+
|
|
188
|
+
| Prefix | Purpose |
|
|
189
|
+
| -------------------- | -------------------------------- |
|
|
190
|
+
| `--tui-bg-*` | Background colors |
|
|
191
|
+
| `--tui-text-*` | Text colors |
|
|
192
|
+
| `--tui-border-*` | Border colors |
|
|
193
|
+
| `--tui-primary-*` | Primary brand colors |
|
|
194
|
+
| `--tui-secondary-*` | Secondary colors |
|
|
195
|
+
| `--tui-success-*` | Success state colors |
|
|
196
|
+
| `--tui-danger-*` | Danger / error state colors |
|
|
197
|
+
| `--tui-warning-*` | Warning state colors |
|
|
198
|
+
| `--tui-info-*` | Info state colors |
|
|
199
|
+
| `--tui-font-*` | Font family, sizes, weights |
|
|
200
|
+
| `--tui-spacing-*` | Spacing scale (xs through 2xl) |
|
|
201
|
+
| `--tui-radius-*` | Border radius scale |
|
|
202
|
+
| `--tui-shadow-*` | Box shadow presets |
|
|
203
|
+
| `--tui-transition-*` | Transition durations |
|
|
204
|
+
| `--tui-z-*` | Z-index layers |
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Component Examples
|
|
209
|
+
|
|
210
|
+
### Button
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
import { Button } from 'trust-ui-react';
|
|
214
|
+
|
|
215
|
+
// Variants
|
|
216
|
+
<Button variant="primary">Primary</Button>
|
|
217
|
+
<Button variant="secondary">Secondary</Button>
|
|
218
|
+
<Button variant="outline">Outline</Button>
|
|
219
|
+
<Button variant="ghost">Ghost</Button>
|
|
220
|
+
<Button variant="danger">Danger</Button>
|
|
221
|
+
|
|
222
|
+
// Sizes
|
|
223
|
+
<Button size="sm">Small</Button>
|
|
224
|
+
<Button size="md">Medium</Button>
|
|
225
|
+
<Button size="lg">Large</Button>
|
|
226
|
+
|
|
227
|
+
// Shapes
|
|
228
|
+
<Button shape="square">Square</Button>
|
|
229
|
+
<Button shape="rounded">Rounded</Button>
|
|
230
|
+
<Button shape="pill">Pill</Button>
|
|
231
|
+
|
|
232
|
+
// Loading state
|
|
233
|
+
<Button loading>Submitting...</Button>
|
|
234
|
+
|
|
235
|
+
// With icons
|
|
236
|
+
<Button startIcon={<PlusIcon />}>Create</Button>
|
|
237
|
+
<Button endIcon={<ArrowIcon />}>Next</Button>
|
|
238
|
+
|
|
239
|
+
// Full width
|
|
240
|
+
<Button fullWidth>Submit</Button>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### TextField
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import { TextField } from 'trust-ui-react';
|
|
247
|
+
|
|
248
|
+
// Basic usage
|
|
249
|
+
<TextField label="Email" type="email" placeholder="you@example.com" />
|
|
250
|
+
|
|
251
|
+
// Shapes
|
|
252
|
+
<TextField label="Square" shape="square" />
|
|
253
|
+
<TextField label="Rounded" shape="rounded" />
|
|
254
|
+
<TextField label="Pill" shape="pill" />
|
|
255
|
+
|
|
256
|
+
// Validation
|
|
257
|
+
<TextField
|
|
258
|
+
label="Username"
|
|
259
|
+
error
|
|
260
|
+
errorMessage="Username is already taken"
|
|
261
|
+
helperText="Choose a unique username"
|
|
262
|
+
/>
|
|
263
|
+
|
|
264
|
+
// Phone number auto-formatting
|
|
265
|
+
<TextField
|
|
266
|
+
type="tel"
|
|
267
|
+
label="Phone"
|
|
268
|
+
onValueChange={(raw) => console.log('Digits only:', raw)}
|
|
269
|
+
/>
|
|
270
|
+
|
|
271
|
+
// Currency auto-formatting
|
|
272
|
+
<TextField
|
|
273
|
+
label="Amount"
|
|
274
|
+
format="currency"
|
|
275
|
+
prefix="$"
|
|
276
|
+
onValueChange={(raw) => console.log('Raw number:', raw)}
|
|
277
|
+
/>
|
|
278
|
+
|
|
279
|
+
// Password with visibility toggle
|
|
280
|
+
<TextField type="password" label="Password" />
|
|
281
|
+
|
|
282
|
+
// Multiline / textarea
|
|
283
|
+
<TextField multiline rows={4} label="Bio" maxLength={200} />
|
|
284
|
+
|
|
285
|
+
// Character counter
|
|
286
|
+
<TextField label="Nickname" maxLength={20} />
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Select
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
import { Select } from 'trust-ui-react';
|
|
293
|
+
|
|
294
|
+
const options = [
|
|
295
|
+
{ value: 'react', label: 'React' },
|
|
296
|
+
{ value: 'vue', label: 'Vue' },
|
|
297
|
+
{ value: 'svelte', label: 'Svelte' },
|
|
298
|
+
{ value: 'angular', label: 'Angular', disabled: true },
|
|
299
|
+
];
|
|
300
|
+
|
|
301
|
+
// Basic select
|
|
302
|
+
<Select options={options} placeholder="Choose a framework" />
|
|
303
|
+
|
|
304
|
+
// Searchable
|
|
305
|
+
<Select options={options} searchable placeholder="Type to search..." />
|
|
306
|
+
|
|
307
|
+
// Multi-select
|
|
308
|
+
<Select options={options} multiple placeholder="Select frameworks" />
|
|
309
|
+
|
|
310
|
+
// Controlled
|
|
311
|
+
function ControlledSelect() {
|
|
312
|
+
const [value, setValue] = useState('react');
|
|
313
|
+
return (
|
|
314
|
+
<Select
|
|
315
|
+
options={options}
|
|
316
|
+
value={value}
|
|
317
|
+
onChange={(v) => setValue(v as string)}
|
|
318
|
+
/>
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Dialog
|
|
324
|
+
|
|
325
|
+
Uses the compound component pattern with `Dialog.Title`, `Dialog.Content`, and `Dialog.Actions`.
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
import { useState } from 'react';
|
|
329
|
+
import { Dialog, Button } from 'trust-ui-react';
|
|
330
|
+
|
|
331
|
+
function ConfirmDialog() {
|
|
332
|
+
const [open, setOpen] = useState(false);
|
|
333
|
+
|
|
334
|
+
return (
|
|
335
|
+
<>
|
|
336
|
+
<Button onClick={() => setOpen(true)}>Open Dialog</Button>
|
|
337
|
+
|
|
338
|
+
<Dialog open={open} onClose={() => setOpen(false)} size="sm">
|
|
339
|
+
<Dialog.Title onClose={() => setOpen(false)}>
|
|
340
|
+
Confirm Deletion
|
|
341
|
+
</Dialog.Title>
|
|
342
|
+
<Dialog.Content>
|
|
343
|
+
Are you sure you want to delete this item? This action cannot be undone.
|
|
344
|
+
</Dialog.Content>
|
|
345
|
+
<Dialog.Actions>
|
|
346
|
+
<Button variant="ghost" onClick={() => setOpen(false)}>
|
|
347
|
+
Cancel
|
|
348
|
+
</Button>
|
|
349
|
+
<Button variant="danger" onClick={() => setOpen(false)}>
|
|
350
|
+
Delete
|
|
351
|
+
</Button>
|
|
352
|
+
</Dialog.Actions>
|
|
353
|
+
</Dialog>
|
|
354
|
+
</>
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
The `size` prop accepts `'sm'`, `'md'`, `'lg'`, or `'fullscreen'`. Pass `closeOnBackdrop={false}` or `closeOnEscape={false}` to prevent accidental dismissal.
|
|
360
|
+
|
|
361
|
+
### Toast
|
|
362
|
+
|
|
363
|
+
Use `ToastProvider` at the app root and the `useToast` hook anywhere in your tree.
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
import { ToastProvider, useToast, Button } from 'trust-ui-react';
|
|
367
|
+
|
|
368
|
+
// Wrap your app
|
|
369
|
+
<ToastProvider position="top-right">
|
|
370
|
+
<App />
|
|
371
|
+
</ToastProvider>
|
|
372
|
+
|
|
373
|
+
// Trigger toasts from any component
|
|
374
|
+
function NotifyButton() {
|
|
375
|
+
const { toast, dismiss, dismissAll } = useToast();
|
|
376
|
+
|
|
377
|
+
const handleClick = () => {
|
|
378
|
+
toast({
|
|
379
|
+
variant: 'success',
|
|
380
|
+
message: 'Changes saved',
|
|
381
|
+
description: 'Your profile has been updated.',
|
|
382
|
+
duration: 4000,
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
return <Button onClick={handleClick}>Save</Button>;
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Available variants: `'success'`, `'danger'`, `'warning'`, `'info'`.
|
|
391
|
+
Position options: `'top-right'`, `'top-left'`, `'top-center'`, `'bottom-right'`, `'bottom-left'`, `'bottom-center'`.
|
|
392
|
+
|
|
393
|
+
### Tabs
|
|
394
|
+
|
|
395
|
+
Compound component with `Tabs.List`, `Tabs.Trigger`, and `Tabs.Content`.
|
|
396
|
+
|
|
397
|
+
```tsx
|
|
398
|
+
import { Tabs } from 'trust-ui-react';
|
|
399
|
+
|
|
400
|
+
<Tabs defaultValue="overview" variant="underline">
|
|
401
|
+
<Tabs.List>
|
|
402
|
+
<Tabs.Trigger value="overview">Overview</Tabs.Trigger>
|
|
403
|
+
<Tabs.Trigger value="features">Features</Tabs.Trigger>
|
|
404
|
+
<Tabs.Trigger value="pricing" disabled>Pricing</Tabs.Trigger>
|
|
405
|
+
</Tabs.List>
|
|
406
|
+
|
|
407
|
+
<Tabs.Content value="overview">
|
|
408
|
+
<p>Overview content goes here.</p>
|
|
409
|
+
</Tabs.Content>
|
|
410
|
+
<Tabs.Content value="features">
|
|
411
|
+
<p>Features content goes here.</p>
|
|
412
|
+
</Tabs.Content>
|
|
413
|
+
<Tabs.Content value="pricing">
|
|
414
|
+
<p>Pricing content goes here.</p>
|
|
415
|
+
</Tabs.Content>
|
|
416
|
+
</Tabs>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Variant options: `'underline'` (default) or `'pill'`.
|
|
420
|
+
|
|
421
|
+
### Table
|
|
422
|
+
|
|
423
|
+
```tsx
|
|
424
|
+
import { Table, type Column } from 'trust-ui-react';
|
|
425
|
+
|
|
426
|
+
interface User {
|
|
427
|
+
id: number;
|
|
428
|
+
name: string;
|
|
429
|
+
email: string;
|
|
430
|
+
role: string;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const columns: Column<User>[] = [
|
|
434
|
+
{ key: 'name', header: 'Name', sortable: true },
|
|
435
|
+
{ key: 'email', header: 'Email', sortable: true },
|
|
436
|
+
{
|
|
437
|
+
key: 'role',
|
|
438
|
+
header: 'Role',
|
|
439
|
+
align: 'center',
|
|
440
|
+
render: (value) => <span style={{ textTransform: 'capitalize' }}>{value}</span>,
|
|
441
|
+
},
|
|
442
|
+
];
|
|
443
|
+
|
|
444
|
+
const data: User[] = [
|
|
445
|
+
{ id: 1, name: 'Alice', email: 'alice@example.com', role: 'admin' },
|
|
446
|
+
{ id: 2, name: 'Bob', email: 'bob@example.com', role: 'editor' },
|
|
447
|
+
{ id: 3, name: 'Charlie', email: 'charlie@example.com', role: 'viewer' },
|
|
448
|
+
];
|
|
449
|
+
|
|
450
|
+
<Table
|
|
451
|
+
columns={columns}
|
|
452
|
+
data={data}
|
|
453
|
+
rowKey="id"
|
|
454
|
+
variant="striped"
|
|
455
|
+
stickyHeader
|
|
456
|
+
onRowClick={(row) => console.log('Clicked:', row.name)}
|
|
457
|
+
/>
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Table variants: `'default'`, `'striped'`, `'bordered'`. Sorting is built-in -- just set `sortable: true` on any column.
|
|
461
|
+
|
|
462
|
+
### DatePicker / DateRangePicker
|
|
463
|
+
|
|
464
|
+
```tsx
|
|
465
|
+
import { useState } from 'react';
|
|
466
|
+
import { DatePicker, DateRangePicker, type DateRange } from 'trust-ui-react';
|
|
467
|
+
|
|
468
|
+
// Single date
|
|
469
|
+
function SingleDate() {
|
|
470
|
+
const [date, setDate] = useState<Date | null>(null);
|
|
471
|
+
|
|
472
|
+
return (
|
|
473
|
+
<DatePicker
|
|
474
|
+
label="Start date"
|
|
475
|
+
value={date}
|
|
476
|
+
onChange={setDate}
|
|
477
|
+
locale="en-US"
|
|
478
|
+
dateFormat="yyyy.MM.dd"
|
|
479
|
+
minDate={new Date(2024, 0, 1)}
|
|
480
|
+
maxDate={new Date(2026, 11, 31)}
|
|
481
|
+
/>
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Date range with presets
|
|
486
|
+
function RangeDate() {
|
|
487
|
+
const [range, setRange] = useState<DateRange>({ start: null, end: null });
|
|
488
|
+
|
|
489
|
+
const presets = [
|
|
490
|
+
{
|
|
491
|
+
label: 'Last 7 days',
|
|
492
|
+
range: {
|
|
493
|
+
start: new Date(Date.now() - 7 * 86400000),
|
|
494
|
+
end: new Date(),
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
label: 'Last 30 days',
|
|
499
|
+
range: {
|
|
500
|
+
start: new Date(Date.now() - 30 * 86400000),
|
|
501
|
+
end: new Date(),
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
];
|
|
505
|
+
|
|
506
|
+
return (
|
|
507
|
+
<DateRangePicker
|
|
508
|
+
label="Period"
|
|
509
|
+
value={range}
|
|
510
|
+
onChange={setRange}
|
|
511
|
+
locale="en-US"
|
|
512
|
+
presets={presets}
|
|
513
|
+
/>
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Expander
|
|
519
|
+
|
|
520
|
+
Compound component with `Expander.Item`, `Expander.Trigger`, and `Expander.Content`.
|
|
521
|
+
|
|
522
|
+
```tsx
|
|
523
|
+
import { Expander } from 'trust-ui-react';
|
|
524
|
+
|
|
525
|
+
// Accordion (single open)
|
|
526
|
+
<Expander type="single" defaultValue="faq-1" variant="bordered">
|
|
527
|
+
<Expander.Item value="faq-1">
|
|
528
|
+
<Expander.Trigger>What is Trust UI?</Expander.Trigger>
|
|
529
|
+
<Expander.Content>
|
|
530
|
+
Trust UI is a lightweight React component library with built-in theming.
|
|
531
|
+
</Expander.Content>
|
|
532
|
+
</Expander.Item>
|
|
533
|
+
|
|
534
|
+
<Expander.Item value="faq-2">
|
|
535
|
+
<Expander.Trigger>Is it accessible?</Expander.Trigger>
|
|
536
|
+
<Expander.Content>
|
|
537
|
+
Yes, all components follow WAI-ARIA patterns and support keyboard navigation.
|
|
538
|
+
</Expander.Content>
|
|
539
|
+
</Expander.Item>
|
|
540
|
+
|
|
541
|
+
<Expander.Item value="faq-3" disabled>
|
|
542
|
+
<Expander.Trigger>Coming soon</Expander.Trigger>
|
|
543
|
+
<Expander.Content>
|
|
544
|
+
This section is not yet available.
|
|
545
|
+
</Expander.Content>
|
|
546
|
+
</Expander.Item>
|
|
547
|
+
</Expander>
|
|
548
|
+
|
|
549
|
+
// Multiple open mode
|
|
550
|
+
<Expander type="multiple" variant="separated">
|
|
551
|
+
{/* ... items ... */}
|
|
552
|
+
</Expander>
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
Type options: `'single'` (accordion, default) or `'multiple'`.
|
|
556
|
+
Variant options: `'default'`, `'bordered'`, `'separated'`.
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## Customization
|
|
561
|
+
|
|
562
|
+
### className override
|
|
563
|
+
|
|
564
|
+
Every component accepts a `className` prop that is appended to its internal class names, allowing you to add or override styles.
|
|
565
|
+
|
|
566
|
+
```tsx
|
|
567
|
+
<Button className="my-custom-button" variant="primary">
|
|
568
|
+
Custom
|
|
569
|
+
</Button>
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
```css
|
|
573
|
+
.my-custom-button {
|
|
574
|
+
border-radius: 9999px;
|
|
575
|
+
text-transform: uppercase;
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### CSS variable scoped override
|
|
580
|
+
|
|
581
|
+
Scope token overrides to a container to theme a specific section without affecting the rest of the app.
|
|
582
|
+
|
|
583
|
+
```tsx
|
|
584
|
+
<div className="promo-section">
|
|
585
|
+
<Button variant="primary">Special Offer</Button>
|
|
586
|
+
</div>
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
```css
|
|
590
|
+
.promo-section {
|
|
591
|
+
--tui-primary: #7c3aed;
|
|
592
|
+
--tui-primary-hover: #6d28d9;
|
|
593
|
+
--tui-primary-active: #5b21b6;
|
|
594
|
+
--tui-radius-md: 12px;
|
|
595
|
+
}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### style prop
|
|
599
|
+
|
|
600
|
+
All components accept an inline `style` prop for one-off adjustments:
|
|
601
|
+
|
|
602
|
+
```tsx
|
|
603
|
+
<Badge variant="success" style={{ fontSize: '0.7rem', letterSpacing: '0.05em' }}>
|
|
604
|
+
NEW
|
|
605
|
+
</Badge>
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
## API Reference
|
|
611
|
+
|
|
612
|
+
All components follow a consistent API pattern:
|
|
613
|
+
|
|
614
|
+
- **`variant`** -- visual style variant (e.g., `'primary'`, `'outlined'`, `'ghost'`)
|
|
615
|
+
- **`size`** -- component size (`'sm'`, `'md'`, `'lg'`)
|
|
616
|
+
- **`shape`** -- border radius shape (`'square'`, `'rounded'`, `'pill'`) on Button and TextField
|
|
617
|
+
- **`disabled`** -- disables the component
|
|
618
|
+
- **`className`** -- additional CSS class names
|
|
619
|
+
- **`style`** -- inline React CSS properties
|
|
620
|
+
- **`ref`** -- forwarded ref (where applicable)
|
|
621
|
+
|
|
622
|
+
Form components additionally support:
|
|
623
|
+
|
|
624
|
+
- **`value` / `defaultValue`** -- controlled and uncontrolled patterns
|
|
625
|
+
- **`onChange`** -- change callback
|
|
626
|
+
- **`error` / `errorMessage`** -- validation state and message
|
|
627
|
+
- **`fullWidth`** -- stretches the component to fill its container
|
|
628
|
+
|
|
629
|
+
For full prop documentation, type definitions, and interactive examples, run the Storybook development server:
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
pnpm dev
|
|
633
|
+
# or
|
|
634
|
+
pnpm storybook
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
---
|
|
638
|
+
|
|
639
|
+
## Browser Support
|
|
640
|
+
|
|
641
|
+
| Browser | Supported versions |
|
|
642
|
+
| ----------------- | ------------------ |
|
|
643
|
+
| Chrome | Last 2 versions |
|
|
644
|
+
| Firefox | Last 2 versions |
|
|
645
|
+
| Safari | Last 2 versions |
|
|
646
|
+
| Edge (Chromium) | Last 2 versions |
|
|
647
|
+
|
|
648
|
+
The library uses modern CSS features such as custom properties and the native `<dialog>` element. Internet Explorer is not supported.
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
## License
|
|
653
|
+
|
|
654
|
+
MIT
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface AvatarProps {
|
|
2
|
+
/** Image URL */
|
|
3
|
+
src?: string;
|
|
4
|
+
/** Alt text for the image */
|
|
5
|
+
alt?: string;
|
|
6
|
+
/** Name used to derive initials when no image is available */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Shape of the avatar */
|
|
9
|
+
shape?: 'circle' | 'square';
|
|
10
|
+
/** Size of the avatar */
|
|
11
|
+
size?: 'sm' | 'md' | 'lg';
|
|
12
|
+
/** Additional CSS class */
|
|
13
|
+
className?: string;
|
|
14
|
+
/** Inline styles */
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
}
|
|
17
|
+
export declare function Avatar({ src, alt, name, shape, size, className, style, }: AvatarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface BadgeProps {
|
|
3
|
+
/** Visual style variant */
|
|
4
|
+
variant?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info';
|
|
5
|
+
/** Size of the badge */
|
|
6
|
+
size?: 'sm' | 'md';
|
|
7
|
+
/** Renders as a small colored dot with no text */
|
|
8
|
+
dot?: boolean;
|
|
9
|
+
/** Badge content */
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
/** Additional CSS class */
|
|
12
|
+
className?: string;
|
|
13
|
+
/** Inline styles */
|
|
14
|
+
style?: React.CSSProperties;
|
|
15
|
+
}
|
|
16
|
+
export declare function Badge({ variant, size, dot, children, className, style, }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|