@yccui/ui 1.0.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.
Files changed (153) hide show
  1. package/README.md +504 -0
  2. package/dist/components/DataDisplay/Accordion.d.ts +12 -0
  3. package/dist/components/DataDisplay/Accordion.d.ts.map +1 -0
  4. package/dist/components/DataDisplay/Avatar.d.ts +9 -0
  5. package/dist/components/DataDisplay/Avatar.d.ts.map +1 -0
  6. package/dist/components/DataDisplay/Badge.d.ts +8 -0
  7. package/dist/components/DataDisplay/Badge.d.ts.map +1 -0
  8. package/dist/components/DataDisplay/Banner.d.ts +13 -0
  9. package/dist/components/DataDisplay/Banner.d.ts.map +1 -0
  10. package/dist/components/DataDisplay/Card.d.ts +27 -0
  11. package/dist/components/DataDisplay/Card.d.ts.map +1 -0
  12. package/dist/components/DataDisplay/CompareBar.d.ts +10 -0
  13. package/dist/components/DataDisplay/CompareBar.d.ts.map +1 -0
  14. package/dist/components/DataDisplay/CopyButton.d.ts +8 -0
  15. package/dist/components/DataDisplay/CopyButton.d.ts.map +1 -0
  16. package/dist/components/DataDisplay/DataList.d.ts +11 -0
  17. package/dist/components/DataDisplay/DataList.d.ts.map +1 -0
  18. package/dist/components/DataDisplay/Donut.d.ts +10 -0
  19. package/dist/components/DataDisplay/Donut.d.ts.map +1 -0
  20. package/dist/components/DataDisplay/EmptyState.d.ts +10 -0
  21. package/dist/components/DataDisplay/EmptyState.d.ts.map +1 -0
  22. package/dist/components/DataDisplay/KV.d.ts +9 -0
  23. package/dist/components/DataDisplay/KV.d.ts.map +1 -0
  24. package/dist/components/DataDisplay/Popover.d.ts +9 -0
  25. package/dist/components/DataDisplay/Popover.d.ts.map +1 -0
  26. package/dist/components/DataDisplay/ProgressBar.d.ts +10 -0
  27. package/dist/components/DataDisplay/ProgressBar.d.ts.map +1 -0
  28. package/dist/components/DataDisplay/StatCard.d.ts +13 -0
  29. package/dist/components/DataDisplay/StatCard.d.ts.map +1 -0
  30. package/dist/components/DataDisplay/Table.d.ts +23 -0
  31. package/dist/components/DataDisplay/Table.d.ts.map +1 -0
  32. package/dist/components/DataDisplay/Tag.d.ts +9 -0
  33. package/dist/components/DataDisplay/Tag.d.ts.map +1 -0
  34. package/dist/components/DataDisplay/Timeline.d.ts +12 -0
  35. package/dist/components/DataDisplay/Timeline.d.ts.map +1 -0
  36. package/dist/components/DataDisplay/Tooltip.d.ts +9 -0
  37. package/dist/components/DataDisplay/Tooltip.d.ts.map +1 -0
  38. package/dist/components/DataDisplay/TrendSpark.d.ts +9 -0
  39. package/dist/components/DataDisplay/TrendSpark.d.ts.map +1 -0
  40. package/dist/components/DataDisplay/index.d.ts +39 -0
  41. package/dist/components/DataDisplay/index.d.ts.map +1 -0
  42. package/dist/components/Feedback/Alert.d.ts +9 -0
  43. package/dist/components/Feedback/Alert.d.ts.map +1 -0
  44. package/dist/components/Feedback/ConfirmDialog.d.ts +14 -0
  45. package/dist/components/Feedback/ConfirmDialog.d.ts.map +1 -0
  46. package/dist/components/Feedback/Drawer.d.ts +12 -0
  47. package/dist/components/Feedback/Drawer.d.ts.map +1 -0
  48. package/dist/components/Feedback/Modal.d.ts +14 -0
  49. package/dist/components/Feedback/Modal.d.ts.map +1 -0
  50. package/dist/components/Feedback/Skeleton.d.ts +8 -0
  51. package/dist/components/Feedback/Skeleton.d.ts.map +1 -0
  52. package/dist/components/Feedback/Spinner.d.ts +8 -0
  53. package/dist/components/Feedback/Spinner.d.ts.map +1 -0
  54. package/dist/components/Feedback/Toast.d.ts +20 -0
  55. package/dist/components/Feedback/Toast.d.ts.map +1 -0
  56. package/dist/components/Feedback/index.d.ts +15 -0
  57. package/dist/components/Feedback/index.d.ts.map +1 -0
  58. package/dist/components/Form/Button.d.ts +16 -0
  59. package/dist/components/Form/Button.d.ts.map +1 -0
  60. package/dist/components/Form/Checkbox.d.ts +12 -0
  61. package/dist/components/Form/Checkbox.d.ts.map +1 -0
  62. package/dist/components/Form/DateInput.d.ts +12 -0
  63. package/dist/components/Form/DateInput.d.ts.map +1 -0
  64. package/dist/components/Form/FileUpload.d.ts +11 -0
  65. package/dist/components/Form/FileUpload.d.ts.map +1 -0
  66. package/dist/components/Form/FormGroup.d.ts +11 -0
  67. package/dist/components/Form/FormGroup.d.ts.map +1 -0
  68. package/dist/components/Form/Input.d.ts +17 -0
  69. package/dist/components/Form/Input.d.ts.map +1 -0
  70. package/dist/components/Form/Radio.d.ts +13 -0
  71. package/dist/components/Form/Radio.d.ts.map +1 -0
  72. package/dist/components/Form/RadioGroup.d.ts +16 -0
  73. package/dist/components/Form/RadioGroup.d.ts.map +1 -0
  74. package/dist/components/Form/ScanZone.d.ts +8 -0
  75. package/dist/components/Form/ScanZone.d.ts.map +1 -0
  76. package/dist/components/Form/SearchInput.d.ts +13 -0
  77. package/dist/components/Form/SearchInput.d.ts.map +1 -0
  78. package/dist/components/Form/Select.d.ts +18 -0
  79. package/dist/components/Form/Select.d.ts.map +1 -0
  80. package/dist/components/Form/Textarea.d.ts +14 -0
  81. package/dist/components/Form/Textarea.d.ts.map +1 -0
  82. package/dist/components/Form/Toggle.d.ts +11 -0
  83. package/dist/components/Form/Toggle.d.ts.map +1 -0
  84. package/dist/components/Form/index.d.ts +27 -0
  85. package/dist/components/Form/index.d.ts.map +1 -0
  86. package/dist/components/Icons/Icon.d.ts +10 -0
  87. package/dist/components/Icons/Icon.d.ts.map +1 -0
  88. package/dist/components/Icons/index.d.ts +3 -0
  89. package/dist/components/Icons/index.d.ts.map +1 -0
  90. package/dist/components/Layout/Col.d.ts +12 -0
  91. package/dist/components/Layout/Col.d.ts.map +1 -0
  92. package/dist/components/Layout/Container.d.ts +9 -0
  93. package/dist/components/Layout/Container.d.ts.map +1 -0
  94. package/dist/components/Layout/Divider.d.ts +7 -0
  95. package/dist/components/Layout/Divider.d.ts.map +1 -0
  96. package/dist/components/Layout/Footer.d.ts +10 -0
  97. package/dist/components/Layout/Footer.d.ts.map +1 -0
  98. package/dist/components/Layout/Grid.d.ts +10 -0
  99. package/dist/components/Layout/Grid.d.ts.map +1 -0
  100. package/dist/components/Layout/Header.d.ts +15 -0
  101. package/dist/components/Layout/Header.d.ts.map +1 -0
  102. package/dist/components/Layout/Page.d.ts +14 -0
  103. package/dist/components/Layout/Page.d.ts.map +1 -0
  104. package/dist/components/Layout/PageHeader.d.ts +9 -0
  105. package/dist/components/Layout/PageHeader.d.ts.map +1 -0
  106. package/dist/components/Layout/Row.d.ts +9 -0
  107. package/dist/components/Layout/Row.d.ts.map +1 -0
  108. package/dist/components/Layout/Sidebar.d.ts +10 -0
  109. package/dist/components/Layout/Sidebar.d.ts.map +1 -0
  110. package/dist/components/Layout/Spacer.d.ts +7 -0
  111. package/dist/components/Layout/Spacer.d.ts.map +1 -0
  112. package/dist/components/Layout/Stack.d.ts +10 -0
  113. package/dist/components/Layout/Stack.d.ts.map +1 -0
  114. package/dist/components/Layout/index.d.ts +25 -0
  115. package/dist/components/Layout/index.d.ts.map +1 -0
  116. package/dist/components/Navigation/Breadcrumb.d.ts +12 -0
  117. package/dist/components/Navigation/Breadcrumb.d.ts.map +1 -0
  118. package/dist/components/Navigation/ContextMenu.d.ts +14 -0
  119. package/dist/components/Navigation/ContextMenu.d.ts.map +1 -0
  120. package/dist/components/Navigation/Nav.d.ts +31 -0
  121. package/dist/components/Navigation/Nav.d.ts.map +1 -0
  122. package/dist/components/Navigation/Pagination.d.ts +9 -0
  123. package/dist/components/Navigation/Pagination.d.ts.map +1 -0
  124. package/dist/components/Navigation/Stepper.d.ts +10 -0
  125. package/dist/components/Navigation/Stepper.d.ts.map +1 -0
  126. package/dist/components/Navigation/Tabs.d.ts +14 -0
  127. package/dist/components/Navigation/Tabs.d.ts.map +1 -0
  128. package/dist/components/Navigation/index.d.ts +13 -0
  129. package/dist/components/Navigation/index.d.ts.map +1 -0
  130. package/dist/components/index.d.ts +7 -0
  131. package/dist/components/index.d.ts.map +1 -0
  132. package/dist/index.cjs +5 -0
  133. package/dist/index.d.ts +11 -0
  134. package/dist/index.d.ts.map +1 -0
  135. package/dist/index.js +3704 -0
  136. package/dist/pages/ComponentShowcase.d.ts +2 -0
  137. package/dist/pages/ComponentShowcase.d.ts.map +1 -0
  138. package/dist/pages/DashboardDemo.d.ts +2 -0
  139. package/dist/pages/DashboardDemo.d.ts.map +1 -0
  140. package/dist/pages/PrototypeHome.d.ts +3 -0
  141. package/dist/pages/PrototypeHome.d.ts.map +1 -0
  142. package/dist/pages/index.d.ts +4 -0
  143. package/dist/pages/index.d.ts.map +1 -0
  144. package/dist/styles.css +1 -0
  145. package/dist/tokens/colors.d.ts +259 -0
  146. package/dist/tokens/colors.d.ts.map +1 -0
  147. package/dist/tokens/index.d.ts +4 -0
  148. package/dist/tokens/index.d.ts.map +1 -0
  149. package/dist/tokens/layout.d.ts +138 -0
  150. package/dist/tokens/layout.d.ts.map +1 -0
  151. package/dist/tokens/typography.d.ts +148 -0
  152. package/dist/tokens/typography.d.ts.map +1 -0
  153. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,504 @@
