@delightui/components 0.1.104 → 0.1.106
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 +104 -1
- package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
- package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
- package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
- package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
- package/dist/cjs/components/molecules/index.d.ts +2 -0
- package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/cjs/components/utils/index.d.ts +2 -0
- package/dist/cjs/library.css +13 -0
- package/dist/cjs/library.js +2 -2
- package/dist/cjs/library.js.map +1 -1
- package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
- package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
- package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
- package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/esm/components/molecules/Select/index.d.ts +2 -9
- package/dist/esm/components/molecules/index.d.ts +2 -0
- package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/esm/components/utils/index.d.ts +2 -0
- package/dist/esm/library.css +13 -0
- package/dist/esm/library.js +3 -3
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +156 -12
- package/docs/README.md +264 -0
- package/docs/components/atoms/ActionImage.md +119 -0
- package/docs/components/atoms/Button.md +197 -0
- package/docs/components/atoms/Checkbox.md +299 -0
- package/docs/components/atoms/CheckboxItem.md +314 -0
- package/docs/components/atoms/Chip.md +380 -0
- package/docs/components/atoms/CustomToggle.md +270 -0
- package/docs/components/atoms/Icon.md +365 -0
- package/docs/components/atoms/IconButton.md +407 -0
- package/docs/components/atoms/Image.md +448 -0
- package/docs/components/atoms/Input.md +430 -0
- package/docs/components/atoms/ListItem.md +502 -0
- package/docs/components/atoms/Password.md +472 -0
- package/docs/components/atoms/RadioButton.md +614 -0
- package/docs/components/atoms/RadioButtonItem.md +588 -0
- package/docs/components/atoms/ResponsiveComponent.md +612 -0
- package/docs/components/atoms/SelectListItem.md +609 -0
- package/docs/components/atoms/Slider.md +605 -0
- package/docs/components/atoms/Spinner.md +605 -0
- package/docs/components/atoms/Text.md +463 -0
- package/docs/components/atoms/TextArea.md +670 -0
- package/docs/components/atoms/ToastNotification.md +668 -0
- package/docs/components/atoms/Toggle.md +737 -0
- package/docs/components/atoms/ToggleButton.md +751 -0
- package/docs/components/atoms/Tooltip.md +391 -0
- package/docs/components/molecules/Accordion.md +440 -0
- package/docs/components/molecules/AccordionGroup.md +547 -0
- package/docs/components/molecules/ActionCard.md +546 -0
- package/docs/components/molecules/Breadcrumb.md +403 -0
- package/docs/components/molecules/Breadcrumbs.md +485 -0
- package/docs/components/molecules/ButtonGroup.md +383 -0
- package/docs/components/molecules/Card.md +298 -0
- package/docs/components/molecules/ChipInput.md +646 -0
- package/docs/components/molecules/ContextMenu.md +768 -0
- package/docs/components/molecules/CustomTimeSelector.md +116 -0
- package/docs/components/molecules/DatePicker.md +516 -0
- package/docs/components/molecules/DateTimeSelector.md +166 -0
- package/docs/components/molecules/FormField.md +312 -0
- package/docs/components/molecules/Grid.md +577 -0
- package/docs/components/molecules/GridItem.md +834 -0
- package/docs/components/molecules/GridList.md +244 -0
- package/docs/components/molecules/List.md +485 -0
- package/docs/components/molecules/Modal.md +470 -0
- package/docs/components/molecules/ModalFooter.md +702 -0
- package/docs/components/molecules/ModalHeader.md +756 -0
- package/docs/components/molecules/ModalProvider.md +205 -0
- package/docs/components/molecules/Nav.md +530 -0
- package/docs/components/molecules/NavItem.md +572 -0
- package/docs/components/molecules/NavLink.md +499 -0
- package/docs/components/molecules/Option.md +521 -0
- package/docs/components/molecules/Pagination.md +592 -0
- package/docs/components/molecules/PaginationNumberField.md +722 -0
- package/docs/components/molecules/Popover.md +516 -0
- package/docs/components/molecules/ProgressBar.md +624 -0
- package/docs/components/molecules/RadioGroup.md +831 -0
- package/docs/components/molecules/RepeaterList.md +185 -0
- package/docs/components/molecules/Select.md +402 -0
- package/docs/components/molecules/SortableTrigger.md +82 -0
- package/docs/components/molecules/useModal.md +379 -0
- package/docs/components/organisms/Dropzone.md +346 -0
- package/docs/components/organisms/DropzoneClear.md +135 -0
- package/docs/components/organisms/DropzoneContent.md +216 -0
- package/docs/components/organisms/DropzoneFilename.md +191 -0
- package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
- package/docs/components/organisms/DropzoneTrigger.md +209 -0
- package/docs/components/organisms/Form.md +533 -0
- package/docs/components/organisms/SlideOutPanel.md +662 -0
- package/docs/components/organisms/TabContent.md +902 -0
- package/docs/components/organisms/TabItem.md +1091 -0
- package/docs/components/organisms/Table.md +611 -0
- package/docs/components/organisms/TableBody.md +679 -0
- package/docs/components/organisms/TableCell.md +482 -0
- package/docs/components/organisms/TableHeader.md +513 -0
- package/docs/components/organisms/TableHeaderCell.md +661 -0
- package/docs/components/organisms/TableRow.md +715 -0
- package/docs/components/organisms/Tabs.md +1330 -0
- package/docs/components/utils/ConditionalView.md +568 -0
- package/docs/components/utils/RenderStateView.md +726 -0
- package/docs/components/utils/WrapTextNodes.md +614 -0
- package/package.json +3 -2
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
# Nav
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
A navigation container component that provides semantic structure for navigation menus and lists. Serves as a flexible wrapper for organizing navigation items, links, and other navigation-related content with proper accessibility semantics and keyboard navigation support.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- Nav
|
|
10
|
+
- Navigation
|
|
11
|
+
- NavContainer
|
|
12
|
+
- NavigationMenu
|
|
13
|
+
- NavBar
|
|
14
|
+
|
|
15
|
+
## Props Breakdown
|
|
16
|
+
|
|
17
|
+
**Extends:** `HTMLAttributes<HTMLElement>`
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Required | Description |
|
|
20
|
+
|------|------|---------|----------|-------------|
|
|
21
|
+
| `children` | `ReactNode` | - | Yes | Navigation items, links, or other content to display |
|
|
22
|
+
| `className` | `string` | - | No | Additional CSS class names for custom styling |
|
|
23
|
+
| `role` | `string` | `'navigation'` | No | ARIA role for accessibility |
|
|
24
|
+
| `aria-label` | `string` | - | No | Accessible label for screen readers |
|
|
25
|
+
|
|
26
|
+
Plus all standard HTML element attributes (`id`, `style`, `onClick`, etc.).
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
### Basic Usage
|
|
31
|
+
```tsx
|
|
32
|
+
import { Nav, NavItem, NavLink } from '@delightui/components';
|
|
33
|
+
|
|
34
|
+
function BasicExample() {
|
|
35
|
+
return (
|
|
36
|
+
<Nav aria-label="Main navigation">
|
|
37
|
+
<NavItem>
|
|
38
|
+
<NavLink to="/home">Home</NavLink>
|
|
39
|
+
</NavItem>
|
|
40
|
+
<NavItem>
|
|
41
|
+
<NavLink to="/about">About</NavLink>
|
|
42
|
+
</NavItem>
|
|
43
|
+
<NavItem>
|
|
44
|
+
<NavLink to="/contact">Contact</NavLink>
|
|
45
|
+
</NavItem>
|
|
46
|
+
</Nav>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Horizontal Navigation Bar
|
|
52
|
+
```tsx
|
|
53
|
+
function HorizontalNavExample() {
|
|
54
|
+
return (
|
|
55
|
+
<Nav className="horizontal-nav" aria-label="Primary navigation">
|
|
56
|
+
<NavItem>
|
|
57
|
+
<NavLink to="/" leadingIcon={<Icon icon="Home" />}>
|
|
58
|
+
Dashboard
|
|
59
|
+
</NavLink>
|
|
60
|
+
</NavItem>
|
|
61
|
+
<NavItem>
|
|
62
|
+
<NavLink to="/projects" leadingIcon={<Icon icon="Folder" />}>
|
|
63
|
+
Projects
|
|
64
|
+
</NavLink>
|
|
65
|
+
</NavItem>
|
|
66
|
+
<NavItem>
|
|
67
|
+
<NavLink to="/team" leadingIcon={<Icon icon="People" />}>
|
|
68
|
+
Team
|
|
69
|
+
</NavLink>
|
|
70
|
+
</NavItem>
|
|
71
|
+
<NavItem>
|
|
72
|
+
<NavLink to="/settings" leadingIcon={<Icon icon="Settings" />}>
|
|
73
|
+
Settings
|
|
74
|
+
</NavLink>
|
|
75
|
+
</NavItem>
|
|
76
|
+
</Nav>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Vertical Sidebar Navigation
|
|
82
|
+
```tsx
|
|
83
|
+
function SidebarNavExample() {
|
|
84
|
+
const [activeSection, setActiveSection] = useState('dashboard');
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Nav className="sidebar-nav" aria-label="Sidebar navigation">
|
|
88
|
+
<NavItem>
|
|
89
|
+
<NavLink
|
|
90
|
+
to="/dashboard"
|
|
91
|
+
className={activeSection === 'dashboard' ? 'active' : ''}
|
|
92
|
+
leadingIcon={<Icon icon="Dashboard" />}
|
|
93
|
+
>
|
|
94
|
+
Dashboard
|
|
95
|
+
</NavLink>
|
|
96
|
+
</NavItem>
|
|
97
|
+
|
|
98
|
+
<NavItem>
|
|
99
|
+
<NavLink
|
|
100
|
+
to="/analytics"
|
|
101
|
+
className={activeSection === 'analytics' ? 'active' : ''}
|
|
102
|
+
leadingIcon={<Icon icon="Analytics" />}
|
|
103
|
+
>
|
|
104
|
+
Analytics
|
|
105
|
+
</NavLink>
|
|
106
|
+
</NavItem>
|
|
107
|
+
|
|
108
|
+
<NavItem>
|
|
109
|
+
<NavLink
|
|
110
|
+
to="/reports"
|
|
111
|
+
className={activeSection === 'reports' ? 'active' : ''}
|
|
112
|
+
leadingIcon={<Icon icon="Report" />}
|
|
113
|
+
>
|
|
114
|
+
Reports
|
|
115
|
+
</NavLink>
|
|
116
|
+
</NavItem>
|
|
117
|
+
|
|
118
|
+
<NavItem>
|
|
119
|
+
<NavLink
|
|
120
|
+
to="/users"
|
|
121
|
+
className={activeSection === 'users' ? 'active' : ''}
|
|
122
|
+
leadingIcon={<Icon icon="Person" />}
|
|
123
|
+
>
|
|
124
|
+
Users
|
|
125
|
+
</NavLink>
|
|
126
|
+
</NavItem>
|
|
127
|
+
</Nav>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Navigation with Nested Sections
|
|
133
|
+
```tsx
|
|
134
|
+
function NestedNavExample() {
|
|
135
|
+
const [expandedSections, setExpandedSections] = useState(new Set());
|
|
136
|
+
|
|
137
|
+
const toggleSection = (section) => {
|
|
138
|
+
const newExpanded = new Set(expandedSections);
|
|
139
|
+
if (newExpanded.has(section)) {
|
|
140
|
+
newExpanded.delete(section);
|
|
141
|
+
} else {
|
|
142
|
+
newExpanded.add(section);
|
|
143
|
+
}
|
|
144
|
+
setExpandedSections(newExpanded);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<Nav className="nested-nav" aria-label="Application navigation">
|
|
149
|
+
<NavItem>
|
|
150
|
+
<NavLink to="/dashboard">Dashboard</NavLink>
|
|
151
|
+
</NavItem>
|
|
152
|
+
|
|
153
|
+
<NavItem>
|
|
154
|
+
<Button
|
|
155
|
+
type="Ghost"
|
|
156
|
+
onClick={() => toggleSection('content')}
|
|
157
|
+
trailingIcon={
|
|
158
|
+
<Icon
|
|
159
|
+
icon={expandedSections.has('content') ? 'ExpandLess' : 'ExpandMore'}
|
|
160
|
+
/>
|
|
161
|
+
}
|
|
162
|
+
>
|
|
163
|
+
Content Management
|
|
164
|
+
</Button>
|
|
165
|
+
|
|
166
|
+
{expandedSections.has('content') && (
|
|
167
|
+
<Nav className="nested-nav-items">
|
|
168
|
+
<NavItem>
|
|
169
|
+
<NavLink to="/content/posts">Posts</NavLink>
|
|
170
|
+
</NavItem>
|
|
171
|
+
<NavItem>
|
|
172
|
+
<NavLink to="/content/pages">Pages</NavLink>
|
|
173
|
+
</NavItem>
|
|
174
|
+
<NavItem>
|
|
175
|
+
<NavLink to="/content/media">Media</NavLink>
|
|
176
|
+
</NavItem>
|
|
177
|
+
</Nav>
|
|
178
|
+
)}
|
|
179
|
+
</NavItem>
|
|
180
|
+
|
|
181
|
+
<NavItem>
|
|
182
|
+
<Button
|
|
183
|
+
type="Ghost"
|
|
184
|
+
onClick={() => toggleSection('admin')}
|
|
185
|
+
trailingIcon={
|
|
186
|
+
<Icon
|
|
187
|
+
icon={expandedSections.has('admin') ? 'ExpandLess' : 'ExpandMore'}
|
|
188
|
+
/>
|
|
189
|
+
}
|
|
190
|
+
>
|
|
191
|
+
Administration
|
|
192
|
+
</Button>
|
|
193
|
+
|
|
194
|
+
{expandedSections.has('admin') && (
|
|
195
|
+
<Nav className="nested-nav-items">
|
|
196
|
+
<NavItem>
|
|
197
|
+
<NavLink to="/admin/users">User Management</NavLink>
|
|
198
|
+
</NavItem>
|
|
199
|
+
<NavItem>
|
|
200
|
+
<NavLink to="/admin/roles">Roles & Permissions</NavLink>
|
|
201
|
+
</NavItem>
|
|
202
|
+
<NavItem>
|
|
203
|
+
<NavLink to="/admin/system">System Settings</NavLink>
|
|
204
|
+
</NavItem>
|
|
205
|
+
</Nav>
|
|
206
|
+
)}
|
|
207
|
+
</NavItem>
|
|
208
|
+
</Nav>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Responsive Navigation
|
|
214
|
+
```tsx
|
|
215
|
+
function ResponsiveNavExample() {
|
|
216
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
217
|
+
|
|
218
|
+
return (
|
|
219
|
+
<>
|
|
220
|
+
{/* Mobile Menu Toggle */}
|
|
221
|
+
<Button
|
|
222
|
+
className="mobile-menu-toggle"
|
|
223
|
+
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
|
224
|
+
aria-label="Toggle navigation menu"
|
|
225
|
+
>
|
|
226
|
+
<Icon icon={isMobileMenuOpen ? 'Close' : 'Menu'} />
|
|
227
|
+
</Button>
|
|
228
|
+
|
|
229
|
+
{/* Navigation */}
|
|
230
|
+
<Nav
|
|
231
|
+
className={`responsive-nav ${isMobileMenuOpen ? 'mobile-open' : ''}`}
|
|
232
|
+
aria-label="Main navigation"
|
|
233
|
+
>
|
|
234
|
+
<NavItem>
|
|
235
|
+
<NavLink to="/" onClick={() => setIsMobileMenuOpen(false)}>
|
|
236
|
+
Home
|
|
237
|
+
</NavLink>
|
|
238
|
+
</NavItem>
|
|
239
|
+
<NavItem>
|
|
240
|
+
<NavLink to="/products" onClick={() => setIsMobileMenuOpen(false)}>
|
|
241
|
+
Products
|
|
242
|
+
</NavLink>
|
|
243
|
+
</NavItem>
|
|
244
|
+
<NavItem>
|
|
245
|
+
<NavLink to="/services" onClick={() => setIsMobileMenuOpen(false)}>
|
|
246
|
+
Services
|
|
247
|
+
</NavLink>
|
|
248
|
+
</NavItem>
|
|
249
|
+
<NavItem>
|
|
250
|
+
<NavLink to="/about" onClick={() => setIsMobileMenuOpen(false)}>
|
|
251
|
+
About
|
|
252
|
+
</NavLink>
|
|
253
|
+
</NavItem>
|
|
254
|
+
<NavItem>
|
|
255
|
+
<NavLink to="/contact" onClick={() => setIsMobileMenuOpen(false)}>
|
|
256
|
+
Contact
|
|
257
|
+
</NavLink>
|
|
258
|
+
</NavItem>
|
|
259
|
+
</Nav>
|
|
260
|
+
</>
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Navigation with User Actions
|
|
266
|
+
```tsx
|
|
267
|
+
function UserActionNavExample() {
|
|
268
|
+
const [user, setUser] = useState({
|
|
269
|
+
name: 'John Doe',
|
|
270
|
+
avatar: '/user-avatar.jpg'
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
return (
|
|
274
|
+
<Nav className="header-nav" aria-label="User navigation">
|
|
275
|
+
{/* Main Navigation */}
|
|
276
|
+
<div className="nav-section">
|
|
277
|
+
<NavItem>
|
|
278
|
+
<NavLink to="/dashboard">Dashboard</NavLink>
|
|
279
|
+
</NavItem>
|
|
280
|
+
<NavItem>
|
|
281
|
+
<NavLink to="/projects">Projects</NavLink>
|
|
282
|
+
</NavItem>
|
|
283
|
+
<NavItem>
|
|
284
|
+
<NavLink to="/tasks">Tasks</NavLink>
|
|
285
|
+
</NavItem>
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
{/* User Actions */}
|
|
289
|
+
<div className="nav-section user-actions">
|
|
290
|
+
<NavItem>
|
|
291
|
+
<Button type="Ghost" leadingIcon={<Icon icon="Notifications" />}>
|
|
292
|
+
<Text>3</Text>
|
|
293
|
+
</Button>
|
|
294
|
+
</NavItem>
|
|
295
|
+
|
|
296
|
+
<NavItem>
|
|
297
|
+
<Button type="Ghost" leadingIcon={<Icon icon="Search" />}>
|
|
298
|
+
Search
|
|
299
|
+
</Button>
|
|
300
|
+
</NavItem>
|
|
301
|
+
|
|
302
|
+
<NavItem>
|
|
303
|
+
<ContextMenu
|
|
304
|
+
trigger={
|
|
305
|
+
<Button type="Ghost">
|
|
306
|
+
<Image src={user.avatar} alt={user.name} size="Small" />
|
|
307
|
+
<Text>{user.name}</Text>
|
|
308
|
+
<Icon icon="ExpandMore" />
|
|
309
|
+
</Button>
|
|
310
|
+
}
|
|
311
|
+
>
|
|
312
|
+
<NavLink to="/profile">Profile</NavLink>
|
|
313
|
+
<NavLink to="/settings">Settings</NavLink>
|
|
314
|
+
<NavLink to="/help">Help</NavLink>
|
|
315
|
+
<hr />
|
|
316
|
+
<NavLink to="/logout">Sign Out</NavLink>
|
|
317
|
+
</ContextMenu>
|
|
318
|
+
</NavItem>
|
|
319
|
+
</div>
|
|
320
|
+
</Nav>
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Tab Navigation
|
|
326
|
+
```tsx
|
|
327
|
+
function TabNavExample() {
|
|
328
|
+
const [activeTab, setActiveTab] = useState('overview');
|
|
329
|
+
|
|
330
|
+
const tabs = [
|
|
331
|
+
{ id: 'overview', label: 'Overview', icon: 'Dashboard' },
|
|
332
|
+
{ id: 'activity', label: 'Activity', icon: 'Timeline' },
|
|
333
|
+
{ id: 'settings', label: 'Settings', icon: 'Settings' },
|
|
334
|
+
{ id: 'billing', label: 'Billing', icon: 'CreditCard' }
|
|
335
|
+
];
|
|
336
|
+
|
|
337
|
+
return (
|
|
338
|
+
<Nav className="tab-nav" role="tablist" aria-label="Account sections">
|
|
339
|
+
{tabs.map(tab => (
|
|
340
|
+
<NavItem key={tab.id} role="none">
|
|
341
|
+
<NavLink
|
|
342
|
+
to={`/account/${tab.id}`}
|
|
343
|
+
role="tab"
|
|
344
|
+
aria-selected={activeTab === tab.id}
|
|
345
|
+
className={activeTab === tab.id ? 'active' : ''}
|
|
346
|
+
onClick={() => setActiveTab(tab.id)}
|
|
347
|
+
leadingIcon={<Icon icon={tab.icon} />}
|
|
348
|
+
>
|
|
349
|
+
{tab.label}
|
|
350
|
+
</NavLink>
|
|
351
|
+
</NavItem>
|
|
352
|
+
))}
|
|
353
|
+
</Nav>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Breadcrumb Navigation
|
|
359
|
+
```tsx
|
|
360
|
+
function BreadcrumbNavExample() {
|
|
361
|
+
const breadcrumbs = [
|
|
362
|
+
{ label: 'Home', to: '/' },
|
|
363
|
+
{ label: 'Products', to: '/products' },
|
|
364
|
+
{ label: 'Electronics', to: '/products/electronics' },
|
|
365
|
+
{ label: 'Smartphones', to: '/products/electronics/smartphones' },
|
|
366
|
+
{ label: 'iPhone 14', to: null } // Current page
|
|
367
|
+
];
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<Nav className="breadcrumb-nav" aria-label="Breadcrumb navigation">
|
|
371
|
+
{breadcrumbs.map((crumb, index) => (
|
|
372
|
+
<NavItem key={index} className="breadcrumb-item">
|
|
373
|
+
{crumb.to ? (
|
|
374
|
+
<NavLink to={crumb.to}>{crumb.label}</NavLink>
|
|
375
|
+
) : (
|
|
376
|
+
<Text className="current-page">{crumb.label}</Text>
|
|
377
|
+
)}
|
|
378
|
+
|
|
379
|
+
{index < breadcrumbs.length - 1 && (
|
|
380
|
+
<Icon icon="ChevronRight" className="breadcrumb-separator" />
|
|
381
|
+
)}
|
|
382
|
+
</NavItem>
|
|
383
|
+
))}
|
|
384
|
+
</Nav>
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Pagination Navigation
|
|
390
|
+
```tsx
|
|
391
|
+
function PaginationNavExample() {
|
|
392
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
393
|
+
const totalPages = 10;
|
|
394
|
+
const maxVisiblePages = 5;
|
|
395
|
+
|
|
396
|
+
const getVisiblePages = () => {
|
|
397
|
+
const start = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
|
|
398
|
+
const end = Math.min(totalPages, start + maxVisiblePages - 1);
|
|
399
|
+
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
return (
|
|
403
|
+
<Nav className="pagination-nav" aria-label="Pagination navigation">
|
|
404
|
+
<NavItem>
|
|
405
|
+
<Button
|
|
406
|
+
disabled={currentPage === 1}
|
|
407
|
+
onClick={() => setCurrentPage(1)}
|
|
408
|
+
aria-label="Go to first page"
|
|
409
|
+
>
|
|
410
|
+
<Icon icon="FirstPage" />
|
|
411
|
+
</Button>
|
|
412
|
+
</NavItem>
|
|
413
|
+
|
|
414
|
+
<NavItem>
|
|
415
|
+
<Button
|
|
416
|
+
disabled={currentPage === 1}
|
|
417
|
+
onClick={() => setCurrentPage(currentPage - 1)}
|
|
418
|
+
aria-label="Go to previous page"
|
|
419
|
+
>
|
|
420
|
+
<Icon icon="ChevronLeft" />
|
|
421
|
+
</Button>
|
|
422
|
+
</NavItem>
|
|
423
|
+
|
|
424
|
+
{getVisiblePages().map(page => (
|
|
425
|
+
<NavItem key={page}>
|
|
426
|
+
<Button
|
|
427
|
+
type={currentPage === page ? 'Filled' : 'Ghost'}
|
|
428
|
+
onClick={() => setCurrentPage(page)}
|
|
429
|
+
aria-label={`Go to page ${page}`}
|
|
430
|
+
aria-current={currentPage === page ? 'page' : undefined}
|
|
431
|
+
>
|
|
432
|
+
{page}
|
|
433
|
+
</Button>
|
|
434
|
+
</NavItem>
|
|
435
|
+
))}
|
|
436
|
+
|
|
437
|
+
<NavItem>
|
|
438
|
+
<Button
|
|
439
|
+
disabled={currentPage === totalPages}
|
|
440
|
+
onClick={() => setCurrentPage(currentPage + 1)}
|
|
441
|
+
aria-label="Go to next page"
|
|
442
|
+
>
|
|
443
|
+
<Icon icon="ChevronRight" />
|
|
444
|
+
</Button>
|
|
445
|
+
</NavItem>
|
|
446
|
+
|
|
447
|
+
<NavItem>
|
|
448
|
+
<Button
|
|
449
|
+
disabled={currentPage === totalPages}
|
|
450
|
+
onClick={() => setCurrentPage(totalPages)}
|
|
451
|
+
aria-label="Go to last page"
|
|
452
|
+
>
|
|
453
|
+
<Icon icon="LastPage" />
|
|
454
|
+
</Button>
|
|
455
|
+
</NavItem>
|
|
456
|
+
</Nav>
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Custom Styled Navigation
|
|
462
|
+
```tsx
|
|
463
|
+
function CustomStyledNavExample() {
|
|
464
|
+
return (
|
|
465
|
+
<Nav
|
|
466
|
+
className="custom-nav"
|
|
467
|
+
style={{
|
|
468
|
+
display: 'flex',
|
|
469
|
+
gap: '1rem',
|
|
470
|
+
padding: '1rem',
|
|
471
|
+
backgroundColor: 'var(--color-surface-elevated)',
|
|
472
|
+
borderRadius: '8px',
|
|
473
|
+
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)'
|
|
474
|
+
}}
|
|
475
|
+
aria-label="Custom navigation"
|
|
476
|
+
>
|
|
477
|
+
<NavItem>
|
|
478
|
+
<NavLink
|
|
479
|
+
to="/dashboard"
|
|
480
|
+
style={{
|
|
481
|
+
display: 'flex',
|
|
482
|
+
alignItems: 'center',
|
|
483
|
+
gap: '0.5rem',
|
|
484
|
+
padding: '0.75rem 1rem',
|
|
485
|
+
borderRadius: '6px',
|
|
486
|
+
transition: 'all 0.2s ease'
|
|
487
|
+
}}
|
|
488
|
+
leadingIcon={<Icon icon="Dashboard" />}
|
|
489
|
+
>
|
|
490
|
+
Dashboard
|
|
491
|
+
</NavLink>
|
|
492
|
+
</NavItem>
|
|
493
|
+
|
|
494
|
+
<NavItem>
|
|
495
|
+
<NavLink
|
|
496
|
+
to="/analytics"
|
|
497
|
+
style={{
|
|
498
|
+
display: 'flex',
|
|
499
|
+
alignItems: 'center',
|
|
500
|
+
gap: '0.5rem',
|
|
501
|
+
padding: '0.75rem 1rem',
|
|
502
|
+
borderRadius: '6px',
|
|
503
|
+
transition: 'all 0.2s ease'
|
|
504
|
+
}}
|
|
505
|
+
leadingIcon={<Icon icon="BarChart" />}
|
|
506
|
+
>
|
|
507
|
+
Analytics
|
|
508
|
+
</NavLink>
|
|
509
|
+
</NavItem>
|
|
510
|
+
|
|
511
|
+
<NavItem>
|
|
512
|
+
<NavLink
|
|
513
|
+
to="/reports"
|
|
514
|
+
style={{
|
|
515
|
+
display: 'flex',
|
|
516
|
+
alignItems: 'center',
|
|
517
|
+
gap: '0.5rem',
|
|
518
|
+
padding: '0.75rem 1rem',
|
|
519
|
+
borderRadius: '6px',
|
|
520
|
+
transition: 'all 0.2s ease'
|
|
521
|
+
}}
|
|
522
|
+
leadingIcon={<Icon icon="Description" />}
|
|
523
|
+
>
|
|
524
|
+
Reports
|
|
525
|
+
</NavLink>
|
|
526
|
+
</NavItem>
|
|
527
|
+
</Nav>
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
```
|