@ceed/cds 1.19.0 → 1.19.1-next.1
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/components/data-display/Markdown.md +832 -0
- package/dist/components/feedback/Dialog.md +605 -3
- package/dist/components/feedback/Modal.md +559 -5
- package/dist/components/feedback/llms.txt +1 -1
- package/dist/components/inputs/Autocomplete.md +734 -2
- package/dist/components/inputs/Calendar.md +655 -1
- package/dist/components/inputs/DatePicker.md +699 -3
- package/dist/components/inputs/DateRangePicker.md +815 -1
- package/dist/components/inputs/MonthPicker.md +626 -4
- package/dist/components/inputs/MonthRangePicker.md +682 -4
- package/dist/components/inputs/Select.md +600 -0
- package/dist/components/layout/Container.md +507 -0
- package/dist/components/navigation/Breadcrumbs.md +470 -0
- package/dist/components/navigation/IconMenuButton.md +693 -0
- package/dist/components/navigation/InsetDrawer.md +775 -118
- package/dist/components/navigation/Link.md +434 -0
- package/dist/components/navigation/MenuButton.md +632 -0
- package/dist/components/navigation/NavigationGroup.md +401 -1
- package/dist/components/navigation/NavigationItem.md +311 -0
- package/dist/components/navigation/Navigator.md +373 -0
- package/dist/components/navigation/Pagination.md +532 -2
- package/dist/components/navigation/Tabs.md +466 -7
- package/dist/components/surfaces/Accordions.md +947 -3
- package/dist/index.cjs +3 -1
- package/dist/index.js +3 -1
- package/dist/llms.txt +1 -1
- package/framer/index.js +16 -16
- package/package.json +3 -2
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
+
The Link component is a navigational element that allows users to navigate between pages or external resources. Built on Joy UI's Link, it provides consistent styling and accessibility features while supporting various visual styles and text hierarchy levels. Links are fundamental to web navigation and should be used to connect related content within your application.
|
|
6
|
+
|
|
5
7
|
```tsx
|
|
6
8
|
<Link
|
|
7
9
|
children="Link"
|
|
@@ -21,4 +23,436 @@
|
|
|
21
23
|
|
|
22
24
|
```tsx
|
|
23
25
|
import { Link } from '@ceed/cds';
|
|
26
|
+
|
|
27
|
+
function MyComponent() {
|
|
28
|
+
return (
|
|
29
|
+
<div>
|
|
30
|
+
{/* Basic link */}
|
|
31
|
+
<Link href="/about">About Us</Link>
|
|
32
|
+
|
|
33
|
+
{/* External link */}
|
|
34
|
+
<Link href="https://example.com" target="_blank" rel="noopener noreferrer">
|
|
35
|
+
External Site
|
|
36
|
+
</Link>
|
|
37
|
+
|
|
38
|
+
{/* Styled link */}
|
|
39
|
+
<Link href="/contact" color="primary" underline="hover">
|
|
40
|
+
Contact
|
|
41
|
+
</Link>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
### Basic Link
|
|
50
|
+
|
|
51
|
+
The default link appearance with plain variant.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
<Link
|
|
55
|
+
children="Link"
|
|
56
|
+
variant="plain"
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Variants
|
|
61
|
+
|
|
62
|
+
Links support different visual styles through the variant prop.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
<Canvas of={Link.Variants} />
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Colors
|
|
69
|
+
|
|
70
|
+
Apply different semantic colors to links.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
<Canvas of={Link.Colors} />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Underline Styles
|
|
77
|
+
|
|
78
|
+
Control the underline behavior of links.
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
<Canvas of={Link.Underline} />
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Typography Levels
|
|
85
|
+
|
|
86
|
+
Links can inherit or specify typography levels for different text hierarchies.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
<Canvas of={Link.Levels} />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Disabled State
|
|
93
|
+
|
|
94
|
+
Links can be disabled to prevent interaction.
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
<Canvas of={Link.Disabled} />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### External Links
|
|
101
|
+
|
|
102
|
+
Links to external resources with proper security attributes.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
<Canvas of={Link.ExternalLink} />
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Inline with Text
|
|
109
|
+
|
|
110
|
+
Links can be seamlessly integrated within paragraph text.
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
<Canvas of={Link.InlineWithText} />
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## When to Use
|
|
117
|
+
|
|
118
|
+
### ✅ Good Use Cases
|
|
119
|
+
|
|
120
|
+
- **Page navigation**: Moving between different pages or sections within your app
|
|
121
|
+
- **External resources**: Linking to external websites, documentation, or references
|
|
122
|
+
- **In-context references**: Linking related content mentioned in text
|
|
123
|
+
- **Skip navigation**: Accessibility links for keyboard users
|
|
124
|
+
- **Breadcrumbs**: Navigation hierarchy indicators
|
|
125
|
+
- **Footer navigation**: Site-wide links in footer sections
|
|
126
|
+
|
|
127
|
+
### ❌ When Not to Use
|
|
128
|
+
|
|
129
|
+
- **Actions that don't navigate**: Use Button instead for actions like submitting forms, opening modals, or triggering events
|
|
130
|
+
- **Primary calls to action**: Use Button for prominent actions users should take
|
|
131
|
+
- **Menu items**: Use MenuItem components within navigation menus
|
|
132
|
+
- **Tab navigation**: Use Tabs component for content switching within a page
|
|
133
|
+
- **Cards/clickable areas**: Use Card with onClick or a wrapping anchor element
|
|
134
|
+
|
|
135
|
+
## Common Use Cases
|
|
136
|
+
|
|
137
|
+
### Navigation Menu Links
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
function NavigationMenu() {
|
|
141
|
+
return (
|
|
142
|
+
<nav>
|
|
143
|
+
<Stack direction="row" spacing={3}>
|
|
144
|
+
<Link href="/" color="neutral" underline="none">
|
|
145
|
+
Home
|
|
146
|
+
</Link>
|
|
147
|
+
<Link href="/products" color="neutral" underline="none">
|
|
148
|
+
Products
|
|
149
|
+
</Link>
|
|
150
|
+
<Link href="/about" color="neutral" underline="none">
|
|
151
|
+
About
|
|
152
|
+
</Link>
|
|
153
|
+
<Link href="/contact" color="neutral" underline="none">
|
|
154
|
+
Contact
|
|
155
|
+
</Link>
|
|
156
|
+
</Stack>
|
|
157
|
+
</nav>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Inline Text Links
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
function ArticleContent() {
|
|
166
|
+
return (
|
|
167
|
+
<Typography level="body-md">
|
|
168
|
+
For more information about our services, please visit our{' '}
|
|
169
|
+
<Link href="/services">services page</Link> or read our{' '}
|
|
170
|
+
<Link href="/faq">frequently asked questions</Link>.
|
|
171
|
+
</Typography>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### External Links with Icon
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
function ExternalResourceLink() {
|
|
180
|
+
return (
|
|
181
|
+
<Link
|
|
182
|
+
href="https://documentation.example.com"
|
|
183
|
+
target="_blank"
|
|
184
|
+
rel="noopener noreferrer"
|
|
185
|
+
endDecorator={<OpenInNewIcon sx={{ fontSize: 16 }} />}
|
|
186
|
+
>
|
|
187
|
+
View Documentation
|
|
188
|
+
</Link>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Footer Links
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
function FooterLinks() {
|
|
197
|
+
return (
|
|
198
|
+
<Stack direction="row" spacing={2} divider={<Divider orientation="vertical" />}>
|
|
199
|
+
<Link href="/privacy" level="body-sm" color="neutral">
|
|
200
|
+
Privacy Policy
|
|
201
|
+
</Link>
|
|
202
|
+
<Link href="/terms" level="body-sm" color="neutral">
|
|
203
|
+
Terms of Service
|
|
204
|
+
</Link>
|
|
205
|
+
<Link href="/cookies" level="body-sm" color="neutral">
|
|
206
|
+
Cookie Policy
|
|
207
|
+
</Link>
|
|
208
|
+
</Stack>
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Link with React Router
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
import { Link as RouterLink } from 'react-router-dom';
|
|
217
|
+
|
|
218
|
+
function RouterIntegration() {
|
|
219
|
+
return (
|
|
220
|
+
<Link component={RouterLink} to="/dashboard">
|
|
221
|
+
Go to Dashboard
|
|
222
|
+
</Link>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Skip to Content Link
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
function SkipLink() {
|
|
231
|
+
return (
|
|
232
|
+
<Link
|
|
233
|
+
href="#main-content"
|
|
234
|
+
sx={{
|
|
235
|
+
position: 'absolute',
|
|
236
|
+
left: '-9999px',
|
|
237
|
+
'&:focus': {
|
|
238
|
+
left: 0,
|
|
239
|
+
zIndex: 1000,
|
|
240
|
+
p: 2,
|
|
241
|
+
bgcolor: 'background.surface',
|
|
242
|
+
},
|
|
243
|
+
}}
|
|
244
|
+
>
|
|
245
|
+
Skip to main content
|
|
246
|
+
</Link>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
24
249
|
```
|
|
250
|
+
|
|
251
|
+
### Download Link
|
|
252
|
+
|
|
253
|
+
```tsx
|
|
254
|
+
function DownloadLink({ filename, url }) {
|
|
255
|
+
return (
|
|
256
|
+
<Link
|
|
257
|
+
href={url}
|
|
258
|
+
download={filename}
|
|
259
|
+
startDecorator={<DownloadIcon />}
|
|
260
|
+
>
|
|
261
|
+
Download {filename}
|
|
262
|
+
</Link>
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Props and Customization
|
|
268
|
+
|
|
269
|
+
### Key Props
|
|
270
|
+
|
|
271
|
+
| Prop | Type | Default | Description |
|
|
272
|
+
| ---------------- | -------------------------------------------------------------- | ----------- | ---------------------------------------- |
|
|
273
|
+
| `href` | `string` | - | The URL to navigate to |
|
|
274
|
+
| `variant` | `'plain' \| 'outlined' \| 'soft' \| 'solid'` | `'plain'` | Visual style variant |
|
|
275
|
+
| `color` | `'primary' \| 'neutral' \| 'danger' \| 'success' \| 'warning'` | `'primary'` | Color scheme |
|
|
276
|
+
| `level` | `string` | - | Typography level (e.g., 'body-md', 'h4') |
|
|
277
|
+
| `underline` | `'none' \| 'hover' \| 'always'` | `'hover'` | Underline behavior |
|
|
278
|
+
| `disabled` | `boolean` | `false` | Disable the link |
|
|
279
|
+
| `startDecorator` | `ReactNode` | - | Element before the link text |
|
|
280
|
+
| `endDecorator` | `ReactNode` | - | Element after the link text |
|
|
281
|
+
| `component` | `ElementType` | `'a'` | The root element type |
|
|
282
|
+
|
|
283
|
+
### Underline Behavior
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
<Stack spacing={2}>
|
|
287
|
+
{/* No underline */}
|
|
288
|
+
<Link underline="none" href="#">Never underlined</Link>
|
|
289
|
+
|
|
290
|
+
{/* Underline on hover (default) */}
|
|
291
|
+
<Link underline="hover" href="#">Underline on hover</Link>
|
|
292
|
+
|
|
293
|
+
{/* Always underlined */}
|
|
294
|
+
<Link underline="always" href="#">Always underlined</Link>
|
|
295
|
+
</Stack>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### With Decorators
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
<Stack spacing={2}>
|
|
302
|
+
<Link href="#" startDecorator={<HomeIcon />}>
|
|
303
|
+
Home
|
|
304
|
+
</Link>
|
|
305
|
+
|
|
306
|
+
<Link href="#" endDecorator={<ArrowForwardIcon />}>
|
|
307
|
+
Learn more
|
|
308
|
+
</Link>
|
|
309
|
+
|
|
310
|
+
<Link
|
|
311
|
+
href="https://external.com"
|
|
312
|
+
target="_blank"
|
|
313
|
+
endDecorator={<OpenInNewIcon sx={{ fontSize: '1rem' }} />}
|
|
314
|
+
>
|
|
315
|
+
External link
|
|
316
|
+
</Link>
|
|
317
|
+
</Stack>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Custom Styling
|
|
321
|
+
|
|
322
|
+
```tsx
|
|
323
|
+
<Link
|
|
324
|
+
href="#"
|
|
325
|
+
sx={{
|
|
326
|
+
fontWeight: 'bold',
|
|
327
|
+
transition: 'color 0.2s',
|
|
328
|
+
'&:hover': {
|
|
329
|
+
color: 'primary.600',
|
|
330
|
+
},
|
|
331
|
+
}}
|
|
332
|
+
>
|
|
333
|
+
Custom styled link
|
|
334
|
+
</Link>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Accessibility
|
|
338
|
+
|
|
339
|
+
Link components include comprehensive accessibility features:
|
|
340
|
+
|
|
341
|
+
### Semantic HTML
|
|
342
|
+
|
|
343
|
+
- Uses native `<a>` element by default for proper semantics
|
|
344
|
+
- Supports custom components for router integration
|
|
345
|
+
|
|
346
|
+
### Screen Reader Support
|
|
347
|
+
|
|
348
|
+
- Links announce their destination or purpose
|
|
349
|
+
- Use descriptive link text instead of "click here" or "read more"
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
// ✅ Good: Descriptive link text
|
|
353
|
+
<Link href="/pricing">View our pricing plans</Link>
|
|
354
|
+
|
|
355
|
+
// ❌ Bad: Non-descriptive link text
|
|
356
|
+
<Link href="/pricing">Click here</Link>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Keyboard Navigation
|
|
360
|
+
|
|
361
|
+
- **Tab**: Navigate to and from links
|
|
362
|
+
- **Enter**: Activate the link
|
|
363
|
+
- Links receive visible focus indicators
|
|
364
|
+
|
|
365
|
+
### External Links
|
|
366
|
+
|
|
367
|
+
Always include proper attributes for external links:
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
<Link
|
|
371
|
+
href="https://external-site.com"
|
|
372
|
+
target="_blank"
|
|
373
|
+
rel="noopener noreferrer"
|
|
374
|
+
aria-label="Visit external site (opens in new tab)"
|
|
375
|
+
>
|
|
376
|
+
External Site
|
|
377
|
+
</Link>
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Color Contrast
|
|
381
|
+
|
|
382
|
+
All link colors meet WCAG contrast requirements. Avoid relying solely on color to indicate links - use underlines or other visual indicators.
|
|
383
|
+
|
|
384
|
+
## Best Practices
|
|
385
|
+
|
|
386
|
+
### ✅ Do
|
|
387
|
+
|
|
388
|
+
1. **Use descriptive text**: Link text should describe the destination
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
// ✅ Good
|
|
392
|
+
<Link href="/documentation">Read the documentation</Link>
|
|
393
|
+
|
|
394
|
+
// ❌ Bad
|
|
395
|
+
<Link href="/documentation">Click here</Link>
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
2. **Indicate external links**: Show users when links open in new tabs
|
|
399
|
+
|
|
400
|
+
```tsx
|
|
401
|
+
<Link href="https://external.com" target="_blank" rel="noopener noreferrer">
|
|
402
|
+
External Resource <OpenInNewIcon sx={{ fontSize: 14 }} />
|
|
403
|
+
</Link>
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
3. **Use appropriate colors**: Match link colors to their context and importance
|
|
407
|
+
|
|
408
|
+
4. **Maintain consistency**: Use consistent link styles throughout your application
|
|
409
|
+
|
|
410
|
+
### ❌ Don't
|
|
411
|
+
|
|
412
|
+
1. **Don't use links for actions**: Use Button for non-navigation actions
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
// ❌ Bad: Using link for action
|
|
416
|
+
<Link onClick={handleSubmit}>Submit Form</Link>
|
|
417
|
+
|
|
418
|
+
// ✅ Good: Using button for action
|
|
419
|
+
<Button onClick={handleSubmit}>Submit Form</Button>
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
2. **Don't disable links without reason**: If content is unavailable, explain why
|
|
423
|
+
|
|
424
|
+
3. **Don't open all external links in new tabs**: Only do so when users might lose context
|
|
425
|
+
|
|
426
|
+
4. **Don't use link styling for non-interactive elements**
|
|
427
|
+
|
|
428
|
+
## Performance Considerations
|
|
429
|
+
|
|
430
|
+
### Prefetching
|
|
431
|
+
|
|
432
|
+
When using with routing libraries, consider implementing link prefetching for improved perceived performance:
|
|
433
|
+
|
|
434
|
+
```tsx
|
|
435
|
+
// With Next.js
|
|
436
|
+
import NextLink from 'next/link';
|
|
437
|
+
|
|
438
|
+
<Link component={NextLink} href="/page" prefetch>
|
|
439
|
+
Prefetched Page
|
|
440
|
+
</Link>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Avoid Unnecessary Re-renders
|
|
444
|
+
|
|
445
|
+
For links in lists or frequently updating components, ensure stable references:
|
|
446
|
+
|
|
447
|
+
```tsx
|
|
448
|
+
// Using useCallback for event handlers in links
|
|
449
|
+
const handleClick = useCallback((e) => {
|
|
450
|
+
trackLinkClick(e);
|
|
451
|
+
}, []);
|
|
452
|
+
|
|
453
|
+
<Link href="/page" onClick={handleClick}>
|
|
454
|
+
Tracked Link
|
|
455
|
+
</Link>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Link is a fundamental navigation component that ensures consistent, accessible navigation throughout your application. Use it thoughtfully to create clear pathways for users to explore your content.
|