@ticatec/uniface-element 0.2.3 → 0.3.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 (178) hide show
  1. package/dist/accordion/README.md +169 -0
  2. package/dist/accordion/README_CN.md +176 -0
  3. package/dist/action-bar/README.md +275 -0
  4. package/dist/action-bar/README_CN.md +285 -0
  5. package/dist/app-layout/README.md +374 -0
  6. package/dist/app-layout/README_CN.md +381 -0
  7. package/dist/app-top-bar/README.md +357 -0
  8. package/dist/app-top-bar/README_CN.md +365 -0
  9. package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
  10. package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
  11. package/dist/base-calendar/CalendarBase.svelte +0 -3
  12. package/dist/box/README.md +385 -0
  13. package/dist/box/README_CN.md +393 -0
  14. package/dist/breadcrumbs/README.md +442 -0
  15. package/dist/breadcrumbs/README_CN.md +442 -0
  16. package/dist/button/Button.svelte +27 -7
  17. package/dist/button/Button.svelte.d.ts +3 -1
  18. package/dist/button/IconButton.svelte +26 -6
  19. package/dist/button/IconButton.svelte.d.ts +3 -1
  20. package/dist/button/IconButton_README.md +513 -0
  21. package/dist/button/IconButton_README_CN.md +513 -0
  22. package/dist/button/README.md +428 -0
  23. package/dist/button/README_CN.md +428 -0
  24. package/dist/button/TextButton.svelte +26 -6
  25. package/dist/button/TextButton.svelte.d.ts +3 -1
  26. package/dist/button/TextButton_README.md +571 -0
  27. package/dist/button/TextButton_README_CN.md +571 -0
  28. package/dist/card/README.md +666 -0
  29. package/dist/card/README_CN.md +666 -0
  30. package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
  31. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
  32. package/dist/cascade-options-select/README.md +663 -2
  33. package/dist/cascade-options-select/README_CN.md +664 -0
  34. package/dist/checkbox/CheckBox.svelte +20 -6
  35. package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
  36. package/dist/checkbox/README.md +562 -0
  37. package/dist/checkbox/README_CN.md +727 -0
  38. package/dist/common-editor/NumberInput.svelte +39 -26
  39. package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
  40. package/dist/concise-data-table/ConciseListTable.svelte +133 -36
  41. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
  42. package/dist/concise-data-table/DataCell.svelte +5 -6
  43. package/dist/concise-data-table/DataRow.svelte +22 -2
  44. package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
  45. package/dist/concise-data-table/README.md +606 -0
  46. package/dist/concise-data-table/README_CN.md +611 -0
  47. package/dist/context-menu/ContextMenu.svelte +138 -21
  48. package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
  49. package/dist/context-menu/ContextMenuItem.d.ts +20 -4
  50. package/dist/context-menu/README.md +551 -0
  51. package/dist/context-menu/README_CN.md +551 -0
  52. package/dist/criteria-field/CriteriaField.svelte +3 -5
  53. package/dist/criteria-field/README.md +532 -0
  54. package/dist/criteria-field/README_CN.md +532 -0
  55. package/dist/data-table/README.md +712 -0
  56. package/dist/data-table/README_CN.md +712 -0
  57. package/dist/date-picker/DatePicker.svelte +44 -7
  58. package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
  59. package/dist/date-picker/DateTimePicker.svelte +32 -8
  60. package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
  61. package/dist/date-picker/README.md +326 -0
  62. package/dist/date-picker/README_CN.md +316 -0
  63. package/dist/date-picker/ScrollBar.svelte +18 -8
  64. package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
  65. package/dist/date-picker/TimePanel.svelte +5 -5
  66. package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
  67. package/dist/date-range/README.md +374 -0
  68. package/dist/date-range/README_CN.md +374 -0
  69. package/dist/dialog/DialogBoard.svelte +1 -1
  70. package/dist/dialog/README.md +596 -0
  71. package/dist/dialog/README_CN.md +596 -0
  72. package/dist/drawer/README.md +679 -1
  73. package/dist/drawer/README_CN.md +679 -0
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  75. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  76. package/dist/group-box/group-check-box/README.md +749 -0
  77. package/dist/group-box/group-check-box/README_CN.md +750 -0
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  79. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  80. package/dist/group-box/group-radio-box/README.md +920 -0
  81. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  82. package/dist/image-files/README.md +1346 -0
  83. package/dist/image-files/README_CN.md +1346 -0
  84. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  85. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  86. package/dist/lib/forwardAllEvents.d.ts +3 -0
  87. package/dist/lib/forwardAllEvents.js +24 -0
  88. package/dist/list-box/README.md +579 -0
  89. package/dist/list-box/README_CN.md +682 -0
  90. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  91. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  92. package/dist/lookup-editor/README.md +684 -0
  93. package/dist/lookup-editor/README_CN.md +684 -0
  94. package/dist/memo-editor/MemoEditor.svelte +77 -27
  95. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  96. package/dist/memo-editor/README.md +819 -0
  97. package/dist/memo-editor/README_CN.md +819 -0
  98. package/dist/message-box/README.md +398 -0
  99. package/dist/message-box/README_CN.md +398 -0
  100. package/dist/number-editor/NumberEditor.svelte +2 -2
  101. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  102. package/dist/number-editor/README.md +353 -22
  103. package/dist/number-editor/README_CN.md +357 -0
  104. package/dist/number-range/README.md +443 -0
  105. package/dist/number-range/README_CN.md +443 -0
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  107. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  108. package/dist/options-multi-select/README.md +480 -0
  109. package/dist/options-multi-select/README_CN.md +480 -0
  110. package/dist/options-select/OptionsSelect.svelte +36 -5
  111. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  112. package/dist/options-select/README.md +632 -0
  113. package/dist/options-select/README_CN.md +632 -0
  114. package/dist/page/README.md +605 -0
  115. package/dist/page/README_CN.md +605 -0
  116. package/dist/pagination/README.md +946 -0
  117. package/dist/pagination/README_CN.md +946 -0
  118. package/dist/pagination-panel/README.md +1075 -0
  119. package/dist/pagination-panel/README_CN.md +1075 -0
  120. package/dist/popup-hint/README.md +841 -0
  121. package/dist/popup-hint/README_CN.md +840 -0
  122. package/dist/progress-bar/README.md +242 -0
  123. package/dist/progress-bar/README_CN.md +242 -0
  124. package/dist/progress-step-bar/README.md +316 -0
  125. package/dist/progress-step-bar/README_CN.md +316 -0
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  127. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  128. package/dist/prompts-text-editor/README.md +329 -0
  129. package/dist/prompts-text-editor/README_CN.md +329 -0
  130. package/dist/property-editor/README.md +969 -0
  131. package/dist/property-editor/README_CN.md +969 -0
  132. package/dist/radio-button/README.md +372 -0
  133. package/dist/radio-button/README_CN.md +372 -0
  134. package/dist/radio-button/RadioButton.svelte +32 -3
  135. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  136. package/dist/search-box/README.md +425 -0
  137. package/dist/search-box/README_CN.md +424 -0
  138. package/dist/search-box/SearchBox.svelte +22 -6
  139. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  140. package/dist/tabs/README.md +919 -0
  141. package/dist/tabs/README_CN.md +920 -0
  142. package/dist/tag/README.md +922 -0
  143. package/dist/tag/README_CN.md +922 -0
  144. package/dist/text-editor/PasswordEditor.svelte +17 -2
  145. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  146. package/dist/text-editor/PasswordEditor_README.md +551 -0
  147. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  148. package/dist/text-editor/README.md +466 -0
  149. package/dist/text-editor/README_CN.md +466 -0
  150. package/dist/text-editor/TextEditor.svelte +51 -19
  151. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  152. package/dist/ticatec-uniface-web.css +1 -0
  153. package/dist/time-editor/README.md +498 -24
  154. package/dist/time-editor/README_CN.md +498 -0
  155. package/dist/time-editor/TimeEditor.svelte +7 -3
  156. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  157. package/dist/toast/README.md +667 -0
  158. package/dist/toast/README_CN.md +667 -0
  159. package/dist/transfer/README.md +795 -0
  160. package/dist/transfer/Transfer.svelte +6 -4
  161. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  162. package/dist/tree-view/README.md +761 -0
  163. package/dist/tree-view/README_CN.md +761 -0
  164. package/dist/tree-view/TreeView.svelte +5 -3
  165. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  166. package/dist/unit-number-editor/README.md +546 -20
  167. package/dist/unit-number-editor/README_CN.md +525 -0
  168. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  169. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  170. package/docs/form-field/cn/README_CN.md +364 -0
  171. package/docs/form-field/en/README.md +364 -0
  172. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  173. package/docs/form-panel/flex-form/en/README.md +586 -0
  174. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  175. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  176. package/docs/form-panel/grid-form/en/README.md +744 -0
  177. package/package.json +1 -1
  178. package/dist/drawer/README-CN.md +0 -1
