@tanishraj/ui-kit 2.4.1 → 2.5.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.
- package/dist/globals.css +1 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +462 -53
- package/dist/index.es.js +155 -100
- package/dist/index.es.js.map +1 -1
- package/package.json +24 -22
- package/readme.md +161 -539
package/readme.md
CHANGED
|
@@ -5,37 +5,15 @@
|
|
|
5
5
|
[](https://github.com/tanishraj/ui-kit/blob/develop/LICENSE)
|
|
6
6
|
[](https://tanishraj.github.io/ui-kit/)
|
|
7
7
|
|
|
8
|
-
A
|
|
9
|
-
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- [Setup for app consumers](#setup-for-app-consumers)
|
|
16
|
-
- [Component Library API](#component-library-api)
|
|
17
|
-
- [Theming](#theming)
|
|
18
|
-
- [Accessibility](#accessibility)
|
|
19
|
-
- [Development](#development)
|
|
20
|
-
- [Testing](#testing)
|
|
21
|
-
- [CI / Automation](#ci--automation)
|
|
22
|
-
- [Publishing](#publishing)
|
|
23
|
-
- [Release Process](#release-process)
|
|
24
|
-
- [Repository Structure](#repository-structure)
|
|
25
|
-
- [Components](#components)
|
|
26
|
-
- [Contributing](#contributing)
|
|
27
|
-
- [License](#license)
|
|
28
|
-
- [Changelog](#changelog)
|
|
29
|
-
|
|
30
|
-
## About
|
|
31
|
-
|
|
32
|
-
This package is designed to be consumed as a reusable component library for modern React apps. It includes:
|
|
33
|
-
|
|
34
|
-
- TypeScript-first component APIs with prop-driven variants
|
|
35
|
-
- Storybook docs and usage examples
|
|
8
|
+
A React + TypeScript component library for product UIs, built with Vite, Storybook, Tailwind CSS, CVA, Floating UI, and strict CI quality gates.
|
|
9
|
+
|
|
10
|
+
## Why this library
|
|
11
|
+
|
|
12
|
+
- TypeScript-first component APIs
|
|
13
|
+
- Consistent visual variants and sizing patterns
|
|
14
|
+
- Storybook-backed documentation and examples
|
|
36
15
|
- Accessibility-minded defaults
|
|
37
|
-
- Unit tests and
|
|
38
|
-
- Automated release and quality checks
|
|
16
|
+
- Unit tests, coverage checks, linting, and type checks
|
|
39
17
|
|
|
40
18
|
## Installation
|
|
41
19
|
|
|
@@ -55,573 +33,217 @@ or
|
|
|
55
33
|
pnpm add @tanishraj/ui-kit
|
|
56
34
|
```
|
|
57
35
|
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
```tsx
|
|
61
|
-
import {
|
|
62
|
-
Accordion,
|
|
63
|
-
Alert,
|
|
64
|
-
AnimatePresence,
|
|
65
|
-
AnimatePresenceChild,
|
|
66
|
-
Badge,
|
|
67
|
-
Avatar,
|
|
68
|
-
AvatarGroup,
|
|
69
|
-
Breadcrumb,
|
|
70
|
-
Button,
|
|
71
|
-
ButtonGroup,
|
|
72
|
-
Checkbox,
|
|
73
|
-
CheckboxGroup,
|
|
74
|
-
Chip,
|
|
75
|
-
Divider,
|
|
76
|
-
Dropdown,
|
|
77
|
-
Drawer,
|
|
78
|
-
Feedback,
|
|
79
|
-
Input,
|
|
80
|
-
ListBox,
|
|
81
|
-
Link,
|
|
82
|
-
Modal,
|
|
83
|
-
OrganizationChart,
|
|
84
|
-
Popover,
|
|
85
|
-
ProgressBar,
|
|
86
|
-
Portal,
|
|
87
|
-
Radio,
|
|
88
|
-
RadioGroup,
|
|
89
|
-
Rating,
|
|
90
|
-
Slider,
|
|
91
|
-
Tab,
|
|
92
|
-
TabPanel,
|
|
93
|
-
Tabs,
|
|
94
|
-
TabsList,
|
|
95
|
-
} from '@tanishraj/ui-kit';
|
|
96
|
-
|
|
97
|
-
export function Demo() {
|
|
98
|
-
return <Button variant='primary'>Get Started</Button>;
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Setup for app consumers
|
|
103
|
-
|
|
104
|
-
The library is built to be consumed like a standard React UI package:
|
|
105
|
-
|
|
106
|
-
1. Install dependency
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
npm install @tanishraj/ui-kit
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
2. Use components (styles are included automatically on package import):
|
|
113
|
-
|
|
114
|
-
Use component APIs directly from the package.
|
|
36
|
+
## Quick Start
|
|
115
37
|
|
|
116
38
|
```tsx
|
|
117
|
-
import {
|
|
118
|
-
AnimatePresence,
|
|
119
|
-
AnimatePresenceChild,
|
|
120
|
-
Avatar,
|
|
121
|
-
Button,
|
|
122
|
-
Chip,
|
|
123
|
-
Divider,
|
|
124
|
-
Dropdown,
|
|
125
|
-
Drawer,
|
|
126
|
-
Feedback,
|
|
127
|
-
Input,
|
|
128
|
-
ListBox,
|
|
129
|
-
Link,
|
|
130
|
-
Modal,
|
|
131
|
-
Popover,
|
|
132
|
-
ProgressBar,
|
|
133
|
-
Radio,
|
|
134
|
-
RadioGroup,
|
|
135
|
-
Rating,
|
|
136
|
-
Slider,
|
|
137
|
-
Tab,
|
|
138
|
-
TabPanel,
|
|
139
|
-
Tabs,
|
|
140
|
-
TabsList,
|
|
141
|
-
} from '@tanishraj/ui-kit';
|
|
142
|
-
import { Plus } from 'lucide-react';
|
|
39
|
+
import { Button, Input, Modal } from '@tanishraj/ui-kit';
|
|
143
40
|
import { useState } from 'react';
|
|
144
41
|
|
|
145
|
-
export
|
|
146
|
-
const [
|
|
147
|
-
const [modalOpen, setModalOpen] = useState(false);
|
|
42
|
+
export function Demo() {
|
|
43
|
+
const [open, setOpen] = useState(false);
|
|
148
44
|
|
|
149
45
|
return (
|
|
150
|
-
<div className='flex
|
|
151
|
-
<
|
|
152
|
-
|
|
46
|
+
<div className='flex flex-col gap-4'>
|
|
47
|
+
<Input label='Workspace name' placeholder='Enter a name' />
|
|
48
|
+
|
|
49
|
+
<Button variant='primary' onClick={() => setOpen(true)}>
|
|
50
|
+
Open modal
|
|
153
51
|
</Button>
|
|
154
|
-
|
|
155
|
-
<Chip icon={Plus} variant='success'>
|
|
156
|
-
Active
|
|
157
|
-
</Chip>
|
|
158
|
-
<Input
|
|
159
|
-
caption='There will be a caption text here'
|
|
160
|
-
label='Label'
|
|
161
|
-
placeholder='Placeholder'
|
|
162
|
-
variant='primary'
|
|
163
|
-
/>
|
|
164
|
-
<Radio defaultChecked label='Radio' />
|
|
165
|
-
<RadioGroup
|
|
166
|
-
defaultValue='email'
|
|
167
|
-
label='Notification method'
|
|
168
|
-
options={[
|
|
169
|
-
{ label: 'Email', value: 'email' },
|
|
170
|
-
{ label: 'SMS', value: 'sms' },
|
|
171
|
-
]}
|
|
172
|
-
/>
|
|
173
|
-
<Feedback defaultValue={4} />
|
|
174
|
-
<Rating defaultValue={3.5} precision={0.5} />
|
|
175
|
-
<Slider label='Slider Label' max={10} value={5} />
|
|
176
|
-
<Tabs defaultValue={0}>
|
|
177
|
-
<TabsList>
|
|
178
|
-
<Tab>Overview</Tab>
|
|
179
|
-
<Tab>Details</Tab>
|
|
180
|
-
</TabsList>
|
|
181
|
-
<TabPanel>Overview content</TabPanel>
|
|
182
|
-
<TabPanel>Details content</TabPanel>
|
|
183
|
-
</Tabs>
|
|
184
|
-
<ListBox
|
|
185
|
-
items={[
|
|
186
|
-
{ label: 'Item Name', value: 'one' },
|
|
187
|
-
{ label: 'Item Name', value: 'two' },
|
|
188
|
-
]}
|
|
189
|
-
/>
|
|
190
|
-
<Dropdown variant='primary'>Dropdown</Dropdown>
|
|
191
|
-
<Button onClick={() => setModalOpen(true)}>Open Modal</Button>
|
|
52
|
+
|
|
192
53
|
<Modal
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
54
|
+
open={open}
|
|
55
|
+
title='Create workspace'
|
|
56
|
+
onClose={() => setOpen(false)}
|
|
57
|
+
footer={
|
|
58
|
+
<Button variant='primary' onClick={() => setOpen(false)}>
|
|
59
|
+
Done
|
|
60
|
+
</Button>
|
|
61
|
+
}
|
|
197
62
|
>
|
|
198
|
-
|
|
63
|
+
Your content goes here.
|
|
199
64
|
</Modal>
|
|
200
|
-
<Button onClick={() => setDrawerOpen(true)}>Open Drawer</Button>
|
|
201
|
-
<Popover
|
|
202
|
-
title='Title'
|
|
203
|
-
trigger={<Button appearance='filled'>Open Popover</Button>}
|
|
204
|
-
>
|
|
205
|
-
Slot Area
|
|
206
|
-
</Popover>
|
|
207
|
-
<ProgressBar
|
|
208
|
-
caption='There will be a caption text here'
|
|
209
|
-
label='Label'
|
|
210
|
-
value={30}
|
|
211
|
-
variant='primary'
|
|
212
|
-
/>
|
|
213
|
-
<Drawer
|
|
214
|
-
footer={<Button onClick={() => setDrawerOpen(false)}>Close</Button>}
|
|
215
|
-
onClose={() => setDrawerOpen(false)}
|
|
216
|
-
open={drawerOpen}
|
|
217
|
-
title='Title'
|
|
218
|
-
>
|
|
219
|
-
Drawer content
|
|
220
|
-
</Drawer>
|
|
221
|
-
<Link external href='/components' leadingIcon={Plus}>
|
|
222
|
-
Components
|
|
223
|
-
</Link>
|
|
224
|
-
<Divider className='w-32' />
|
|
225
|
-
<AnimatePresence presence={drawerOpen}>
|
|
226
|
-
<AnimatePresenceChild>
|
|
227
|
-
<div className='animate-in fade-in duration-500'>
|
|
228
|
-
Animated helper content
|
|
229
|
-
</div>
|
|
230
|
-
</AnimatePresenceChild>
|
|
231
|
-
</AnimatePresence>
|
|
232
65
|
</div>
|
|
233
66
|
);
|
|
234
67
|
}
|
|
235
68
|
```
|
|
236
69
|
|
|
237
|
-
|
|
70
|
+
## Styling
|
|
71
|
+
|
|
72
|
+
Styles are included by the package entrypoint. If your app needs explicit stylesheet imports, use:
|
|
238
73
|
|
|
239
74
|
```ts
|
|
240
|
-
// Optional: import globals explicitly when your bundler does not auto-include package CSS
|
|
241
75
|
import '@tanishraj/ui-kit/globals.css';
|
|
242
|
-
|
|
243
|
-
// Optional: import base color tokens directly
|
|
244
|
-
import '@tanishraj/ui-kit/base.css';
|
|
245
|
-
|
|
246
|
-
// Optional: import this only when you want secondary theme
|
|
247
|
-
import '@tanishraj/ui-kit/theme-secondary.css';
|
|
248
76
|
```
|
|
249
77
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
To add a new packaged theme later:
|
|
253
|
-
|
|
254
|
-
1. Add `src/themes/<theme-name>.css`.
|
|
255
|
-
2. Add a package export in `package.json`:
|
|
256
|
-
- `./theme-<theme-name>.css` -> `./dist/themes/<theme-name>.css`
|
|
257
|
-
3. Update the `copy:theme` script to include the new file.
|
|
258
|
-
4. Optionally publish a themed import via `./themes/<theme-name>.css` (already supported by the wildcard export pattern).
|
|
259
|
-
|
|
260
|
-
You can also import through:
|
|
78
|
+
Optional theme entrypoints:
|
|
261
79
|
|
|
262
80
|
```ts
|
|
81
|
+
import '@tanishraj/ui-kit/base.css';
|
|
82
|
+
import '@tanishraj/ui-kit/theme-secondary.css';
|
|
83
|
+
|
|
84
|
+
// or
|
|
263
85
|
import '@tanishraj/ui-kit/themes/primary.css';
|
|
264
86
|
import '@tanishraj/ui-kit/themes/secondary.css';
|
|
265
87
|
```
|
|
266
88
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
orientation='horizontal'
|
|
359
|
-
/>
|
|
360
|
-
|
|
361
|
-
<Feedback defaultValue={4} />
|
|
362
|
-
<Rating defaultValue={3.5} precision={0.5} />
|
|
363
|
-
<Slider label='Slider Label' max={10} value={5} />
|
|
364
|
-
<Tabs defaultValue={0}>
|
|
365
|
-
<TabsList>
|
|
366
|
-
<Tab>Overview</Tab>
|
|
367
|
-
<Tab>Details</Tab>
|
|
368
|
-
</TabsList>
|
|
369
|
-
<TabPanel>Overview content</TabPanel>
|
|
370
|
-
<TabPanel>Details content</TabPanel>
|
|
371
|
-
</Tabs>
|
|
372
|
-
|
|
373
|
-
<Divider>
|
|
374
|
-
<Button leadingIcon={Plus} size='sm' variant='default'>
|
|
375
|
-
Add item
|
|
376
|
-
</Button>
|
|
377
|
-
</Divider>
|
|
378
|
-
|
|
379
|
-
<Dropdown appearance='outline' variant='primary'>
|
|
380
|
-
Dropdown
|
|
381
|
-
</Dropdown>
|
|
382
|
-
|
|
383
|
-
<Input
|
|
384
|
-
caption='There will be a caption text here'
|
|
385
|
-
label='Label'
|
|
386
|
-
leadingIcon={Plus}
|
|
387
|
-
placeholder='Placeholder'
|
|
388
|
-
required
|
|
389
|
-
trailingIcon={Plus}
|
|
390
|
-
variant='primary'
|
|
391
|
-
/>
|
|
392
|
-
|
|
393
|
-
<ListBox
|
|
394
|
-
items={[
|
|
395
|
-
{ label: 'Item Name', value: 'one' },
|
|
396
|
-
{ label: 'Item Name', value: 'two' },
|
|
397
|
-
{ label: 'Item Name', value: 'three' },
|
|
398
|
-
]}
|
|
399
|
-
selectedValue='two'
|
|
400
|
-
/>
|
|
401
|
-
|
|
402
|
-
<Modal
|
|
403
|
-
footer={<Button variant='primary'>Button</Button>}
|
|
404
|
-
leadingIcon={Plus}
|
|
405
|
-
onClose={() => undefined}
|
|
406
|
-
open={false}
|
|
407
|
-
title='Title'
|
|
408
|
-
>
|
|
409
|
-
Slot Area
|
|
410
|
-
</Modal>
|
|
411
|
-
|
|
412
|
-
<Popover
|
|
413
|
-
placement='bottom'
|
|
414
|
-
title='Title'
|
|
415
|
-
trigger={<Button variant='primary'>Open popover</Button>}
|
|
416
|
-
variant='primary'
|
|
417
|
-
>
|
|
418
|
-
Slot Area
|
|
419
|
-
</Popover>
|
|
420
|
-
|
|
421
|
-
<ProgressBar
|
|
422
|
-
caption='There will be a caption text here'
|
|
423
|
-
label='Label'
|
|
424
|
-
showDot
|
|
425
|
-
value={30}
|
|
426
|
-
variant='success'
|
|
427
|
-
/>
|
|
428
|
-
|
|
429
|
-
<AnimatePresence presence>
|
|
430
|
-
<AnimatePresenceChild>
|
|
431
|
-
<div className='animate-in slide-in-from-right duration-500'>
|
|
432
|
-
Presence-managed content
|
|
433
|
-
</div>
|
|
434
|
-
</AnimatePresenceChild>
|
|
435
|
-
</AnimatePresence>
|
|
436
|
-
</div>
|
|
437
|
-
);
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
### Component Notes
|
|
442
|
-
|
|
443
|
-
- `AnimatePresence` and `AnimatePresenceChild` keep exiting elements mounted until their CSS `animationend` event fires. Use them with `data-state`, `animate-in`, `animate-out`, and slide/fade utilities for smooth enter/exit motion.
|
|
444
|
-
- `Breadcrumb` supports `appearance="ghost" | "outline"` and `separator=">" | "/"`. The chevron separator is rendered as an icon.
|
|
445
|
-
- `Checkbox` and `CheckboxGroup` support `shape="square" | "circle"`, with `square` as the default.
|
|
446
|
-
- `Chip` supports `variant`, `appearance="filled" | "outline"`, `shape`, `size`, `inverted`, optional `icon`, and removable chips via `onClose`.
|
|
447
|
-
- `Divider` supports `orientation="horizontal" | "vertical"` and optional centered content through `children`.
|
|
448
|
-
- `Dropdown` opens a Floating UI menu-style popover list. It shares Button `variant`, `appearance`, `size`, `loading`, `disabled`, `inverted`, and `fullWidth` props, with default chevron, optional icon-only mode, `items`, `selectedValue`, `onItemSelect`, custom `trigger` / `menuContent`, `triggerAction="click" | "hover"`, `menuPlacement`, `menuOffset`, optional arrow, and Portal targeting. It uses `ListBox` internally for list rendering.
|
|
449
|
-
- `Drawer` is controlled with `open` and `onClose`, supports `placement="right" | "left" | "top" | "bottom"`, `size="sm" | "md" | "lg" | "full"`, overlay close, Escape close, footer actions, Portal targeting, and placement-aware slide animations.
|
|
450
|
-
- `Feedback` supports controlled or uncontrolled five-point sentiment selection with `value`, `defaultValue`, `onValueChange`, `options`, `variant="face" | "emoji"`, `size`, read-only state, disabled state, and custom accessible labels via `getLabelText`.
|
|
451
|
-
- `Input` supports `label`, `caption`, `error`, `variant`, `size`, required marker, disabled state, optional leading/trailing icons, `clearable`, `onClear`, and `fullWidth`.
|
|
452
|
-
- `ListBox` and `ListItem` provide reusable selectable list surfaces with shared row spacing, selected state, disabled state, optional leading icons, and `option` / `menuitem` semantics.
|
|
453
|
-
- `Modal` is controlled with `open` and `onClose`, supports `size="sm" | "md" | "lg"`, optional leading header icon, overlay close, Escape close, footer actions, Portal targeting, and centered fade/scale animations.
|
|
454
|
-
- `Portal` renders to `document.body` by default and can target a custom container via `container`, `containerRef`, or `containerId`.
|
|
455
|
-
- `Link` supports `variant`, `size`, `underline="none" | "hover" | "always"`, `inverted`, `disabled`, `truncate`, optional leading/trailing icons, and `external` links.
|
|
456
|
-
- `Popover` is powered by Floating UI, supports `placement`, `align`, `variant`, optional arrow/close controls, controlled or uncontrolled open state, and slot-style body content.
|
|
457
|
-
- `ProgressBar` supports `appearance="linear" | "circular"`, semantic `variant`, `size`, labels, captions, visible values, optional linear endpoint dots, custom value formatting, `fullWidth`, and inverted dark-surface styling.
|
|
458
|
-
- `Radio` supports `label`, `description`, `error`, `size`, required marker, disabled state, and native radio input props for single-option composition.
|
|
459
|
-
- `RadioGroup` supports controlled or uncontrolled single selection with `value`, `defaultValue`, `onValueChange`, options, group label, description, error text, `orientation`, `size`, disabled state, and required marker.
|
|
460
|
-
- `Rating` supports controlled or uncontrolled star ratings with `value`, `defaultValue`, `onValueChange`, `max`, `precision={1 | 0.5}`, `size`, read-only state, disabled state, and custom accessible labels.
|
|
461
|
-
- `Slider` supports controlled or uncontrolled single or range selection with `value`, `defaultValue`, `onValueChange`, `min`, `max`, `step`, size variants, visible value markers, labels, captions, and error/disabled states.
|
|
462
|
-
- `Tabs`, `TabsList`, `Tab`, and `TabPanel` provide a compound tabs API with controlled or uncontrolled selection, `variant="underline" | "pill"`, `size`, `orientation`, disabled states, optional adornments, status dots, and close actions.
|
|
463
|
-
|
|
464
|
-
### Documentation and examples
|
|
465
|
-
|
|
466
|
-
- Storybook: run locally with `npm run storybook`
|
|
467
|
-
- Deploy guide and live docs: see repository CI/Pages setup
|
|
468
|
-
|
|
469
|
-
## Theming
|
|
470
|
-
|
|
471
|
-
- Component style variants are centralized with CVA + Tailwind utility patterns.
|
|
472
|
-
- Theme tokens are built in and theme files are exported from package entry points:
|
|
473
|
-
- `base.css`
|
|
474
|
-
- `theme-secondary.css`
|
|
475
|
-
- `themes/primary.css`
|
|
476
|
-
- `themes/secondary.css`
|
|
477
|
-
- `globals.css`
|
|
478
|
-
|
|
479
|
-
## Accessibility
|
|
480
|
-
|
|
481
|
-
This library is built with accessibility as a first-class goal:
|
|
482
|
-
|
|
483
|
-
- Keyboard support follows platform conventions (`Tab`, `Enter`, `Space`, and focus-visible states).
|
|
484
|
-
- ARIA attributes are applied where required.
|
|
485
|
-
- Buttons, badges, and avatar controls are composed to preserve semantic meaning.
|
|
486
|
-
- Disabled/loading states are explicitly represented in props and reflected visually and via attributes.
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
- Live Storybook: https://tanishraj.github.io/ui-kit/
|
|
92
|
+
- Repository: https://github.com/tanishraj/ui-kit
|
|
93
|
+
- Package: https://www.npmjs.com/package/@tanishraj/ui-kit
|
|
94
|
+
|
|
95
|
+
Storybook is the source of truth for public component usage, variants, and examples.
|
|
96
|
+
|
|
97
|
+
## Included Components
|
|
98
|
+
|
|
99
|
+
### Layout and overlays
|
|
100
|
+
|
|
101
|
+
- `Accordion`
|
|
102
|
+
- `AnimatePresence`
|
|
103
|
+
- `AnimatePresenceChild`
|
|
104
|
+
- `ConfirmationPopup`
|
|
105
|
+
- `Divider`
|
|
106
|
+
- `Drawer`
|
|
107
|
+
- `Modal`
|
|
108
|
+
- `Popover`
|
|
109
|
+
- `Portal`
|
|
110
|
+
- `Table`
|
|
111
|
+
- `Tabs`
|
|
112
|
+
- `TabsList`
|
|
113
|
+
- `Tab`
|
|
114
|
+
- `TabPanel`
|
|
115
|
+
|
|
116
|
+
### Actions and navigation
|
|
117
|
+
|
|
118
|
+
- `Breadcrumb`
|
|
119
|
+
- `Button`
|
|
120
|
+
- `ButtonGroup`
|
|
121
|
+
- `Dropdown`
|
|
122
|
+
- `Link`
|
|
123
|
+
|
|
124
|
+
### Inputs and selection
|
|
125
|
+
|
|
126
|
+
- `Checkbox`
|
|
127
|
+
- `CheckboxGroup`
|
|
128
|
+
- `Input`
|
|
129
|
+
- `Radio`
|
|
130
|
+
- `RadioGroup`
|
|
131
|
+
- `Select`
|
|
132
|
+
- `AsyncSelect`
|
|
133
|
+
- `CheckboxSelect`
|
|
134
|
+
- `GroupedSelect`
|
|
135
|
+
- `MultiSelectCompact`
|
|
136
|
+
- `SelectWithApply`
|
|
137
|
+
- `Slider`
|
|
138
|
+
- `TextArea`
|
|
139
|
+
|
|
140
|
+
### Feedback and status
|
|
141
|
+
|
|
142
|
+
- `Alert`
|
|
143
|
+
- `Badge`
|
|
144
|
+
- `Chip`
|
|
145
|
+
- `Feedback`
|
|
146
|
+
- `ProgressBar`
|
|
147
|
+
- `Rating`
|
|
148
|
+
- `Tooltip`
|
|
149
|
+
- `TrendIndicator`
|
|
150
|
+
- `Toaster`
|
|
151
|
+
- `useToast`
|
|
152
|
+
|
|
153
|
+
### Data display
|
|
154
|
+
|
|
155
|
+
- `CompactList`
|
|
156
|
+
- `CountryFlag`
|
|
157
|
+
- `Label`
|
|
158
|
+
- `ListBox`
|
|
159
|
+
- `ListItem`
|
|
160
|
+
- `MetricCard`
|
|
161
|
+
- `MetricValueItem`
|
|
162
|
+
- `OrganizationChart`
|
|
163
|
+
|
|
164
|
+
### Identity
|
|
165
|
+
|
|
166
|
+
- `Avatar`
|
|
167
|
+
- `AvatarGroup`
|
|
168
|
+
|
|
169
|
+
## API Conventions
|
|
170
|
+
|
|
171
|
+
Most components follow a shared set of prop patterns where relevant:
|
|
172
|
+
|
|
173
|
+
- `size`: typically `sm`, `md`, `lg`
|
|
174
|
+
- `variant`: semantic or visual intent
|
|
175
|
+
- `appearance`: surface treatment such as `filled`, `outline`, or `ghost`
|
|
176
|
+
- `disabled`: disabled interaction state
|
|
177
|
+
- `fullWidth`: expands to parent width where supported
|
|
178
|
+
|
|
179
|
+
Not every component supports every prop. Use Storybook or the exported TypeScript types for the exact API.
|
|
487
180
|
|
|
488
181
|
## Development
|
|
489
182
|
|
|
490
|
-
|
|
183
|
+
Prerequisites:
|
|
491
184
|
|
|
492
185
|
- Node.js 20+
|
|
493
|
-
-
|
|
186
|
+
- `yarn.lock` is used in CI installs
|
|
494
187
|
|
|
495
|
-
|
|
188
|
+
Common scripts:
|
|
496
189
|
|
|
497
190
|
```bash
|
|
498
|
-
npm run build
|
|
499
|
-
npm run lint
|
|
500
|
-
npm run type-check
|
|
501
|
-
npm run test
|
|
502
|
-
npm run
|
|
503
|
-
npm run
|
|
504
|
-
npm run storybook
|
|
505
|
-
npm run storybook:build # build Storybook static site
|
|
506
|
-
npm run clean # remove generated artifacts
|
|
191
|
+
npm run build
|
|
192
|
+
npm run lint
|
|
193
|
+
npm run type-check
|
|
194
|
+
npm run test
|
|
195
|
+
npm run test:coverage
|
|
196
|
+
npm run storybook
|
|
197
|
+
npm run storybook:build
|
|
507
198
|
```
|
|
508
199
|
|
|
509
|
-
|
|
200
|
+
## Quality Gates
|
|
510
201
|
|
|
511
|
-
|
|
202
|
+
The repository validates changes with:
|
|
512
203
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
-
|
|
516
|
-
-
|
|
517
|
-
-
|
|
518
|
-
|
|
519
|
-
## CI / Automation
|
|
520
|
-
|
|
521
|
-
Current repository workflows:
|
|
522
|
-
|
|
523
|
-
- `eslint.yml`
|
|
524
|
-
- `type-check.yml`
|
|
525
|
-
- `unit-tests.yml`
|
|
526
|
-
- `coverage-report.yml`
|
|
527
|
-
- `codeql.yml`
|
|
528
|
-
- `npm-publish.yml`
|
|
529
|
-
- `deploy-storybook.yml`
|
|
530
|
-
|
|
531
|
-
Quality gates include linting, type checking, unit tests, and coverage checks.
|
|
204
|
+
- ESLint
|
|
205
|
+
- TypeScript type-checking
|
|
206
|
+
- Vitest unit tests
|
|
207
|
+
- coverage thresholds
|
|
208
|
+
- GitHub Actions workflows for CI, releases, and Storybook deployment
|
|
532
209
|
|
|
533
210
|
## Publishing
|
|
534
211
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
- Publish is handled through GitHub Actions.
|
|
538
|
-
- Workflow validates checks before `npm publish`.
|
|
539
|
-
- Scope is controlled by repository secrets and workflow rules.
|
|
540
|
-
|
|
541
|
-
### Required secret
|
|
542
|
-
|
|
543
|
-
- `NPM_TOKEN`
|
|
212
|
+
Publishing is handled through GitHub Actions.
|
|
544
213
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
- [`release.md`](release.md)
|
|
214
|
+
- npm publish workflow: `.github/workflows/npm-publish.yml`
|
|
215
|
+
- required secret: `NPM_TOKEN`
|
|
216
|
+
- release guide: [`release.md`](release.md)
|
|
550
217
|
|
|
551
218
|
Quick release flow:
|
|
552
219
|
|
|
553
|
-
1.
|
|
554
|
-
2.
|
|
555
|
-
3. CI
|
|
220
|
+
1. Update the version with `npm version patch|minor|major`
|
|
221
|
+
2. Create a release tag such as `v1.2.0`
|
|
222
|
+
3. Let CI validate and publish
|
|
556
223
|
|
|
557
224
|
## Repository Structure
|
|
558
225
|
|
|
559
226
|
```text
|
|
560
227
|
src/
|
|
561
228
|
components/ # React component implementations
|
|
562
|
-
themes/ # theme
|
|
563
|
-
utils/ # shared helpers and
|
|
564
|
-
.storybook/ # Storybook
|
|
565
|
-
.github/workflows/ # CI and
|
|
229
|
+
themes/ # exported theme files
|
|
230
|
+
utils/ # shared helpers and utilities
|
|
231
|
+
.storybook/ # Storybook configuration
|
|
232
|
+
.github/workflows/ # CI and publishing workflows
|
|
566
233
|
```
|
|
567
234
|
|
|
568
|
-
## Components
|
|
569
|
-
|
|
570
|
-
| Component | Location | Storybook | Status |
|
|
571
|
-
| ----------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------ |
|
|
572
|
-
| Accordion | `src/components/Accordion` | [Accordion](https://tanishraj.github.io/ui-kit/?path=/story/components-accordion--default) | Stable |
|
|
573
|
-
| Alert | `src/components/Alert` | [Alert](https://tanishraj.github.io/ui-kit/?path=/story/components-alert--default) | Stable |
|
|
574
|
-
| AnimatePresence | `src/components/AnimatePresence` | [AnimatePresence](https://tanishraj.github.io/ui-kit/?path=/story/ui-kit-components-animatepresence--basicexample) | Stable |
|
|
575
|
-
| Avatar | `src/components/Avatar` | [Avatar](https://tanishraj.github.io/ui-kit/?path=/story/components-avatar--playground) | Stable |
|
|
576
|
-
| AvatarGroup | `src/components/AvatarGroup` | [AvatarGroup](https://tanishraj.github.io/ui-kit/?path=/story/components-avatargroup--default) | Stable |
|
|
577
|
-
| Badge | `src/components/Badge` | [Badge](https://tanishraj.github.io/ui-kit/?path=/story/components-badge--playground) | Stable |
|
|
578
|
-
| Breadcrumb | `src/components/Breadcrumb` | [Breadcrumb](https://tanishraj.github.io/ui-kit/?path=/story/components-breadcrumb--playground) | Stable |
|
|
579
|
-
| Button | `src/components/Button` | [Button](https://tanishraj.github.io/ui-kit/?path=/story/components-button--playground) | Stable |
|
|
580
|
-
| ButtonGroup | `src/components/ButtonGroup` | [ButtonGroup](https://tanishraj.github.io/ui-kit/?path=/story/components-buttongroup--playground) | Stable |
|
|
581
|
-
| Checkbox | `src/components/Checkbox` | [Checkbox](https://tanishraj.github.io/ui-kit/?path=/story/components-checkbox--playground) | Stable |
|
|
582
|
-
| CheckboxGroup | `src/components/CheckboxGroup` | [CheckboxGroup](https://tanishraj.github.io/ui-kit/?path=/story/components-checkboxgroup--playground) | Stable |
|
|
583
|
-
| Chip | `src/components/Chip` | [Chip](https://tanishraj.github.io/ui-kit/?path=/story/components-chip--playground) | Stable |
|
|
584
|
-
| Divider | `src/components/Divider` | [Divider](https://tanishraj.github.io/ui-kit/?path=/story/components-divider--playground) | Stable |
|
|
585
|
-
| Dropdown | `src/components/Dropdown` | [Dropdown](https://tanishraj.github.io/ui-kit/?path=/story/components-dropdown--playground) | Stable |
|
|
586
|
-
| Drawer | `src/components/Drawer` | [Drawer](https://tanishraj.github.io/ui-kit/?path=/story/components-drawer--playground) | Stable |
|
|
587
|
-
| Feedback | `src/components/Feedback` | [Feedback](https://tanishraj.github.io/ui-kit/?path=/story/components-feedback--playground) | Stable |
|
|
588
|
-
| Input | `src/components/Input` | [Input](https://tanishraj.github.io/ui-kit/?path=/story/components-input--playground) | Stable |
|
|
589
|
-
| ListBox | `src/components/ListBox` | [ListBox](https://tanishraj.github.io/ui-kit/?path=/story/components-listbox--playground) | Stable |
|
|
590
|
-
| Link | `src/components/Link` | [Link](https://tanishraj.github.io/ui-kit/?path=/story/components-link--playground) | Stable |
|
|
591
|
-
| Modal | `src/components/Modal` | [Modal](https://tanishraj.github.io/ui-kit/?path=/story/components-modal--playground) | Stable |
|
|
592
|
-
| OrganizationChart | `src/components/OrganizationChart` | [OrganizationChart](https://tanishraj.github.io/ui-kit/?path=/story/components-organizationchart--playground) | Stable |
|
|
593
|
-
| Popover | `src/components/Popover` | [Popover](https://tanishraj.github.io/ui-kit/?path=/story/components-popover--playground) | Stable |
|
|
594
|
-
| ProgressBar | `src/components/ProgressBar` | [ProgressBar](https://tanishraj.github.io/ui-kit/?path=/story/components-progressbar--playground) | Stable |
|
|
595
|
-
| Portal | `src/components/Portal` | N/A | Stable |
|
|
596
|
-
| Radio | `src/components/Radio` | [Radio](https://tanishraj.github.io/ui-kit/?path=/story/components-radio--playground) | Stable |
|
|
597
|
-
| RadioGroup | `src/components/RadioGroup` | [RadioGroup](https://tanishraj.github.io/ui-kit/?path=/story/components-radiogroup--playground) | Stable |
|
|
598
|
-
| Rating | `src/components/Rating` | [Rating](https://tanishraj.github.io/ui-kit/?path=/story/components-rating--playground) | Stable |
|
|
599
|
-
| Slider | `src/components/Slider` | [Slider](https://tanishraj.github.io/ui-kit/?path=/story/components-slider--playground) | Stable |
|
|
600
|
-
| Tabs | `src/components/Tabs` | [Tabs](https://tanishraj.github.io/ui-kit/?path=/story/components-tabs--playground) | Stable |
|
|
601
|
-
|
|
602
|
-
## Versioning and Changelog
|
|
603
|
-
|
|
604
|
-
- This package follows [Semantic Versioning (SemVer)](https://semver.org/).
|
|
605
|
-
- Version updates use `npm version patch|minor|major`.
|
|
606
|
-
- Pre-release versions are supported and published with the `next` tag when release is marked as prerelease.
|
|
607
|
-
- Breaking changes are documented and shipped as a new major version.
|
|
608
|
-
- Changes must be recorded in [`CHANGELOG.md`](CHANGELOG.md).
|
|
609
|
-
|
|
610
|
-
## Changelog
|
|
611
|
-
|
|
612
|
-
- Maintained using Keep a Changelog structure: `Unreleased`, `Added`, `Changed`, `Fixed`.
|
|
613
|
-
- Update changelog before tagging and include impact, scope, and migration notes when needed.
|
|
614
|
-
- Keep the latest released version at top below `Unreleased`.
|
|
615
|
-
|
|
616
235
|
## Contributing
|
|
617
236
|
|
|
618
237
|
Contributions should include:
|
|
619
238
|
|
|
620
|
-
-
|
|
621
|
-
-
|
|
622
|
-
-
|
|
239
|
+
- implementation updates
|
|
240
|
+
- matching Storybook examples when behavior changes
|
|
241
|
+
- tests for new or changed behavior
|
|
242
|
+
- lint-safe and type-safe code
|
|
243
|
+
|
|
244
|
+
## Changelog
|
|
623
245
|
|
|
624
|
-
|
|
246
|
+
See [`CHANGELOG.md`](CHANGELOG.md).
|
|
625
247
|
|
|
626
248
|
## License
|
|
627
249
|
|