1
+ # @ycc/ui
2
+
3
+ > Professional React component library for logistics and freight management platforms.
4
+ > Extracted from the Your Cargo Contact APIP platform.
5
+
6
+ ![npm version](https://img.shields.io/badge/npm-v1.0.0-blue)
7
+ ![React](https://img.shields.io/badge/React-18%2B-61dafb)
8
+ ![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)
9
+ ![License](https://img.shields.io/badge/license-MIT-green)
10
+
11
+ ## Table of Contents
12
+
13
+ - [Why @ycc/ui](#why-yccui)
14
+ - [Installation](#installation)
15
+ - [Quick Start](#quick-start)
16
+ - [Package Structure](#package-structure)
17
+ - [Components](#components)
18
+ - [Design Tokens](#design-tokens)
19
+ - [Theming](#theming)
20
+ - [Icon Reference](#icon-reference)
21
+ - [Browser Support](#browser-support)
22
+ - [Contributing](#contributing)
23
+ - [License](#license)
24
+
25
+ ## Why @ycc/ui
26
+
27
+ - Purpose-built for customs, freight, warehousing, and back-office dashboards.
28
+ - Fully typed React components with bundled CSS and design-token theming.
29
+ - Production-ready package output with ESM, CommonJS, declarations, and a live docs site.
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ npm install @ycc/ui
35
+ yarn add @ycc/ui
36
+ pnpm add @ycc/ui
37
+ ```
38
+
39
+ Peer dependencies: `react >=18.0.0` and `react-dom >=18.0.0`.
40
+
41
+ ## Quick Start
42
+
43
+ ```tsx
44
+ import '@ycc/ui/styles';
45
+ import { ToastProvider, Page, Nav, NavGroup, NavItem, StatCard } from '@ycc/ui';
46
+
47
+ export function App() {
48
+ return (
49
+ <ToastProvider>
50
+ <Page
51
+ user={{ name: 'Mark', role: 'Administrator' }}
52
+ notificationCount={3}
53
+ nav={(
54
+ <Nav activePage="air">
55
+ <NavGroup label="Freight">
56
+ <NavItem id="air" label="Air Freight" icon="Plane" />
57
+ <NavItem id="sea" label="Sea Freight" icon="Ship" />
58
+ </NavGroup>
59
+ </Nav>
60
+ )}
61
+ >
62
+ <StatCard title="Open Shipments" value="128" change={8.3} trend="up" icon="PackageCheck" />
63
+ </Page>
64
+ </ToastProvider>
65
+ );
66
+ }
67
+ ```
68
+
69
+ ## Package Structure
70
+
71
+ ```text
72
+ dist/
73
+ index.js ESM bundle
74
+ index.cjs CommonJS bundle
75
+ index.d.ts TypeScript declarations
76
+ styles.css Bundled component styles
77
+ ```
78
+
79
+ ## Components
80
+
81
+ Each component is exported from `@ycc/ui` and styled by `@ycc/ui/styles`.
82
+
83
+ ### Page
84
+ Full application shell with Sidebar, Header, content, and Footer.
85
+
86
+ | Prop | Type | Default | Description |
87
+ |---|---|---|---|
88
+ | nav | `ReactNode` | required | Navigation rendered inside the sidebar. |
89
+ | user | `HeaderProps['user']` | `undefined` | Header user summary. |
90
+ | notificationCount | `number` | `undefined` | Notification badge count. |
91
+ | children | `ReactNode` | required | Main page content. |
92
+ | defaultCollapsed | `boolean` | `false` | Initial sidebar state. |
93
+
94
+ ```tsx
95
+ <Page nav={<Nav><NavGroup label="Freight"><NavItem id="air" label="Air Freight" /></NavGroup></Nav>}>
96
+ <StatCard title="Open files" value="128" />
97
+ </Page>
98
+ ```
99
+
100
+ ### Header
101
+ Topbar with search, notifications, language select, and user menu.
102
+
103
+ | Prop | Type | Default | Description |
104
+ |---|---|---|---|
105
+ | onMenuToggle | `() => void` | `undefined` | Handles menu toggling. |
106
+ | title | `string` | `undefined` | Optional title. |
107
+ | user | `{ name: string; role: string; avatar?: string }` | `undefined` | User display data. |
108
+ | notificationCount | `number` | `undefined` | Notification count. |
109
+ | onLogout | `() => void` | `undefined` | Logout callback. |
110
+
111
+ ```tsx
112
+ <Header title="Operations" user={{ name: 'Mark', role: 'Administrator' }} notificationCount={3} />
113
+ ```
114
+
115
+ ### Footer
116
+ Bottom bar with copyright and links.
117
+
118
+ | Prop | Type | Default | Description |
119
+ |---|---|---|---|
120
+ | copyright | `string` | current year YCC | Copyright text. |
121
+ | links | `Array<{ label: string; href: string }>` | `[]` | Footer links. |
122
+
123
+ ```tsx
124
+ <Footer copyright="© 2026 Your Cargo Contact" links={[{ label: 'Support', href: '/support' }]} />
125
+ ```
126
+
127
+ ### Sidebar
128
+ Collapsible sidebar container.
129
+
130
+ | Prop | Type | Default | Description |
131
+ |---|---|---|---|
132
+ | collapsed | `boolean` | `false` | Compact sidebar state. |
133
+ | onToggle | `() => void` | `undefined` | Toggle callback. |
134
+ | logo | `ReactNode` | text logo | Logo content. |
135
+ | children | `ReactNode` | required | Sidebar body. |
136
+
137
+ ```tsx
138
+ <Sidebar logo="YCC"><Nav>{/* items */}</Nav></Sidebar>
139
+ ```
140
+
141
+ ### Container
142
+ Centered max-width wrapper.
143
+
144
+ | Prop | Type | Default | Description |
145
+ |---|---|---|---|
146
+ | children | `ReactNode` | required | Content. |
147
+ | maxWidth | `'sm'|'md'|'lg'|'xl'|'full'` | `'lg'` | Max-width preset. |
148
+ | className | `string` | `undefined` | Custom class. |
149
+
150
+ ```tsx
151
+ <Container maxWidth="xl">Dashboard content</Container>
152
+ ```
153
+
154
+ ### Row / Col
155
+ 12-column flex grid primitives.
156
+
157
+ | Prop | Type | Default | Description |
158
+ |---|---|---|---|
159
+ | Row.children | `ReactNode` | required | Row content. |
160
+ | Row.gap | `number` | `3` | Gap multiplier. |
161
+ | Col.span | `1..12` | `12` | Base span. |
162
+ | Col.sm / Col.lg | `1..12` | span | Responsive spans. |
163
+
164
+ ```tsx
165
+ <Row gap={2}><Col span={6}>Air</Col><Col span={6}>Sea</Col></Row>
166
+ ```
167
+
168
+ ### Grid
169
+ CSS grid wrapper.
170
+
171
+ | Prop | Type | Default | Description |
172
+ |---|---|---|---|
173
+ | children | `ReactNode` | required | Grid items. |
174
+ | cols | `1|2|3|4|5|6|12` | `2` | Column count. |
175
+ | gap | `number` | `3` | Gap multiplier. |
176
+
177
+ ```tsx
178
+ <Grid cols={3}><Card>Air</Card><Card>Sea</Card><Card>Truck</Card></Grid>
179
+ ```
180
+
181
+ ### PageHeader
182
+ Page title, subtitle, and actions slot.
183
+
184
+ | Prop | Type | Default | Description |
185
+ |---|---|---|---|
186
+ | title | `string` | required | Page title. |
187
+ | subtitle | `string` | `undefined` | Supporting text. |
188
+ | actions | `ReactNode` | `undefined` | Action buttons. |
189
+
190
+ ```tsx
191
+ <PageHeader title="Air Freight" subtitle="Live operations" actions={<Button>Create file</Button>} />
192
+ ```
193
+
194
+ ### Divider
195
+ Horizontal rule with optional label.
196
+
197
+ | Prop | Type | Default | Description |
198
+ |---|---|---|---|
199
+ | label | `string` | `undefined` | Center label. |
200
+ | spacing | `'sm'|'md'|'lg'` | `'md'` | Vertical spacing. |
201
+
202
+ ```tsx
203
+ <Divider label="Documents" spacing="lg" />
204
+ ```
205
+
206
+ ### Stack
207
+ Vertical flex stack.
208
+
209
+ | Prop | Type | Default | Description |
210
+ |---|---|---|---|
211
+ | children | `ReactNode` | required | Stack content. |
212
+ | gap | `number` | `3` | Gap multiplier. |
213
+ | align | `'start'|'center'|'end'|'stretch'` | `'stretch'` | Cross-axis alignment. |
214
+
215
+ ```tsx
216
+ <Stack gap={2}><Badge label="Import" variant="import" /></Stack>
217
+ ```
218
+
219
+ ### Spacer
220
+ Whitespace primitive.
221
+
222
+ | Prop | Type | Default | Description |
223
+ |---|---|---|---|
224
+ | size | `number` | `4` | Space multiplier. |
225
+ | axis | `'x'|'y'` | `'y'` | Direction. |
226
+
227
+ ```tsx
228
+ <Spacer size={6} />
229
+ ```
230
+
231
+ ### Nav / NavGroup / NavItem
232
+ Vertical navigation with active state, groups, icons, and badges.
233
+
234
+ | Prop | Type | Default | Description |
235
+ |---|---|---|---|
236
+ | Nav.children | `ReactNode` | required | Groups/items. |
237
+ | Nav.activePage | `string` | `''` | Active item id. |
238
+ | Nav.collapsed | `boolean` | `false` | Compact mode. |
239
+ | NavItem.badge | `string | number` | `undefined` | Item badge. |
240
+
241
+ ```tsx
242
+ <Nav activePage="air"><NavGroup label="Freight"><NavItem id="air" label="Air Freight" icon="Plane" /></NavGroup></Nav>
243
+ ```
244
+
245
+ ### Breadcrumb
246
+ Path trail.
247
+
248
+ | Prop | Type | Default | Description |
249
+ |---|---|---|---|
250
+ | items | `Array<{ label: string; href?: string; onClick?: () => void }>` | required | Breadcrumb items. |
251
+ | separator | `ReactNode` | `'/'` | Separator. |
252
+
253
+ ```tsx
254
+ <Breadcrumb items={[{ label: 'Home' }, { label: 'Air Freight' }, { label: 'AF-2026-00142' }]} />
255
+ ```
256
+
257
+ ### Tabs
258
+ Controlled tab bar.
259
+
260
+ | Prop | Type | Default | Description |
261
+ |---|---|---|---|
262
+ | tabs | `Array<{ id: string; label: string; icon?: string }>` | required | Tabs. |
263
+ | activeTab | `string` | required | Active id. |
264
+ | onChange | `(id: string) => void` | required | Change handler. |
265
+ | children | `ReactNode` | `undefined` | Panel. |
266
+
267
+ ```tsx
268
+ <Tabs tabs={tabs} activeTab={activeTab} onChange={setActiveTab}>Overview</Tabs>
269
+ ```
270
+
271
+ ### Stepper
272
+ Step indicator.
273
+
274
+ | Prop | Type | Default | Description |
275
+ |---|---|---|---|
276
+ | steps | `Array<{ label: string; description?: string }>` | required | Steps. |
277
+ | currentStep | `number` | required | Active zero-based step. |
278
+
279
+ ```tsx
280
+ <Stepper currentStep={1} steps={[{ label: 'Details' }, { label: 'Documents' }]} />
281
+ ```
282
+
283
+ ### Pagination
284
+ Page number controls.
285
+
286
+ | Prop | Type | Default | Description |
287
+ |---|---|---|---|
288
+ | page | `number` | required | Current page. |
289
+ | totalPages | `number` | required | Total pages. |
290
+ | onChange | `(page: number) => void` | required | Page callback. |
291
+ | siblingCount | `number` | `1` | Adjacent page count. |
292
+
293
+ ```tsx
294
+ <Pagination page={2} totalPages={8} onChange={setPage} />
295
+ ```
296
+
297
+ ### ContextMenu
298
+ Dropdown action menu.
299
+
300
+ | Prop | Type | Default | Description |
301
+ |---|---|---|---|
302
+ | items | `Array<{ label: string; icon?: string; onClick: () => void; danger?: boolean; disabled?: boolean }>` | required | Menu items. |
303
+ | trigger | `ReactNode` | required | Trigger element. |
304
+
305
+ ```tsx
306
+ <ContextMenu trigger={<Button>Actions</Button>} items={[{ label: 'Open', onClick }]} />
307
+ ```
308
+
309
+ ### Button
310
+ Action button.
311
+
312
+ | Prop | Type | Default | Description |
313
+ |---|---|---|---|
314
+ | variant | `'primary'|'secondary'|'ghost'|'danger'|'link'` | `'primary'` | Visual style. |
315
+ | size | `'sm'|'md'|'lg'` | `'md'` | Size. |
316
+ | loading | `boolean` | `false` | Loading state. |
317
+ | leftIcon / rightIcon | `string` | `undefined` | Icon names. |
318
+
319
+ ```tsx
320
+ <Button variant="primary" leftIcon="Plus">Create shipment</Button>
321
+ ```
322
+
323
+ ### Input, Select, Checkbox, Textarea, Toggle, FormGroup, FileUpload
324
+ Core form controls for APIP workflows.
325
+
326
+ ```tsx
327
+ <FormGroup label="Origin port" required>
328
+ <Select options={[{ value: 'ams', label: 'Amsterdam (AMS)' }]} />
329
+ </FormGroup>
330
+ ```
331
+
332
+ ### Radio / RadioGroup
333
+ Radio selection controls.
334
+
335
+ ```tsx
336
+ <RadioGroup name="mode" options={[{ value: 'air', label: 'Air Freight' }]} />
337
+ ```
338
+
339
+ ### DateInput
340
+ Styled native date input.
341
+
342
+ ```tsx
343
+ <DateInput defaultValue="2026-06-27" />
344
+ ```
345
+
346
+ ### SearchInput
347
+ Search input with clear button.
348
+
349
+ ```tsx
350
+ <SearchInput value={query} onChange={handleSearch} onClear={() => setQuery('')} />
351
+ ```
352
+
353
+ ### ScanZone
354
+ Barcode/QR scan input area.
355
+
356
+ ```tsx
357
+ <ScanZone active onScan={handleAwbScan} placeholder="Scan AWB barcode" />
358
+ ```
359
+
360
+ ### Card, StatCard, Table, Badge, Avatar, Tag, Banner, Alert
361
+ Primary data display components for dashboard surfaces.
362
+
363
+ ```tsx
364
+ <Card shadow>
365
+ <CardHeader title="Shipment Summary" subtitle="AF-2026-00142" />
366
+ <CardBody>PVG to AMS, 482 kg electronics.</CardBody>
367
+ </Card>
368
+ ```
369
+
370
+ ### Tooltip, Popover, KV, DataList, EmptyState
371
+ Detail and contextual display helpers.
372
+
373
+ ```tsx
374
+ <DataList columns={2} items={[{ label: 'Reference', value: 'AF-2026-00142' }]} />
375
+ ```
376
+
377
+ ### ProgressBar, Donut, TrendSpark, CompareBar, Timeline, Accordion
378
+ Operational visualization components with no external chart dependency.
379
+
380
+ ```tsx
381
+ <ProgressBar value={72} label="Warehouse capacity" showPercent />
382
+ <TrendSpark data={[4, 8, 7, 10, 12]} />
383
+ ```
384
+
385
+ ### CopyButton
386
+ Copy-to-clipboard button.
387
+
388
+ | Prop | Type | Default | Description |
389
+ |---|---|---|---|
390
+ | value | `string` | required | Text to copy. |
391
+ | label | `string` | `'Copy'` | Default label. |
392
+ | copiedLabel | `string` | `'Copied'` | Success label. |
393
+
394
+ ```tsx
395
+ <CopyButton value="AF-2026-00142" label="Copy reference" />
396
+ ```
397
+
398
+ ### Toast / useToast
399
+ Toast notifications.
400
+
401
+ ```tsx
402
+ function SaveButton() {
403
+ const toast = useToast();
404
+ return <Button onClick={() => toast.success('Shipment saved')}>Save</Button>;
405
+ }
406
+ ```
407
+
408
+ ### Modal, Drawer, Spinner, Skeleton, ConfirmDialog
409
+ Feedback and overlay components.
410
+
411
+ ```tsx
412
+ <ConfirmDialog open={open} onClose={close} onConfirm={confirm} message="Delete shipment file?" danger />
413
+ ```
414
+
415
+ ### Icon
416
+ Icon renderer.
417
+
418
+ | Prop | Type | Default | Description |
419
+ |---|---|---|---|
420
+ | name | `string` | required | Icon name. |
421
+ | size | `number` | `16` | SVG size. |
422
+ | color | `string` | `undefined` | CSS color. |
423
+ | className | `string` | `undefined` | Custom class. |
424
+
425
+ ```tsx
426
+ <Icon name="Plane" size={20} />
427
+ ```
428
+
429
+ ## Design Tokens
430
+
431
+ `@ycc/ui` uses CSS custom properties from `src/tokens`. Import styles once:
432
+
433
+ ```tsx
434
+ import '@ycc/ui/styles';
435
+ ```
436
+
437
+ Override tokens globally:
438
+
439
+ ```css
440
+ :root {
441
+ --ycc-accent: #3B82F6;
442
+ --ycc-card: #FFFFFF;
443
+ }
444
+ ```
445
+
446
+ ## Theming
447
+
448
+ Global theme:
449
+
450
+ ```css
451
+ :root { --ycc-accent: #3B82F6; }
452
+ ```
453
+
454
+ Scoped theme:
455
+
456
+ ```css
457
+ .customs-dashboard { --ycc-accent: var(--ycc-branch-customs); }
458
+ ```
459
+
460
+ One-off component override:
461
+
462
+ ```tsx
463
+ <Card className="shipment-priority-card">Priority cargo</Card>
464
+ ```
465
+
466
+ ## Icon Reference
467
+
468
+ | Icon | Icon | Icon | Icon |
469
+ |---|---|---|---|
470
+ | Activity | AlertTriangle | ArrowLeft | ArrowLeftRight |
471
+ | ArrowRight | BarChart3 | Barcode | Bell |
472
+ | BellOff | BookOpen | Boxes | Briefcase |
473
+ | Cable | Calendar | Camera | Check |
474
+ | CheckCircle2 | ChevronDown | ChevronRight | ClipboardCheck |
475
+ | Clock | Copy | Cpu | Database |
476
+ | Download | Euro | FileCheck | FileSpreadsheet |
477
+ | FileText | Filter | Gauge | Globe |
478
+ | Hash | HelpCircle | Home | Image |
479
+ | Landmark | Layers | LayoutDashboard | LayoutGrid |
480
+ | LeafMark | Link2 | Lock | Mail |
481
+ | MapPin | Menu | PackageCheck | PackageOpen |
482
+ | PackageSearch | Pause | Pencil | Plane |
483
+ | PlaneLanding | PlaneTakeoff | Play | Plug |
484
+ | Plus | Power | Printer | Radio |
485
+ | Receipt | RefreshCw | RotateCcw | Route |
486
+ | Ruler | Scale | ScanLine | ScanSearch |
487
+ | Search | Send | Server | Settings |
488
+ | ShieldCheck | Ship | SlidersHorizontal | Split |
489
+ | Square | Tag | Tags | Trash2 |
490
+ | TrendingUp | Truck | Upload | Users |
491
+ | Wallet | Warehouse | Workflow | XCircle |
492
+ | Zap | | | |
493
+
494
+ ## Browser Support
495
+
496
+ Chrome 90+, Firefox 88+, Safari 14+, Edge 90+.
497
+
498
+ ## Contributing
499
+
500
+ Keep components typed, reusable, documented, and styled only through `--ycc-*` CSS variables.
501
+
502
+ ## License
503
+
504
+ MIT
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from 'react';
2
+ import './Accordion.css';
3
+ export interface AccordionProps {
4
+ items: Array<{
5
+ id: string;
6
+ title: string;
7
+ content: ReactNode;
8
+ }>;
9
+ defaultOpen?: string[];
10
+ }
11
+ export declare function Accordion({ items, defaultOpen }: AccordionProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=Accordion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/Accordion.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEjD,OAAO,iBAAiB,CAAC;AAEzB,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAChE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,WAAgB,EAAE,EAAE,cAAc,+BAuBpE"}
@@ -0,0 +1,9 @@
1
+ import './Avatar.css';
2
+ export interface AvatarProps {
3
+ src?: string;
4
+ name: string;
5
+ size?: 'sm' | 'md' | 'lg';
6
+ status?: 'online' | 'offline' | 'away';
7
+ }
8
+ export declare function Avatar({ src, name, size, status }: AvatarProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=Avatar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/Avatar.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CACxC;AAYD,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAW,EAAE,MAAM,EAAE,EAAE,WAAW,+BAOrE"}
@@ -0,0 +1,8 @@
1
+ import './Badge.css';
2
+ export interface BadgeProps {
3
+ label: string;
4
+ variant: string;
5
+ size?: 'sm' | 'md';
6
+ }
7
+ export declare function Badge({ label, variant, size }: BadgeProps): import("react").JSX.Element;
8
+ //# sourceMappingURL=Badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB;AAMD,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAW,EAAE,EAAE,UAAU,+BAOhE"}
@@ -0,0 +1,13 @@
1
+ import './Banner.css';
2
+ export interface BannerProps {
3
+ message: string;
4
+ variant?: 'info' | 'success' | 'warning' | 'danger';
5
+ title?: string;
6
+ onDismiss?: () => void;
7
+ action?: {
8
+ label: string;
9
+ onClick: () => void;
10
+ };
11
+ }
12
+ export declare function Banner({ message, variant, title, onDismiss, action }: BannerProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=Banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/Banner.tsx"],"names":[],"mappings":"AACA,OAAO,cAAc,CAAC;AAEtB,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CACjD;AAED,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,OAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,WAAW,+BAa1F"}
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from 'react';
2
+ import './Card.css';
3
+ export interface CardProps {
4
+ children: ReactNode;
5
+ className?: string;
6
+ padding?: 'none' | 'sm' | 'md' | 'lg';
7
+ shadow?: boolean;
8
+ }
9
+ export interface CardHeaderProps {
10
+ title: string;
11
+ subtitle?: string;
12
+ actions?: ReactNode;
13
+ icon?: string;
14
+ }
15
+ export interface CardBodyProps {
16
+ children: ReactNode;
17
+ className?: string;
18
+ }
19
+ export interface CardFooterProps {
20
+ children: ReactNode;
21
+ align?: 'left' | 'right' | 'between';
22
+ }
23
+ export declare function Card({ children, className, padding, shadow }: CardProps): import("react").JSX.Element;
24
+ export declare function CardHeader({ title, subtitle, actions, icon }: CardHeaderProps): import("react").JSX.Element;
25
+ export declare function CardBody({ children, className }: CardBodyProps): import("react").JSX.Element;
26
+ export declare function CardFooter({ children, align }: CardFooterProps): import("react").JSX.Element;
27
+ //# sourceMappingURL=Card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,YAAY,CAAC;AAEpB,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACtC;AAMD,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAc,EAAE,MAAM,EAAE,EAAE,SAAS,+BAE9E;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,eAAe,+BAa7E;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,aAAa,+BAE9D;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAe,EAAE,EAAE,eAAe,+BAExE"}
@@ -0,0 +1,10 @@
1
+ import './CompareBar.css';
2
+ export interface CompareBarProps {
3
+ labelA: string;
4
+ valueA: number;
5
+ labelB: string;
6
+ valueB: number;
7
+ color?: string;
8
+ }
9
+ export declare function CompareBar({ labelA, valueA, labelB, valueB, color }: CompareBarProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=CompareBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompareBar.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/CompareBar.tsx"],"names":[],"mappings":"AACA,OAAO,kBAAkB,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAA2B,EAAE,EAAE,eAAe,+BAc1G"}
@@ -0,0 +1,8 @@
1
+ import './CopyButton.css';
2
+ export interface CopyButtonProps {
3
+ value: string;
4
+ label?: string;
5
+ copiedLabel?: string;
6
+ }
7
+ export declare function CopyButton({ value, label, copiedLabel }: CopyButtonProps): import("react").JSX.Element;
8
+ //# sourceMappingURL=CopyButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyButton.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/CopyButton.tsx"],"names":[],"mappings":"AAEA,OAAO,kBAAkB,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAc,EAAE,WAAsB,EAAE,EAAE,eAAe,+BAe5F"}
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ import './DataList.css';
3
+ export interface DataListProps {
4
+ items: Array<{
5
+ label: string;
6
+ value: ReactNode;
7
+ }>;
8
+ columns?: 1 | 2 | 3;
9
+ }
10
+ export declare function DataList({ items, columns }: DataListProps): import("react").JSX.Element;
11
+ //# sourceMappingURL=DataList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataList.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/DataList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,gBAAgB,CAAC;AAExB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAClD,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CACrB;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAW,EAAE,EAAE,aAAa,+BAW7D"}
@@ -0,0 +1,10 @@
1
+ import './Donut.css';
2
+ export interface DonutProps {
3
+ value: number;
4
+ max?: number;
5
+ size?: number;
6
+ color?: string;
7
+ label?: string;
8
+ }
9
+ export declare function Donut({ value, max, size, color, label }: DonutProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=Donut.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Donut.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/Donut.tsx"],"names":[],"mappings":"AACA,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,GAAS,EAAE,IAAS,EAAE,KAA2B,EAAE,KAAK,EAAE,EAAE,UAAU,+BAepG"}
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from 'react';
2
+ import './EmptyState.css';
3
+ export interface EmptyStateProps {
4
+ icon?: string;
5
+ title: string;
6
+ message?: string;
7
+ action?: ReactNode;
8
+ }
9
+ export declare function EmptyState({ icon, title, message, action }: EmptyStateProps): import("react").JSX.Element;
10
+ //# sourceMappingURL=EmptyState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmptyState.d.ts","sourceRoot":"","sources":["../../../src/components/DataDisplay/EmptyState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,kBAAkB,CAAC;AAE1B,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe,+BASrF"}
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from 'react';
2
+ import './KV.css';
3
+ export interface KVProps {
4
+ label: string;
5
+ value: ReactNode;
6
+ size?: 'sm' | 'md';
7
+ }
8
+ export declare function KV({ label, value, size }: KVProps): import("react").JSX.Element;
9
+ //# sourceMappingURL=KV.d.ts.map