@ticatec/uniface-element 0.2.4 → 0.3.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/accordion/README.md +169 -0
- package/dist/accordion/README_CN.md +176 -0
- package/dist/action-bar/README.md +275 -0
- package/dist/action-bar/README_CN.md +285 -0
- package/dist/app-layout/README.md +374 -0
- package/dist/app-layout/README_CN.md +381 -0
- package/dist/app-top-bar/README.md +357 -0
- package/dist/app-top-bar/README_CN.md +365 -0
- package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
- package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
- package/dist/base-calendar/CalendarBase.svelte +0 -3
- package/dist/box/README.md +385 -0
- package/dist/box/README_CN.md +393 -0
- package/dist/breadcrumbs/README.md +442 -0
- package/dist/breadcrumbs/README_CN.md +442 -0
- package/dist/button/Button.svelte +27 -7
- package/dist/button/Button.svelte.d.ts +3 -1
- package/dist/button/IconButton.svelte +26 -6
- package/dist/button/IconButton.svelte.d.ts +3 -1
- package/dist/button/IconButton_README.md +513 -0
- package/dist/button/IconButton_README_CN.md +513 -0
- package/dist/button/README.md +428 -0
- package/dist/button/README_CN.md +428 -0
- package/dist/button/TextButton.svelte +26 -6
- package/dist/button/TextButton.svelte.d.ts +3 -1
- package/dist/button/TextButton_README.md +571 -0
- package/dist/button/TextButton_README_CN.md +571 -0
- package/dist/card/README.md +666 -0
- package/dist/card/README_CN.md +666 -0
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
- package/dist/cascade-options-select/README.md +663 -2
- package/dist/cascade-options-select/README_CN.md +664 -0
- package/dist/checkbox/CheckBox.svelte +20 -6
- package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
- package/dist/checkbox/README.md +562 -0
- package/dist/checkbox/README_CN.md +727 -0
- package/dist/common-editor/NumberInput.svelte +39 -26
- package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
- package/dist/concise-data-table/ConciseListTable.svelte +133 -36
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
- package/dist/concise-data-table/DataCell.svelte +5 -6
- package/dist/concise-data-table/DataRow.svelte +22 -2
- package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
- package/dist/concise-data-table/README.md +606 -0
- package/dist/concise-data-table/README_CN.md +611 -0
- package/dist/context-menu/ContextMenu.svelte +138 -21
- package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
- package/dist/context-menu/ContextMenuItem.d.ts +20 -4
- package/dist/context-menu/README.md +551 -0
- package/dist/context-menu/README_CN.md +551 -0
- package/dist/criteria-field/CriteriaField.svelte +3 -5
- package/dist/criteria-field/README.md +532 -0
- package/dist/criteria-field/README_CN.md +532 -0
- package/dist/data-table/README.md +712 -0
- package/dist/data-table/README_CN.md +712 -0
- package/dist/date-picker/DatePicker.svelte +44 -7
- package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
- package/dist/date-picker/DateTimePicker.svelte +32 -8
- package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
- package/dist/date-picker/README.md +326 -0
- package/dist/date-picker/README_CN.md +316 -0
- package/dist/date-picker/ScrollBar.svelte +18 -8
- package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
- package/dist/date-picker/TimePanel.svelte +5 -5
- package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
- package/dist/date-range/README.md +374 -0
- package/dist/date-range/README_CN.md +374 -0
- package/dist/dialog/README.md +596 -0
- package/dist/dialog/README_CN.md +596 -0
- package/dist/drawer/README.md +679 -1
- package/dist/drawer/README_CN.md +679 -0
- package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
- package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
- package/dist/group-box/group-check-box/README.md +749 -0
- package/dist/group-box/group-check-box/README_CN.md +750 -0
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
- package/dist/group-box/group-radio-box/README.md +920 -0
- package/dist/group-box/group-radio-box/README_CN.md +920 -0
- package/dist/image-files/README.md +1346 -0
- package/dist/image-files/README_CN.md +1346 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
- package/dist/lib/forwardAllEvents.d.ts +3 -0
- package/dist/lib/forwardAllEvents.js +24 -0
- package/dist/list-box/README.md +579 -0
- package/dist/list-box/README_CN.md +682 -0
- package/dist/lookup-editor/LookupEditor.svelte +15 -3
- package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
- package/dist/lookup-editor/README.md +684 -0
- package/dist/lookup-editor/README_CN.md +684 -0
- package/dist/memo-editor/MemoEditor.svelte +77 -27
- package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
- package/dist/memo-editor/README.md +819 -0
- package/dist/memo-editor/README_CN.md +819 -0
- package/dist/message-box/README.md +398 -0
- package/dist/message-box/README_CN.md +398 -0
- package/dist/number-editor/NumberEditor.svelte +2 -2
- package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
- package/dist/number-editor/README.md +353 -22
- package/dist/number-editor/README_CN.md +357 -0
- package/dist/number-range/README.md +443 -0
- package/dist/number-range/README_CN.md +443 -0
- package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
- package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
- package/dist/options-multi-select/README.md +480 -0
- package/dist/options-multi-select/README_CN.md +480 -0
- package/dist/options-select/OptionsSelect.svelte +36 -5
- package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
- package/dist/options-select/README.md +632 -0
- package/dist/options-select/README_CN.md +632 -0
- package/dist/page/README.md +605 -0
- package/dist/page/README_CN.md +605 -0
- package/dist/pagination/README.md +946 -0
- package/dist/pagination/README_CN.md +946 -0
- package/dist/pagination-panel/README.md +1075 -0
- package/dist/pagination-panel/README_CN.md +1075 -0
- package/dist/popup-hint/README.md +841 -0
- package/dist/popup-hint/README_CN.md +840 -0
- package/dist/progress-bar/README.md +242 -0
- package/dist/progress-bar/README_CN.md +242 -0
- package/dist/progress-step-bar/README.md +316 -0
- package/dist/progress-step-bar/README_CN.md +316 -0
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
- package/dist/prompts-text-editor/README.md +329 -0
- package/dist/prompts-text-editor/README_CN.md +329 -0
- package/dist/property-editor/README.md +969 -0
- package/dist/property-editor/README_CN.md +969 -0
- package/dist/radio-button/README.md +372 -0
- package/dist/radio-button/README_CN.md +372 -0
- package/dist/radio-button/RadioButton.svelte +32 -3
- package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
- package/dist/search-box/README.md +425 -0
- package/dist/search-box/README_CN.md +424 -0
- package/dist/search-box/SearchBox.svelte +22 -6
- package/dist/search-box/SearchBox.svelte.d.ts +4 -1
- package/dist/tabs/README.md +919 -0
- package/dist/tabs/README_CN.md +920 -0
- package/dist/tag/README.md +922 -0
- package/dist/tag/README_CN.md +922 -0
- package/dist/text-editor/PasswordEditor.svelte +17 -2
- package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
- package/dist/text-editor/PasswordEditor_README.md +551 -0
- package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
- package/dist/text-editor/README.md +466 -0
- package/dist/text-editor/README_CN.md +466 -0
- package/dist/text-editor/TextEditor.svelte +51 -19
- package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
- package/dist/ticatec-uniface-web.css +2 -0
- package/dist/time-editor/README.md +498 -24
- package/dist/time-editor/README_CN.md +498 -0
- package/dist/time-editor/TimeEditor.svelte +7 -3
- package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
- package/dist/toast/README.md +667 -0
- package/dist/toast/README_CN.md +667 -0
- package/dist/transfer/README.md +795 -0
- package/dist/transfer/Transfer.svelte +6 -4
- package/dist/transfer/Transfer.svelte.d.ts +3 -1
- package/dist/tree-view/README.md +761 -0
- package/dist/tree-view/README_CN.md +761 -0
- package/dist/tree-view/TreeView.svelte +5 -3
- package/dist/tree-view/TreeView.svelte.d.ts +3 -1
- package/dist/unit-number-editor/README.md +546 -20
- package/dist/unit-number-editor/README_CN.md +525 -0
- package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
- package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
- package/docs/form-field/cn/README_CN.md +364 -0
- package/docs/form-field/en/README.md +364 -0
- package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
- package/docs/form-panel/flex-form/en/README.md +586 -0
- package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
- package/docs/form-panel/flex-row-form/en/README.md +787 -0
- package/docs/form-panel/grid-form/en/README.md +744 -0
- package/package.json +1 -1
- package/dist/drawer/README-CN.md +0 -1
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# Breadcrumbs Component
|
|
2
|
+
|
|
3
|
+
A navigation component that shows the user's current location in a hierarchical structure, helping users understand where they are and navigate back to previous levels.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Hierarchical Navigation**: Display path from root to current location
|
|
8
|
+
- **Clickable Items**: Navigate to any previous level (except current)
|
|
9
|
+
- **Custom Separators**: Configurable separator between breadcrumb items
|
|
10
|
+
- **Custom Data**: Associate any data with breadcrumb items
|
|
11
|
+
- **Click Handlers**: Custom logic for navigation actions
|
|
12
|
+
- **Responsive**: Adapts to container width
|
|
13
|
+
|
|
14
|
+
## Basic Usage
|
|
15
|
+
|
|
16
|
+
```svelte
|
|
17
|
+
<script>
|
|
18
|
+
import Breadcrumbs, { type Breadcrumb } from '@ticatec/uniface-element/Breadcrumbs';
|
|
19
|
+
|
|
20
|
+
const breadcrumbItems: Breadcrumb[] = [
|
|
21
|
+
{ label: 'Home', data: { path: '/' } },
|
|
22
|
+
{ label: 'Products', data: { path: '/products' } },
|
|
23
|
+
{ label: 'Electronics', data: { path: '/products/electronics' } },
|
|
24
|
+
{ label: 'Smartphones', data: { path: '/products/electronics/smartphones' } }
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const handleItemClick = (data: any) => (event: MouseEvent) => {
|
|
28
|
+
console.log('Navigate to:', data.path);
|
|
29
|
+
// Handle navigation logic
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<Breadcrumbs
|
|
34
|
+
items={breadcrumbItems}
|
|
35
|
+
onItemClick={handleItemClick}
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Props
|
|
40
|
+
|
|
41
|
+
| Prop | Type | Default | Description |
|
|
42
|
+
|------|------|---------|-------------|
|
|
43
|
+
| `items` | `Breadcrumb[]` | `[]` | Array of breadcrumb items |
|
|
44
|
+
| `separator` | `string` | `"/"` | Separator character between items |
|
|
45
|
+
| `onItemClick` | `(item: any) => (event: MouseEvent) => void` | - | Click handler for breadcrumb items |
|
|
46
|
+
| `style` | `string` | `''` | Custom CSS styles |
|
|
47
|
+
|
|
48
|
+
## Breadcrumb Interface
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
interface Breadcrumb {
|
|
52
|
+
label: string; // Display text for the breadcrumb
|
|
53
|
+
data: any; // Associated data (e.g., route, ID, etc.)
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Examples
|
|
58
|
+
|
|
59
|
+
### Basic File System Navigation
|
|
60
|
+
|
|
61
|
+
```svelte
|
|
62
|
+
<script>
|
|
63
|
+
const fileSystemPath = [
|
|
64
|
+
{ label: 'Documents', data: { path: '/documents' } },
|
|
65
|
+
{ label: 'Projects', data: { path: '/documents/projects' } },
|
|
66
|
+
{ label: 'MyApp', data: { path: '/documents/projects/myapp' } },
|
|
67
|
+
{ label: 'src', data: { path: '/documents/projects/myapp/src' } }
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
const navigateToFolder = (data: any) => (event: MouseEvent) => {
|
|
71
|
+
window.location.href = data.path;
|
|
72
|
+
};
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<Breadcrumbs
|
|
76
|
+
items={fileSystemPath}
|
|
77
|
+
onItemClick={navigateToFolder}
|
|
78
|
+
separator=" > "
|
|
79
|
+
/>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### E-commerce Category Navigation
|
|
83
|
+
|
|
84
|
+
```svelte
|
|
85
|
+
<script>
|
|
86
|
+
const categoryPath = [
|
|
87
|
+
{ label: 'All Categories', data: { categoryId: null } },
|
|
88
|
+
{ label: 'Electronics', data: { categoryId: 'electronics' } },
|
|
89
|
+
{ label: 'Computers', data: { categoryId: 'computers' } },
|
|
90
|
+
{ label: 'Laptops', data: { categoryId: 'laptops' } }
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const goToCategory = (data: any) => (event: MouseEvent) => {
|
|
94
|
+
if (data.categoryId) {
|
|
95
|
+
router.push(`/category/${data.categoryId}`);
|
|
96
|
+
} else {
|
|
97
|
+
router.push('/categories');
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
</script>
|
|
101
|
+
|
|
102
|
+
<Breadcrumbs
|
|
103
|
+
items={categoryPath}
|
|
104
|
+
onItemClick={goToCategory}
|
|
105
|
+
separator=" › "
|
|
106
|
+
/>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Admin Panel Navigation
|
|
110
|
+
|
|
111
|
+
```svelte
|
|
112
|
+
<script>
|
|
113
|
+
const adminPath = [
|
|
114
|
+
{ label: 'Dashboard', data: { route: '/admin' } },
|
|
115
|
+
{ label: 'User Management', data: { route: '/admin/users' } },
|
|
116
|
+
{ label: 'Edit User', data: { route: '/admin/users/edit', userId: 123 } }
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const navigateToAdminPage = (data: any) => (event: MouseEvent) => {
|
|
120
|
+
// Custom navigation logic
|
|
121
|
+
adminRouter.navigate(data.route);
|
|
122
|
+
};
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<Breadcrumbs
|
|
126
|
+
items={adminPath}
|
|
127
|
+
onItemClick={navigateToAdminPage}
|
|
128
|
+
/>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Documentation Site
|
|
132
|
+
|
|
133
|
+
```svelte
|
|
134
|
+
<script>
|
|
135
|
+
const docsPath = [
|
|
136
|
+
{ label: 'Documentation', data: { section: 'home' } },
|
|
137
|
+
{ label: 'Components', data: { section: 'components' } },
|
|
138
|
+
{ label: 'Form Controls', data: { section: 'forms' } },
|
|
139
|
+
{ label: 'TextEditor', data: { section: 'texteditor' } }
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
const goToDocsSection = (data: any) => (event: MouseEvent) => {
|
|
143
|
+
scrollToSection(data.section);
|
|
144
|
+
};
|
|
145
|
+
</script>
|
|
146
|
+
|
|
147
|
+
<Breadcrumbs
|
|
148
|
+
items={docsPath}
|
|
149
|
+
onItemClick={goToDocsSection}
|
|
150
|
+
separator=" • "
|
|
151
|
+
/>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Custom Separator with Icons
|
|
155
|
+
|
|
156
|
+
```svelte
|
|
157
|
+
<script>
|
|
158
|
+
const projectPath = [
|
|
159
|
+
{ label: 'Workspace', data: { id: 'workspace' } },
|
|
160
|
+
{ label: 'Project Alpha', data: { id: 'project-alpha' } },
|
|
161
|
+
{ label: 'Settings', data: { id: 'settings' } }
|
|
162
|
+
];
|
|
163
|
+
</script>
|
|
164
|
+
|
|
165
|
+
<Breadcrumbs
|
|
166
|
+
items={projectPath}
|
|
167
|
+
onItemClick={handleNavigation}
|
|
168
|
+
separator=" 🔹 "
|
|
169
|
+
style="font-size: 14px; color: #666;"
|
|
170
|
+
/>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### With Custom Styling
|
|
174
|
+
|
|
175
|
+
```svelte
|
|
176
|
+
<Breadcrumbs
|
|
177
|
+
items={breadcrumbs}
|
|
178
|
+
onItemClick={navigate}
|
|
179
|
+
separator=" / "
|
|
180
|
+
style="
|
|
181
|
+
background: #f8f9fa;
|
|
182
|
+
padding: 8px 16px;
|
|
183
|
+
border-radius: 4px;
|
|
184
|
+
font-size: 13px;
|
|
185
|
+
"
|
|
186
|
+
/>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Dynamic Breadcrumbs
|
|
190
|
+
|
|
191
|
+
```svelte
|
|
192
|
+
<script>
|
|
193
|
+
let currentPath = [];
|
|
194
|
+
|
|
195
|
+
// Build breadcrumbs based on current route
|
|
196
|
+
$: breadcrumbs = buildBreadcrumbs($page.url.pathname);
|
|
197
|
+
|
|
198
|
+
function buildBreadcrumbs(pathname) {
|
|
199
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
200
|
+
const items = [{ label: 'Home', data: { path: '/' } }];
|
|
201
|
+
|
|
202
|
+
let currentPath = '';
|
|
203
|
+
segments.forEach(segment => {
|
|
204
|
+
currentPath += `/${segment}`;
|
|
205
|
+
items.push({
|
|
206
|
+
label: formatSegment(segment),
|
|
207
|
+
data: { path: currentPath }
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return items;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function formatSegment(segment) {
|
|
215
|
+
return segment.charAt(0).toUpperCase() + segment.slice(1);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const navigateTo = (data) => (event) => {
|
|
219
|
+
goto(data.path);
|
|
220
|
+
};
|
|
221
|
+
</script>
|
|
222
|
+
|
|
223
|
+
<Breadcrumbs
|
|
224
|
+
items={breadcrumbs}
|
|
225
|
+
onItemClick={navigateTo}
|
|
226
|
+
/>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Behavior
|
|
230
|
+
|
|
231
|
+
### Click Interaction
|
|
232
|
+
- All breadcrumb items except the last one are clickable
|
|
233
|
+
- The last item (current location) is not clickable and appears as plain text
|
|
234
|
+
- Click handlers receive the associated data object from the breadcrumb item
|
|
235
|
+
|
|
236
|
+
### Navigation Pattern
|
|
237
|
+
- Typically used for hierarchical navigation
|
|
238
|
+
- Helps users understand their current location
|
|
239
|
+
- Provides quick access to parent levels
|
|
240
|
+
|
|
241
|
+
## Styling
|
|
242
|
+
|
|
243
|
+
The component uses the following CSS classes:
|
|
244
|
+
|
|
245
|
+
- `.uniface-breadcrumbs` - Main container
|
|
246
|
+
- `.breadcrumb` - Individual breadcrumb item
|
|
247
|
+
|
|
248
|
+
### Example CSS
|
|
249
|
+
|
|
250
|
+
```css
|
|
251
|
+
.uniface-breadcrumbs {
|
|
252
|
+
display: flex;
|
|
253
|
+
align-items: center;
|
|
254
|
+
flex-wrap: wrap;
|
|
255
|
+
gap: 4px;
|
|
256
|
+
font-size: 14px;
|
|
257
|
+
color: #666;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.breadcrumb {
|
|
261
|
+
cursor: pointer;
|
|
262
|
+
color: #007acc;
|
|
263
|
+
text-decoration: none;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.breadcrumb:hover {
|
|
267
|
+
text-decoration: underline;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.breadcrumb:last-child {
|
|
271
|
+
cursor: default;
|
|
272
|
+
color: #333;
|
|
273
|
+
font-weight: 500;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* Responsive design */
|
|
277
|
+
@media (max-width: 768px) {
|
|
278
|
+
.uniface-breadcrumbs {
|
|
279
|
+
font-size: 12px;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Common Patterns
|
|
285
|
+
|
|
286
|
+
### Page Title Integration
|
|
287
|
+
|
|
288
|
+
```svelte
|
|
289
|
+
<div class="page-header">
|
|
290
|
+
<Breadcrumbs items={breadcrumbs} onItemClick={navigate} />
|
|
291
|
+
<h1>{currentPageTitle}</h1>
|
|
292
|
+
</div>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### With Loading State
|
|
296
|
+
|
|
297
|
+
```svelte
|
|
298
|
+
<script>
|
|
299
|
+
let loading = false;
|
|
300
|
+
let breadcrumbs = [];
|
|
301
|
+
|
|
302
|
+
const loadBreadcrumbs = async (pageId) => {
|
|
303
|
+
loading = true;
|
|
304
|
+
try {
|
|
305
|
+
breadcrumbs = await fetchBreadcrumbs(pageId);
|
|
306
|
+
} finally {
|
|
307
|
+
loading = false;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
</script>
|
|
311
|
+
|
|
312
|
+
{#if loading}
|
|
313
|
+
<div class="breadcrumb-skeleton">Loading...</div>
|
|
314
|
+
{:else}
|
|
315
|
+
<Breadcrumbs items={breadcrumbs} onItemClick={navigate} />
|
|
316
|
+
{/if}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Truncated Long Paths
|
|
320
|
+
|
|
321
|
+
```svelte
|
|
322
|
+
<script>
|
|
323
|
+
const MAX_ITEMS = 4;
|
|
324
|
+
|
|
325
|
+
$: displayItems = breadcrumbs.length > MAX_ITEMS
|
|
326
|
+
? [
|
|
327
|
+
breadcrumbs[0],
|
|
328
|
+
{ label: '...', data: { truncated: true } },
|
|
329
|
+
...breadcrumbs.slice(-2)
|
|
330
|
+
]
|
|
331
|
+
: breadcrumbs;
|
|
332
|
+
|
|
333
|
+
const handleClick = (data) => (event) => {
|
|
334
|
+
if (data.truncated) {
|
|
335
|
+
// Show dropdown with hidden items
|
|
336
|
+
showFullPath = true;
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
navigate(data);
|
|
340
|
+
};
|
|
341
|
+
</script>
|
|
342
|
+
|
|
343
|
+
<Breadcrumbs
|
|
344
|
+
items={displayItems}
|
|
345
|
+
onItemClick={handleClick}
|
|
346
|
+
/>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Accessibility
|
|
350
|
+
|
|
351
|
+
- Use semantic navigation structure
|
|
352
|
+
- Provide clear visual distinction between clickable and non-clickable items
|
|
353
|
+
- Ensure adequate color contrast
|
|
354
|
+
- Consider ARIA labels for screen readers
|
|
355
|
+
|
|
356
|
+
```svelte
|
|
357
|
+
<nav aria-label="Breadcrumb navigation">
|
|
358
|
+
<Breadcrumbs items={breadcrumbs} onItemClick={navigate} />
|
|
359
|
+
</nav>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Integration with Routing
|
|
363
|
+
|
|
364
|
+
### SvelteKit Integration
|
|
365
|
+
|
|
366
|
+
```svelte
|
|
367
|
+
<script>
|
|
368
|
+
import { page } from '$app/stores';
|
|
369
|
+
import { goto } from '$app/navigation';
|
|
370
|
+
|
|
371
|
+
$: breadcrumbs = generateBreadcrumbs($page.route.id);
|
|
372
|
+
|
|
373
|
+
function generateBreadcrumbs(routeId) {
|
|
374
|
+
// Generate breadcrumbs based on route structure
|
|
375
|
+
return routeSegments.map(segment => ({
|
|
376
|
+
label: segment.title,
|
|
377
|
+
data: { path: segment.path }
|
|
378
|
+
}));
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const navigate = (data) => (event) => {
|
|
382
|
+
goto(data.path);
|
|
383
|
+
};
|
|
384
|
+
</script>
|
|
385
|
+
|
|
386
|
+
<Breadcrumbs items={breadcrumbs} onItemClick={navigate} />
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### React Router Integration
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
// For reference - similar pattern can be adapted
|
|
393
|
+
const breadcrumbs = useBreadcrumbs(routes);
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Best Practices
|
|
397
|
+
|
|
398
|
+
1. **Clear Hierarchy**: Ensure breadcrumbs reflect a logical hierarchy
|
|
399
|
+
2. **Consistent Naming**: Use consistent labeling across similar pages
|
|
400
|
+
3. **Responsive Design**: Consider how breadcrumbs appear on mobile devices
|
|
401
|
+
4. **Performance**: Don't over-nest breadcrumb levels
|
|
402
|
+
5. **User Context**: Show relevant path based on user's entry point
|
|
403
|
+
6. **Skip Navigation**: Provide skip links for accessibility
|
|
404
|
+
|
|
405
|
+
## Mobile Considerations
|
|
406
|
+
|
|
407
|
+
For mobile devices, consider:
|
|
408
|
+
|
|
409
|
+
```css
|
|
410
|
+
@media (max-width: 480px) {
|
|
411
|
+
.uniface-breadcrumbs {
|
|
412
|
+
overflow-x: auto;
|
|
413
|
+
white-space: nowrap;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* Or show only parent and current */
|
|
417
|
+
.breadcrumb:not(:nth-last-child(2)):not(:last-child) {
|
|
418
|
+
display: none;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Testing
|
|
424
|
+
|
|
425
|
+
When testing breadcrumbs:
|
|
426
|
+
|
|
427
|
+
```javascript
|
|
428
|
+
// Test navigation
|
|
429
|
+
const breadcrumbs = [
|
|
430
|
+
{ label: 'Home', data: { path: '/' } },
|
|
431
|
+
{ label: 'Products', data: { path: '/products' } }
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
const mockNavigate = vi.fn();
|
|
435
|
+
render(Breadcrumbs, {
|
|
436
|
+
props: { items: breadcrumbs, onItemClick: mockNavigate }
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// Click first breadcrumb
|
|
440
|
+
fireEvent.click(screen.getByText('Home'));
|
|
441
|
+
expect(mockNavigate).toHaveBeenCalledWith({ path: '/' });
|
|
442
|
+
```
|