@@ -0,0 +1,919 @@
1
+ # Tabs
2
+
3
+ A flexible tab navigation component with horizontal scrolling, closable tabs, and custom rendering support. Features include automatic overflow handling, smooth scrolling animations, and tab reload functionality. Perfect for document interfaces, dashboards, and multi-panel applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ticatec/uniface-element
9
+ ```
10
+
11
+ ## Import
12
+
13
+ ```typescript
14
+ import Tabs, { type TabActionHandler, type TabCloseHandler, type TabRender } from "@ticatec/uniface-element/Tabs";
15
+ ```
16
+
17
+ ## Basic Usage
18
+
19
+ ```svelte
20
+ <script>
21
+ import Tabs from "@ticatec/uniface-element/Tabs";
22
+
23
+ let tabs = [
24
+ { text: "Home" },
25
+ { text: "Products" },
26
+ { text: "Services" },
27
+ { text: "About" },
28
+ { text: "Contact" }
29
+ ];
30
+
31
+ let activeTab = tabs[0];
32
+ </script>
33
+
34
+ <Tabs {tabs} bind:activeTab>
35
+ <div class="tab-content">
36
+ <h2>{activeTab.text}</h2>
37
+ <p>Content for {activeTab.text} tab</p>
38
+ </div>
39
+ </Tabs>
40
+ ```
41
+
42
+ ## Props
43
+
44
+ | Prop | Type | Default | Description |
45
+ |------|------|---------|-------------|
46
+ | `tabs` | `Array<any>` | `[]` | Array of tab objects |
47
+ | `activeTab` | `any` | `null` | Currently active tab object |
48
+ | `textField` | `string` | `"text"` | Field name for tab display text |
49
+ | `simple` | `boolean` | `false` | Whether to use simple styling |
50
+ | `closable` | `boolean \| TabActionHandler` | `false` | Whether tabs can be closed |
51
+ | `scrollStep` | `number` | `100` | Scroll step size in pixels |
52
+ | `tabRender` | `TabRender` | `null` | Custom tab rendering component |
53
+ | `reloadHandler` | `TabActionHandler` | `null` | Handler for tab reload action |
54
+ | `closeHandler` | `TabCloseHandler` | `null` | Handler for tab close action |
55
+ | `style` | `string` | `""` | Additional CSS styles |
56
+ | `class` | `string` | `""` | CSS class name |
57
+
58
+ ## Type Definitions
59
+
60
+ ### TabActionHandler
61
+ ```typescript
62
+ type TabActionHandler = (tab: any) => void;
63
+ ```
64
+
65
+ ### TabCloseHandler
66
+ ```typescript
67
+ type TabCloseHandler = (tab: any) => Promise<boolean>;
68
+ ```
69
+
70
+ ### TabRender
71
+ ```typescript
72
+ type TabRender = (tab: any) => any;
73
+ ```
74
+
75
+ ## Examples
76
+
77
+ ### Basic Tab Navigation
78
+
79
+ ```svelte
80
+ <script>
81
+ import Tabs from "@ticatec/uniface-element/Tabs";
82
+
83
+ let navigationTabs = [
84
+ { id: 1, text: "Dashboard", icon: "dashboard" },
85
+ { id: 2, text: "Analytics", icon: "analytics" },
86
+ { id: 3, text: "Reports", icon: "reports" },
87
+ { id: 4, text: "Settings", icon: "settings" }
88
+ ];
89
+
90
+ let currentTab = navigationTabs[0];
91
+ </script>
92
+
93
+ <div class="app-container">
94
+ <Tabs tabs={navigationTabs} bind:activeTab={currentTab} style="height: 400px;">
95
+ {#if currentTab.id === 1}
96
+ <div class="dashboard">
97
+ <h2>📊 Dashboard</h2>
98
+ <p>Welcome to your dashboard overview</p>
99
+ <div class="stats">
100
+ <div class="stat">Users: 1,234</div>
101
+ <div class="stat">Revenue: $12,345</div>
102
+ <div class="stat">Orders: 567</div>
103
+ </div>
104
+ </div>
105
+ {:else if currentTab.id === 2}
106
+ <div class="analytics">
107
+ <h2>📈 Analytics</h2>
108
+ <p>View your performance metrics</p>
109
+ <div class="charts">
110
+ <div class="chart">Monthly Growth: +15%</div>
111
+ <div class="chart">Conversion Rate: 3.2%</div>
112
+ </div>
113
+ </div>
114
+ {:else if currentTab.id === 3}
115
+ <div class="reports">
116
+ <h2>📋 Reports</h2>
117
+ <p>Generate and view reports</p>
118
+ <button>Generate Monthly Report</button>
119
+ <button>Export Data</button>
120
+ </div>
121
+ {:else if currentTab.id === 4}
122
+ <div class="settings">
123
+ <h2>⚙️ Settings</h2>
124
+ <p>Configure your preferences</p>
125
+ <label><input type="checkbox"> Email notifications</label>
126
+ <label><input type="checkbox"> Dark mode</label>
127
+ </div>
128
+ {/if}
129
+ </Tabs>
130
+ </div>
131
+
132
+ <style>
133
+ .app-container {
134
+ max-width: 800px;
135
+ margin: 20px auto;
136
+ border: 1px solid #ddd;
137
+ border-radius: 8px;
138
+ }
139
+
140
+ .dashboard, .analytics, .reports, .settings {
141
+ padding: 20px;
142
+ }
143
+
144
+ .stats, .charts {
145
+ display: grid;
146
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
147
+ gap: 16px;
148
+ margin-top: 16px;
149
+ }
150
+
151
+ .stat, .chart {
152
+ padding: 12px;
153
+ background: #f8f9fa;
154
+ border-radius: 4px;
155
+ text-align: center;
156
+ }
157
+
158
+ .reports button {
159
+ margin: 8px 8px 8px 0;
160
+ padding: 8px 16px;
161
+ border: none;
162
+ background: #007bff;
163
+ color: white;
164
+ border-radius: 4px;
165
+ cursor: pointer;
166
+ }
167
+
168
+ .settings label {
169
+ display: block;
170
+ margin: 8px 0;
171
+ }
172
+ </style>
173
+ ```
174
+
175
+ ### Simple Tabs
176
+
177
+ ```svelte
178
+ <script>
179
+ import Tabs from "@ticatec/uniface-element/Tabs";
180
+
181
+ let documentTabs = [
182
+ { text: "Introduction" },
183
+ { text: "Getting Started" },
184
+ { text: "API Reference" },
185
+ { text: "Examples" }
186
+ ];
187
+
188
+ let currentDoc = documentTabs[0];
189
+ </script>
190
+
191
+ <div class="docs-container">
192
+ <Tabs tabs={documentTabs} bind:activeTab={currentDoc} simple style="height: 300px;">
193
+ <div class="doc-content">
194
+ {#if currentDoc.text === "Introduction"}
195
+ <h3>Introduction</h3>
196
+ <p>Welcome to our comprehensive documentation. This guide will help you get started with our platform and make the most of its features.</p>
197
+ {:else if currentDoc.text === "Getting Started"}
198
+ <h3>Getting Started</h3>
199
+ <ol>
200
+ <li>Create an account</li>
201
+ <li>Verify your email</li>
202
+ <li>Complete your profile</li>
203
+ <li>Start using the platform</li>
204
+ </ol>
205
+ {:else if currentDoc.text === "API Reference"}
206
+ <h3>API Reference</h3>
207
+ <p>Complete API documentation with endpoints, parameters, and examples.</p>
208
+ <code>GET /api/users</code>
209
+ {:else if currentDoc.text === "Examples"}
210
+ <h3>Examples</h3>
211
+ <p>Practical examples and code snippets to help you implement common use cases.</p>
212
+ {/if}
213
+ </div>
214
+ </Tabs>
215
+ </div>
216
+
217
+ <style>
218
+ .docs-container {
219
+ max-width: 600px;
220
+ margin: 20px auto;
221
+ }
222
+
223
+ .doc-content {
224
+ padding: 20px;
225
+ background: #f8f9fa;
226
+ }
227
+
228
+ .doc-content h3 {
229
+ margin-top: 0;
230
+ color: #333;
231
+ }
232
+
233
+ .doc-content code {
234
+ background: #e9ecef;
235
+ padding: 4px 8px;
236
+ border-radius: 4px;
237
+ font-family: monospace;
238
+ }
239
+
240
+ .doc-content ol {
241
+ padding-left: 20px;
242
+ }
243
+
244
+ .doc-content li {
245
+ margin: 8px 0;
246
+ }
247
+ </style>
248
+ ```
249
+
250
+ ### Closable Tabs
251
+
252
+ ```svelte
253
+ <script>
254
+ import Tabs from "@ticatec/uniface-element/Tabs";
255
+
256
+ let browserTabs = [
257
+ { id: 1, text: "Google", url: "https://google.com", modified: false },
258
+ { id: 2, text: "GitHub", url: "https://github.com", modified: true },
259
+ { id: 3, text: "Stack Overflow", url: "https://stackoverflow.com", modified: false },
260
+ { id: 4, text: "MDN Docs", url: "https://developer.mozilla.org", modified: false }
261
+ ];
262
+
263
+ let activeTab = browserTabs[0];
264
+
265
+ async function handleTabClose(tab) {
266
+ if (tab.modified) {
267
+ const confirmed = confirm(`"${tab.text}" has unsaved changes. Close anyway?`);
268
+ if (!confirmed) return false;
269
+ }
270
+
271
+ console.log(`Closing tab: ${tab.text}`);
272
+ return true;
273
+ }
274
+
275
+ function addNewTab() {
276
+ const newId = Math.max(...browserTabs.map(t => t.id)) + 1;
277
+ const newTab = {
278
+ id: newId,
279
+ text: "New Tab",
280
+ url: "about:blank",
281
+ modified: false
282
+ };
283
+
284
+ browserTabs = [...browserTabs, newTab];
285
+ activeTab = newTab;
286
+ }
287
+ </script>
288
+
289
+ <div class="browser-container">
290
+ <div class="browser-header">
291
+ <Tabs
292
+ tabs={browserTabs}
293
+ bind:activeTab
294
+ closable={true}
295
+ closeHandler={handleTabClose}
296
+ style="height: 350px;"
297
+ >
298
+ <div class="page-content">
299
+ <div class="address-bar">
300
+ <span>🔒 {activeTab.url}</span>
301
+ </div>
302
+ <div class="page-body">
303
+ <h2>{activeTab.text}</h2>
304
+ <p>This is the content for {activeTab.text}</p>
305
+ {#if activeTab.modified}
306
+ <p class="modified">⚠️ This page has unsaved changes</p>
307
+ {/if}
308
+ <button on:click={() => activeTab.modified = !activeTab.modified}>
309
+ {activeTab.modified ? 'Mark as Saved' : 'Make Changes'}
310
+ </button>
311
+ </div>
312
+ </div>
313
+ </Tabs>
314
+ <button class="new-tab-btn" on:click={addNewTab}>+</button>
315
+ </div>
316
+ </div>
317
+
318
+ <style>
319
+ .browser-container {
320
+ max-width: 900px;
321
+ margin: 20px auto;
322
+ border: 1px solid #ddd;
323
+ border-radius: 8px;
324
+ overflow: hidden;
325
+ }
326
+
327
+ .browser-header {
328
+ display: flex;
329
+ align-items: stretch;
330
+ }
331
+
332
+ .new-tab-btn {
333
+ width: 40px;
334
+ border: none;
335
+ background: #f8f9fa;
336
+ cursor: pointer;
337
+ font-size: 18px;
338
+ border-left: 1px solid #ddd;
339
+ }
340
+
341
+ .new-tab-btn:hover {
342
+ background: #e9ecef;
343
+ }
344
+
345
+ .page-content {
346
+ padding: 0;
347
+ height: 100%;
348
+ display: flex;
349
+ flex-direction: column;
350
+ }
351
+
352
+ .address-bar {
353
+ padding: 8px 16px;
354
+ background: #f8f9fa;
355
+ border-bottom: 1px solid #ddd;
356
+ font-family: monospace;
357
+ font-size: 14px;
358
+ }
359
+
360
+ .page-body {
361
+ padding: 20px;
362
+ flex: 1;
363
+ }
364
+
365
+ .modified {
366
+ color: #dc3545;
367
+ font-weight: 500;
368
+ }
369
+
370
+ button {
371
+ margin-top: 12px;
372
+ padding: 8px 16px;
373
+ border: 1px solid #007bff;
374
+ background: white;
375
+ color: #007bff;
376
+ border-radius: 4px;
377
+ cursor: pointer;
378
+ }
379
+
380
+ button:hover {
381
+ background: #007bff;
382
+ color: white;
383
+ }
384
+ </style>
385
+ ```
386
+
387
+ ### Tabs with Reload Functionality
388
+
389
+ ```svelte
390
+ <script>
391
+ import Tabs from "@ticatec/uniface-element/Tabs";
392
+
393
+ let dataTabs = [
394
+ { id: 1, text: "Sales Data", lastUpdated: "2 min ago", loading: false },
395
+ { id: 2, text: "User Analytics", lastUpdated: "5 min ago", loading: false },
396
+ { id: 3, text: "Performance", lastUpdated: "10 min ago", loading: false }
397
+ ];
398
+
399
+ let activeDataTab = dataTabs[0];
400
+
401
+ function handleTabReload(tab) {
402
+ console.log(`Reloading tab: ${tab.text}`);
403
+
404
+ // Set loading state
405
+ tab.loading = true;
406
+ dataTabs = [...dataTabs];
407
+
408
+ // Simulate data reload
409
+ setTimeout(() => {
410
+ tab.loading = false;
411
+ tab.lastUpdated = "Just now";
412
+ dataTabs = [...dataTabs];
413
+ }, 2000);
414
+ }
415
+ </script>
416
+
417
+ <div class="data-dashboard">
418
+ <Tabs
419
+ tabs={dataTabs}
420
+ bind:activeTab={activeDataTab}
421
+ reloadHandler={handleTabReload}
422
+ style="height: 400px;"
423
+ >
424
+ <div class="data-content">
425
+ <div class="data-header">
426
+ <h3>{activeDataTab.text}</h3>
427
+ <div class="last-updated">
428
+ {#if activeDataTab.loading}
429
+ <span class="loading">🔄 Refreshing...</span>
430
+ {:else}
431
+ <span>Last updated: {activeDataTab.lastUpdated}</span>
432
+ {/if}
433
+ </div>
434
+ </div>
435
+
436
+ <div class="data-body">
437
+ {#if activeDataTab.id === 1}
438
+ <div class="chart-placeholder">
439
+ <h4>Sales Overview</h4>
440
+ <div class="metrics">
441
+ <div>Total Sales: $45,678</div>
442
+ <div>Growth: +12.5%</div>
443
+ <div>Transactions: 234</div>
444
+ </div>
445
+ </div>
446
+ {:else if activeDataTab.id === 2}
447
+ <div class="chart-placeholder">
448
+ <h4>User Engagement</h4>
449
+ <div class="metrics">
450
+ <div>Active Users: 1,890</div>
451
+ <div>Session Duration: 4:32</div>
452
+ <div>Bounce Rate: 23%</div>
453
+ </div>
454
+ </div>
455
+ {:else if activeDataTab.id === 3}
456
+ <div class="chart-placeholder">
457
+ <h4>System Performance</h4>
458
+ <div class="metrics">
459
+ <div>Response Time: 145ms</div>
460
+ <div>Uptime: 99.9%</div>
461
+ <div>CPU Usage: 45%</div>
462
+ </div>
463
+ </div>
464
+ {/if}
465
+ </div>
466
+ </div>
467
+ </Tabs>
468
+ </div>
469
+
470
+ <style>
471
+ .data-dashboard {
472
+ max-width: 800px;
473
+ margin: 20px auto;
474
+ border: 1px solid #ddd;
475
+ border-radius: 8px;
476
+ }
477
+
478
+ .data-content {
479
+ padding: 20px;
480
+ height: 100%;
481
+ display: flex;
482
+ flex-direction: column;
483
+ }
484
+
485
+ .data-header {
486
+ display: flex;
487
+ justify-content: space-between;
488
+ align-items: center;
489
+ margin-bottom: 20px;
490
+ padding-bottom: 12px;
491
+ border-bottom: 1px solid #eee;
492
+ }
493
+
494
+ .data-header h3 {
495
+ margin: 0;
496
+ }
497
+
498
+ .last-updated {
499
+ font-size: 14px;
500
+ color: #666;
501
+ }
502
+
503
+ .loading {
504
+ color: #007bff;
505
+ animation: pulse 1.5s infinite;
506
+ }
507
+
508
+ @keyframes pulse {
509
+ 0%, 100% { opacity: 1; }
510
+ 50% { opacity: 0.5; }
511
+ }
512
+
513
+ .chart-placeholder {
514
+ flex: 1;
515
+ background: #f8f9fa;
516
+ border-radius: 8px;
517
+ padding: 20px;
518
+ text-align: center;
519
+ }
520
+
521
+ .chart-placeholder h4 {
522
+ margin: 0 0 20px 0;
523
+ color: #333;
524
+ }
525
+
526
+ .metrics {
527
+ display: grid;
528
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
529
+ gap: 16px;
530
+ }
531
+
532
+ .metrics div {
533
+ padding: 16px;
534
+ background: white;
535
+ border-radius: 4px;
536
+ font-weight: 500;
537
+ }
538
+ </style>
539
+ ```
540
+
541
+ ### Custom Tab Rendering
542
+
543
+ ```svelte
544
+ <script>
545
+ import Tabs from "@ticatec/uniface-element/Tabs";
546
+ import CustomTab from "./CustomTab.svelte";
547
+
548
+ let projectTabs = [
549
+ {
550
+ id: 1,
551
+ text: "Frontend",
552
+ status: "active",
553
+ notifications: 3,
554
+ color: "#007bff"
555
+ },
556
+ {
557
+ id: 2,
558
+ text: "Backend",
559
+ status: "warning",
560
+ notifications: 1,
561
+ color: "#ffc107"
562
+ },
563
+ {
564
+ id: 3,
565
+ text: "Database",
566
+ status: "error",
567
+ notifications: 5,
568
+ color: "#dc3545"
569
+ },
570
+ {
571
+ id: 4,
572
+ text: "DevOps",
573
+ status: "success",
574
+ notifications: 0,
575
+ color: "#28a745"
576
+ }
577
+ ];
578
+
579
+ let activeProject = projectTabs[0];
580
+
581
+ async function handleProjectClose(tab) {
582
+ const confirmed = confirm(`Close project "${tab.text}"?`);
583
+ return confirmed;
584
+ }
585
+ </script>
586
+
587
+ <!-- CustomTab.svelte -->
588
+ <script>
589
+ export let tab;
590
+ export let closeTab = null;
591
+ export let reloadTab = null;
592
+ export let closable = false;
593
+
594
+ function getStatusIcon(status) {
595
+ switch (status) {
596
+ case 'active': return '🟢';
597
+ case 'warning': return '🟡';
598
+ case 'error': return '🔴';
599
+ case 'success': return '✅';
600
+ default: return '⚪';
601
+ }
602
+ }
603
+ </script>
604
+
605
+ <div class="custom-tab" style="border-left: 3px solid {tab.color};">
606
+ <div class="tab-content">
607
+ <span class="status-icon">{getStatusIcon(tab.status)}</span>
608
+ <span class="tab-text">{tab.text}</span>
609
+ {#if tab.notifications > 0}
610
+ <span class="notification-badge">{tab.notifications}</span>
611
+ {/if}
612
+ </div>
613
+
614
+ <div class="tab-actions">
615
+ {#if reloadTab}
616
+ <button class="action-btn" on:click={reloadTab}>🔄</button>
617
+ {/if}
618
+ {#if closable && closeTab}
619
+ <button class="action-btn close" on:click={closeTab}>×</button>
620
+ {/if}
621
+ </div>
622
+ </div>
623
+
624
+ <style>
625
+ .custom-tab {
626
+ display: flex;
627
+ align-items: center;
628
+ justify-content: space-between;
629
+ padding: 8px 12px;
630
+ background: white;
631
+ border-radius: 4px 4px 0 0;
632
+ min-width: 120px;
633
+ }
634
+
635
+ .tab-content {
636
+ display: flex;
637
+ align-items: center;
638
+ gap: 6px;
639
+ }
640
+
641
+ .status-icon {
642
+ font-size: 12px;
643
+ }
644
+
645
+ .tab-text {
646
+ font-weight: 500;
647
+ }
648
+
649
+ .notification-badge {
650
+ background: #dc3545;
651
+ color: white;
652
+ font-size: 10px;
653
+ padding: 2px 6px;
654
+ border-radius: 10px;
655
+ min-width: 16px;
656
+ text-align: center;
657
+ }
658
+
659
+ .tab-actions {
660
+ display: flex;
661
+ gap: 4px;
662
+ }
663
+
664
+ .action-btn {
665
+ background: none;
666
+ border: none;
667
+ padding: 2px 4px;
668
+ cursor: pointer;
669
+ border-radius: 2px;
670
+ font-size: 12px;
671
+ }
672
+
673
+ .action-btn:hover {
674
+ background: #f8f9fa;
675
+ }
676
+
677
+ .action-btn.close:hover {
678
+ background: #dc3545;
679
+ color: white;
680
+ }
681
+ </style>
682
+
683
+ <!-- Main component -->
684
+ <div class="project-dashboard">
685
+ <Tabs
686
+ tabs={projectTabs}
687
+ bind:activeTab={activeProject}
688
+ tabRender={CustomTab}
689
+ closable={true}
690
+ closeHandler={handleProjectClose}
691
+ style="height: 350px;"
692
+ >
693
+ <div class="project-content">
694
+ <h3>{activeProject.text} Project</h3>
695
+ <div class="project-status">
696
+ <span>Status: </span>
697
+ <span class="status {activeProject.status}">{activeProject.status.toUpperCase()}</span>
698
+ </div>
699
+
700
+ {#if activeProject.notifications > 0}
701
+ <div class="notifications">
702
+ <h4>Notifications ({activeProject.notifications})</h4>
703
+ <ul>
704
+ {#each Array(activeProject.notifications) as _, i}
705
+ <li>Notification #{i + 1} for {activeProject.text}</li>
706
+ {/each}
707
+ </ul>
708
+ </div>
709
+ {:else}
710
+ <p>No notifications for this project.</p>
711
+ {/if}
712
+ </div>
713
+ </Tabs>
714
+ </div>
715
+
716
+ <style>
717
+ .project-dashboard {
718
+ max-width: 800px;
719
+ margin: 20px auto;
720
+ border: 1px solid #ddd;
721
+ border-radius: 8px;
722
+ }
723
+
724
+ .project-content {
725
+ padding: 20px;
726
+ }
727
+
728
+ .project-status {
729
+ margin: 16px 0;
730
+ }
731
+
732
+ .status {
733
+ padding: 4px 8px;
734
+ border-radius: 4px;
735
+ font-weight: bold;
736
+ text-transform: uppercase;
737
+ font-size: 12px;
738
+ }
739
+
740
+ .status.active {
741
+ background: #cce5ff;
742
+ color: #004085;
743
+ }
744
+
745
+ .status.warning {
746
+ background: #fff3cd;
747
+ color: #856404;
748
+ }
749
+
750
+ .status.error {
751
+ background: #f8d7da;
752
+ color: #721c24;
753
+ }
754
+
755
+ .status.success {
756
+ background: #d4edda;
757
+ color: #155724;
758
+ }
759
+
760
+ .notifications h4 {
761
+ margin: 20px 0 12px 0;
762
+ }
763
+
764
+ .notifications ul {
765
+ padding-left: 20px;
766
+ }
767
+
768
+ .notifications li {
769
+ margin: 8px 0;
770
+ }
771
+ </style>
772
+ ```
773
+
774
+ ### Horizontal Scrolling Tabs
775
+
776
+ ```svelte
777
+ <script>
778
+ import Tabs from "@ticatec/uniface-element/Tabs";
779
+
780
+ // Create many tabs to demonstrate scrolling
781
+ let manyTabs = Array.from({length: 15}, (_, i) => ({
782
+ id: i + 1,
783
+ text: `Tab ${i + 1}`,
784
+ content: `This is the content for Tab ${i + 1}. Lorem ipsum dolor sit amet, consectetur adipiscing elit.`
785
+ }));
786
+
787
+ let currentTab = manyTabs[0];
788
+ </script>
789
+
790
+ <div class="scrollable-demo">
791
+ <h3>Horizontal Scrolling Tabs Demo</h3>
792
+ <p>This example shows how tabs automatically scroll when there are too many to fit.</p>
793
+
794
+ <Tabs
795
+ tabs={manyTabs}
796
+ bind:activeTab={currentTab}
797
+ scrollStep={150}
798
+ style="height: 300px; width: 600px;"
799
+ >
800
+ <div class="scroll-content">
801
+ <h4>{currentTab.text}</h4>
802
+ <p>{currentTab.content}</p>
803
+ <div class="tab-info">
804
+ <p><strong>Tab ID:</strong> {currentTab.id}</p>
805
+ <p><strong>Position:</strong> {manyTabs.indexOf(currentTab) + 1} of {manyTabs.length}</p>
806
+ </div>
807
+ </div>
808
+ </Tabs>
809
+ </div>
810
+
811
+ <style>
812
+ .scrollable-demo {
813
+ max-width: 700px;
814
+ margin: 20px auto;
815
+ padding: 20px;
816
+ }
817
+
818
+ .scrollable-demo h3 {
819
+ margin-bottom: 8px;
820
+ }
821
+
822
+ .scrollable-demo p {
823
+ margin-bottom: 20px;
824
+ color: #666;
825
+ }
826
+
827
+ .scroll-content {
828
+ padding: 20px;
829
+ background: #f8f9fa;
830
+ height: 100%;
831
+ }
832
+
833
+ .tab-info {
834
+ margin-top: 20px;
835
+ padding: 12px;
836
+ background: white;
837
+ border-radius: 4px;
838
+ border-left: 3px solid #007bff;
839
+ }
840
+
841
+ .tab-info p {
842
+ margin: 4px 0;
843
+ font-size: 14px;
844
+ }
845
+ </style>
846
+ ```
847
+
848
+ ## Features
849
+
850
+ - **Horizontal Scrolling**: Automatic scroll controls when tabs overflow
851
+ - **Closable Tabs**: Optional tab closing with confirmation callbacks
852
+ - **Reload Functionality**: Built-in reload button with custom handlers
853
+ - **Custom Rendering**: Use custom components for tab appearance
854
+ - **Smooth Animations**: CSS transitions and motion tweening
855
+ - **Keyboard Accessible**: Full keyboard navigation support
856
+ - **Responsive Design**: Adapts to container width
857
+ - **Simple Mode**: Minimalist styling option
858
+
859
+ ## Styling
860
+
861
+ The Tabs component supports extensive CSS customization:
862
+
863
+ ```css
864
+ /* Tab panel container */
865
+ .uniface-tab-panel {
866
+ /* Your custom styles */
867
+ }
868
+
869
+ /* Individual tab styling */
870
+ .uniface-tab {
871
+ /* Tab appearance */
872
+ }
873
+
874
+ .uniface-tab.active {
875
+ /* Active tab styles */
876
+ }
877
+
878
+ /* Simple mode styling */
879
+ .uniface-tabs-wrap.simple {
880
+ /* Simple mode overrides */
881
+ }
882
+
883
+ /* Scroll buttons */
884
+ .scroll-left, .scroll-right {
885
+ /* Scroll control styling */
886
+ }
887
+ ```
888
+
889
+ ## Accessibility
890
+
891
+ - Keyboard navigation with Tab and Arrow keys
892
+ - ARIA attributes for screen readers
893
+ - Focus management and visual indicators
894
+ - Semantic HTML structure
895
+ - High contrast support
896
+
897
+ ## Best Practices
898
+
899
+ 1. **Tab Management**: Keep tab count reasonable for better UX
900
+ 2. **Content Loading**: Use reload functionality for dynamic content
901
+ 3. **Close Confirmation**: Always confirm before closing modified tabs
902
+ 4. **Custom Rendering**: Use custom tab components for complex layouts
903
+ 5. **Responsive Design**: Test tab behavior on different screen sizes
904
+ 6. **Performance**: Consider lazy loading for tab content
905
+
906
+ ## Browser Support
907
+
908
+ - Modern browsers with CSS Grid and Flexbox support
909
+ - Compatible with Svelte 5+
910
+ - Smooth animations on supported browsers
911
+ - Touch-friendly interface
912
+ - Full TypeScript support
913
+
914
+ ## Related Components
915
+
916
+ - `Accordion` - Collapsible content panels
917
+ - `Stepper` - Step-by-step navigation
918
+ - `Breadcrumb` - Hierarchical navigation
919
+ - `Sidebar` - Side navigation component