@ticatec/uniface-element 0.2.0 → 0.2.2
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 +320 -1
- package/README_CN.md +392 -0
- package/dist/accordion/Accordion.svelte +1 -1
- package/dist/action-bar/ActionBar.svelte +7 -1
- package/dist/attachment-files/FileRender.svelte +1 -1
- package/dist/attachment-files/FileUploadBar.svelte +7 -6
- package/dist/attachment-files/FileUploadPanel.svelte +2 -2
- package/dist/base-calendar/DateContext.js +5 -4
- package/dist/base-calendar/YearPickupPanel.svelte +4 -4
- package/dist/card/Card.svelte +1 -1
- package/dist/card/Card.svelte.d.ts +1 -1
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +2 -3
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +46 -1
- package/dist/cascade-options-select/CascadePanel.svelte +1 -1
- package/dist/checkbox/CheckBox.svelte +1 -1
- package/dist/color-picker/ColorPicker.svelte +9 -9
- package/dist/color-picker/ColorPicker.svelte.d.ts +0 -2
- package/dist/color-picker/ColorPickerPanel.svelte +11 -15
- package/dist/color-picker/ColorPickerPanel.svelte.d.ts +1 -1
- package/dist/common/CommonPicker.svelte +2 -2
- package/dist/common/CommonPicker.svelte.d.ts +1 -1
- package/dist/common/MouseClickHandler.d.ts +1 -1
- package/dist/common/Popover.svelte +28 -6
- package/dist/common/Popover.svelte.d.ts +9 -3
- package/dist/common/uniface-utils.js +6 -4
- package/dist/common-editor/CommonEditor.svelte +1 -1
- package/dist/common-editor/CommonEditor.svelte.d.ts +1 -1
- package/dist/common-editor/NumberInput.svelte +1 -1
- package/dist/common-editor/NumberInput.svelte.d.ts +1 -1
- package/dist/concise-data-table/ConciseListTable.svelte +7 -2
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +1 -0
- package/dist/concise-data-table/DataRow.svelte +1 -1
- package/dist/concise-data-table/TableOptions.d.ts +1 -1
- package/dist/data-table/DataTable.svelte +1 -1
- package/dist/data-table/parts/ActionsPanel.svelte +4 -3
- package/dist/data-table/parts/ActionsRow.svelte +3 -3
- package/dist/data-table/parts/ContentPanel.svelte +3 -2
- package/dist/data-table/parts/FixedColumnsPanel.svelte +0 -1
- package/dist/data-table/parts/FixedColumnsPanel.svelte.d.ts +1 -2
- package/dist/data-table/parts/FixedHeaderPanel.svelte +2 -2
- package/dist/data-table/parts/FixedRow.svelte +2 -1
- package/dist/data-table/parts/FixedRow.svelte.d.ts +1 -1
- package/dist/data-table/parts/HrefCell.svelte +23 -2
- package/dist/data-table/parts/PopupMenu.svelte +25 -2
- package/dist/data-table/parts/PopupMenu.svelte.d.ts +8 -1
- package/dist/date-picker/DatePicker.svelte +0 -1
- package/dist/date-picker/DateTimePicker.svelte +3 -3
- package/dist/date-picker/ScrollBar.svelte +4 -7
- package/dist/date-range/DateRangeEditor.svelte +1 -1
- package/dist/dialog/CommonDialog.svelte +8 -5
- package/dist/dialog/CommonDialog.svelte.d.ts +2 -1
- package/dist/dialog/Dialog.svelte +37 -12
- package/dist/dialog/Dialog.svelte.d.ts +4 -3
- package/dist/dialog/DialogBoard.svelte +11 -8
- package/dist/dialog/DialogWrapper.svelte +10 -0
- package/dist/{common-editor/DateInput.svelte.d.ts → dialog/DialogWrapper.svelte.d.ts} +6 -13
- package/dist/dialog/Dialogs.js +1 -1
- package/dist/dialog/ModalResult.d.ts +5 -0
- package/dist/dialog/ModalResult.js +5 -0
- package/dist/drawer/Drawer.svelte +1 -1
- package/dist/form-field/FormField.svelte +2 -1
- package/dist/form-field/FormField.svelte.d.ts +1 -0
- package/dist/form-panel/flex-row-form/FormContainer.svelte +1 -1
- package/dist/form-panel/grid-form/EmptyCell.svelte +8 -7
- package/dist/form-panel/grid-form/EmptyCell.svelte.d.ts +2 -2
- package/dist/form-panel/grid-form/GridField.svelte +1 -1
- package/dist/i18nRes/i18nRes.d.ts +2 -0
- package/dist/i18nRes/i18nRes.js +44 -0
- package/dist/i18nRes/index.d.ts +2 -0
- package/dist/i18nRes/index.js +2 -0
- package/dist/image-files/ImageFilesField.svelte +1 -1
- package/dist/indicator/IndicatorBoard.svelte +1 -1
- package/dist/inline-cell-editor/InvalidEditor.svelte +1 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +6 -6
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +1 -1
- package/dist/layout/flex/FlexBlock.svelte +1 -1
- package/dist/lookup-editor/LookupEditor.svelte +1 -1
- package/dist/memo-editor/MemoEditor.svelte +2 -2
- package/dist/message-box/IMessageBox.d.ts +2 -4
- package/dist/message-box/IMessageBox.js +4 -6
- package/dist/message-box/MessageBoxBoard.svelte +1 -3
- package/dist/options-multi-select/OptionsMultiSelect.svelte +1 -1
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +2 -2
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +1 -1
- package/dist/property-editor/PropertyEditor.svelte +3 -3
- package/dist/text-editor/PasswordEditor.svelte +1 -1
- package/dist/transfer/Transfer.svelte +17 -12
- package/dist/transfer/Transfer.svelte.d.ts +0 -1
- package/dist/unit-number-editor/UnitNumberEditor.svelte +2 -2
- package/docs/buttons/cn/ActionBar.md +459 -0
- package/docs/buttons/cn/Button.md +228 -0
- package/docs/buttons/cn/IconButton.md +294 -0
- package/docs/buttons/cn/README.md +600 -0
- package/docs/buttons/cn/TextButton.md +163 -0
- package/docs/buttons/en/ActionBar.md +459 -0
- package/docs/buttons/en/Button.md +228 -0
- package/docs/buttons/en/IconButton.md +294 -0
- package/docs/buttons/en/README.md +600 -0
- package/docs/buttons/en/TextButton.md +163 -0
- package/docs/containers/cn/accordion.md +622 -0
- package/docs/containers/cn/box.md +445 -0
- package/docs/containers/cn/card.md +404 -0
- package/docs/containers/cn/page.md +576 -0
- package/docs/containers/cn/tabs.md +686 -0
- package/docs/containers/en/accordion.md +622 -0
- package/docs/containers/en/box.md +445 -0
- package/docs/containers/en/card.md +404 -0
- package/docs/containers/en/page.md +576 -0
- package/docs/containers/en/tabs.md +686 -0
- package/docs/data-display/cn/concise-data-table.md +731 -0
- package/docs/data-display/cn/listbox.md +786 -0
- package/docs/data-display/cn/treeview.md +863 -0
- package/docs/data-display/en/concise-data-table.md +732 -0
- package/docs/data-display/en/listbox.md +786 -0
- package/docs/data-display/en/treeview.md +863 -0
- package/docs/data-table/cn/README.md +596 -0
- package/docs/data-table/en/README.md +596 -0
- package/docs/dialog/cn/README.md +767 -0
- package/docs/dialog/en/README.md +767 -0
- package/docs/form/cn/README.md +847 -0
- package/docs/form/en/README.md +847 -0
- package/docs/form-components/cn/README.md +495 -0
- package/docs/form-components/cn/attachmentfilesfield.md +757 -0
- package/docs/form-components/cn/cascade-options-select.md +374 -0
- package/docs/form-components/cn/checkbox.md +58 -0
- package/docs/form-components/cn/date-picker.md +138 -0
- package/docs/form-components/cn/datetime-picker.md +228 -0
- package/docs/form-components/cn/group-checkbox.md +405 -0
- package/docs/form-components/cn/group-radiobox.md +525 -0
- package/docs/form-components/cn/imagefilesfield.md +651 -0
- package/docs/form-components/cn/input-options-select.md +250 -0
- package/docs/form-components/cn/lookup-editor.md +406 -0
- package/docs/form-components/cn/memoeditor.md +409 -0
- package/docs/form-components/cn/number-editor.md +261 -0
- package/docs/form-components/cn/options-multi-select.md +177 -0
- package/docs/form-components/cn/options-select.md +83 -0
- package/docs/form-components/cn/passwordeditor.md +538 -0
- package/docs/form-components/cn/prompts-text-editor.md +241 -0
- package/docs/form-components/cn/radiobutton.md +84 -0
- package/docs/form-components/cn/switch.md +178 -0
- package/docs/form-components/cn/text-editor.md +142 -0
- package/docs/form-components/cn/time-editor.md +159 -0
- package/docs/form-components/cn/unit-number-editor.md +164 -0
- package/docs/form-components/en/README.md +463 -0
- package/docs/form-components/en/attachmentfilesfield.md +757 -0
- package/docs/form-components/en/cascade-options-select.md +358 -0
- package/docs/form-components/en/checkbox.md +59 -0
- package/docs/form-components/en/date-picker.md +138 -0
- package/docs/form-components/en/datetime-picker.md +228 -0
- package/docs/form-components/en/group-checkbox.md +395 -0
- package/docs/form-components/en/group-radiobox.md +498 -0
- package/docs/form-components/en/imagefilesfield.md +651 -0
- package/docs/form-components/en/input-options-select.md +239 -0
- package/docs/form-components/en/lookup-editor.md +389 -0
- package/docs/form-components/en/memoeditor.md +409 -0
- package/docs/form-components/en/number-editor.md +249 -0
- package/docs/form-components/en/options-multi-select.md +177 -0
- package/docs/form-components/en/options-select.md +83 -0
- package/docs/form-components/en/passwordeditor.md +538 -0
- package/docs/form-components/en/prompts-text-editor.md +241 -0
- package/docs/form-components/en/radiobutton.md +84 -0
- package/docs/form-components/en/switch.md +180 -0
- package/docs/form-components/en/text-editor.md +142 -0
- package/docs/form-components/en/time-editor.md +159 -0
- package/docs/form-components/en/unit-number-editor.md +164 -0
- package/docs/form-layout/cn/criteria-field.md +652 -0
- package/docs/form-layout/cn/flex-form.md +454 -0
- package/docs/form-layout/cn/flex-row-form.md +542 -0
- package/docs/form-layout/cn/form-field.md +923 -0
- package/docs/form-layout/cn/grid-form.md +676 -0
- package/docs/form-layout/en/criteria-field.md +652 -0
- package/docs/form-layout/en/flex-form.md +454 -0
- package/docs/form-layout/en/flex-row-form.md +542 -0
- package/docs/form-layout/en/form-field.md +923 -0
- package/docs/form-layout/en/grid-form.md +676 -0
- package/docs/global/cn/README.md +534 -0
- package/docs/global/en/README.md +534 -0
- package/docs/layout/cn/classiclayout.md +460 -0
- package/docs/layout/cn/headerlayout.md +524 -0
- package/docs/layout/cn/sidebarlayout.md +263 -0
- package/docs/layout/en/classiclayout.md +951 -0
- package/docs/layout/en/headerlayout.md +524 -0
- package/docs/layout/en/sidebarlayout.md +262 -0
- package/docs/misc/cn/README.md +1217 -0
- package/docs/misc/en/README.md +1217 -0
- package/docs/navigation/cn/breadcrumb.md +291 -0
- package/docs/navigation/cn/navigator.md +322 -0
- package/docs/navigation/cn/navigatormenu.md +512 -0
- package/docs/navigation/cn/progressbar.md +199 -0
- package/docs/navigation/cn/progressstepbar.md +299 -0
- package/docs/navigation/en/breadcrumb.md +291 -0
- package/docs/navigation/en/navigator.md +322 -0
- package/docs/navigation/en/navigatormenu.md +512 -0
- package/docs/navigation/en/progressbar.md +199 -0
- package/docs/navigation/en/progressstepbar.md +299 -0
- package/docs/search-filters/cn/daterange.md +1156 -0
- package/docs/search-filters/cn/numberrange.md +688 -0
- package/docs/search-filters/cn/searchbox.md +1582 -0
- package/docs/search-filters/en/daterange.md +1156 -0
- package/docs/search-filters/en/numberrange.md +688 -0
- package/docs/search-filters/en/searchbox.md +1582 -0
- package/package.json +53 -13
- package/dist/common-editor/DateInput.svelte +0 -27
- package/dist/i18n_resources/index.d.ts +0 -3
- package/dist/i18n_resources/index.js +0 -3
- /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.d.ts +0 -0
- /package/dist/{i18n_resources → i18nRes}/uniface_cn_resource.js +0 -0
- /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.d.ts +0 -0
- /package/dist/{i18n_resources → i18nRes}/uniface_en_resource.js +0 -0
|
@@ -0,0 +1,1217 @@
|
|
|
1
|
+
# Miscellaneous Components
|
|
2
|
+
|
|
3
|
+
The Uniface Element library provides a collection of utility and layout components for building modern Svelte applications. These components handle common UI patterns and provide flexible layouts.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Split Component](#split-component)
|
|
8
|
+
- [Drawer Component](#drawer-component)
|
|
9
|
+
- [Tag Component](#tag-component)
|
|
10
|
+
- [Card Component](#card-component)
|
|
11
|
+
- [Best Practices](#best-practices)
|
|
12
|
+
|
|
13
|
+
## Split Component
|
|
14
|
+
|
|
15
|
+
The Split component provides resizable dividers for creating split-pane layouts with draggable separators.
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
- **Horizontal and Vertical**: Support for both horizontal and vertical splitting
|
|
20
|
+
- **Draggable Resizing**: Interactive resize handles with mouse drag support
|
|
21
|
+
- **Reversible Direction**: Control resize direction with reverse property
|
|
22
|
+
- **Panel Binding**: Bind to specific panels for controlled resizing
|
|
23
|
+
- **Fixed Mode**: Optionally disable resizing for static layouts
|
|
24
|
+
|
|
25
|
+
### Basic Usage
|
|
26
|
+
|
|
27
|
+
```svelte
|
|
28
|
+
<script lang="ts">
|
|
29
|
+
import Split from '@ticatec/uniface-element/Split';
|
|
30
|
+
|
|
31
|
+
let leftPanel;
|
|
32
|
+
let topPanel;
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<!-- Vertical split (left/right panels) -->
|
|
36
|
+
<div class="split-container">
|
|
37
|
+
<div class="left-panel" bind:this={leftPanel}>
|
|
38
|
+
Left Panel Content
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<Split
|
|
42
|
+
direction="vertical"
|
|
43
|
+
width={4}
|
|
44
|
+
bindingPanel={leftPanel}
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
<div class="right-panel">
|
|
48
|
+
Right Panel Content
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<!-- Horizontal split (top/bottom panels) -->
|
|
53
|
+
<div class="split-container horizontal">
|
|
54
|
+
<div class="top-panel" bind:this={topPanel}>
|
|
55
|
+
Top Panel Content
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<Split
|
|
59
|
+
direction="horizontal"
|
|
60
|
+
width={4}
|
|
61
|
+
bindingPanel={topPanel}
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
<div class="bottom-panel">
|
|
65
|
+
Bottom Panel Content
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<style>
|
|
70
|
+
.split-container {
|
|
71
|
+
display: flex;
|
|
72
|
+
height: 400px;
|
|
73
|
+
width: 100%;
|
|
74
|
+
border: 1px solid #ddd;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.split-container.horizontal {
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.left-panel, .right-panel {
|
|
82
|
+
flex: 1;
|
|
83
|
+
padding: 16px;
|
|
84
|
+
overflow: auto;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.top-panel, .bottom-panel {
|
|
88
|
+
flex: 1;
|
|
89
|
+
padding: 16px;
|
|
90
|
+
overflow: auto;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.left-panel {
|
|
94
|
+
background: #f8f9fa;
|
|
95
|
+
min-width: 150px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.right-panel {
|
|
99
|
+
background: #fff;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.top-panel {
|
|
103
|
+
background: #f8f9fa;
|
|
104
|
+
min-height: 100px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.bottom-panel {
|
|
108
|
+
background: #fff;
|
|
109
|
+
}
|
|
110
|
+
</style>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Advanced Layout
|
|
114
|
+
|
|
115
|
+
```svelte
|
|
116
|
+
<script lang="ts">
|
|
117
|
+
import Split from '@ticatec/uniface-element/Split';
|
|
118
|
+
|
|
119
|
+
let sidebar;
|
|
120
|
+
let contentLeft;
|
|
121
|
+
let contentTop;
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<!-- Complex split layout: sidebar + main content with nested splits -->
|
|
125
|
+
<div class="app-layout">
|
|
126
|
+
<!-- Sidebar -->
|
|
127
|
+
<div class="sidebar" bind:this={sidebar}>
|
|
128
|
+
<h3>Navigation</h3>
|
|
129
|
+
<nav>
|
|
130
|
+
<ul>
|
|
131
|
+
<li>Dashboard</li>
|
|
132
|
+
<li>Projects</li>
|
|
133
|
+
<li>Settings</li>
|
|
134
|
+
</ul>
|
|
135
|
+
</nav>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<!-- Vertical splitter -->
|
|
139
|
+
<Split
|
|
140
|
+
direction="vertical"
|
|
141
|
+
width={3}
|
|
142
|
+
bindingPanel={sidebar}
|
|
143
|
+
/>
|
|
144
|
+
|
|
145
|
+
<!-- Main content area -->
|
|
146
|
+
<div class="main-content">
|
|
147
|
+
<!-- Top content area -->
|
|
148
|
+
<div class="content-top" bind:this={contentTop}>
|
|
149
|
+
<h2>Main Content</h2>
|
|
150
|
+
<p>This is the main content area that can be resized.</p>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<!-- Horizontal splitter -->
|
|
154
|
+
<Split
|
|
155
|
+
direction="horizontal"
|
|
156
|
+
width={3}
|
|
157
|
+
bindingPanel={contentTop}
|
|
158
|
+
reverse={true}
|
|
159
|
+
/>
|
|
160
|
+
|
|
161
|
+
<!-- Bottom content area -->
|
|
162
|
+
<div class="content-bottom">
|
|
163
|
+
<h3>Details Panel</h3>
|
|
164
|
+
<p>Additional details and information.</p>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<style>
|
|
170
|
+
.app-layout {
|
|
171
|
+
display: flex;
|
|
172
|
+
height: 500px;
|
|
173
|
+
width: 100%;
|
|
174
|
+
border: 1px solid #ccc;
|
|
175
|
+
border-radius: 4px;
|
|
176
|
+
overflow: hidden;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.sidebar {
|
|
180
|
+
width: 200px;
|
|
181
|
+
min-width: 150px;
|
|
182
|
+
background: #2c3e50;
|
|
183
|
+
color: white;
|
|
184
|
+
padding: 16px;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.sidebar h3 {
|
|
188
|
+
margin: 0 0 16px 0;
|
|
189
|
+
color: #ecf0f1;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.sidebar nav ul {
|
|
193
|
+
list-style: none;
|
|
194
|
+
padding: 0;
|
|
195
|
+
margin: 0;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.sidebar nav li {
|
|
199
|
+
padding: 8px 0;
|
|
200
|
+
cursor: pointer;
|
|
201
|
+
transition: color 0.2s;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.sidebar nav li:hover {
|
|
205
|
+
color: #3498db;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.main-content {
|
|
209
|
+
flex: 1;
|
|
210
|
+
display: flex;
|
|
211
|
+
flex-direction: column;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.content-top {
|
|
215
|
+
flex: 1;
|
|
216
|
+
min-height: 200px;
|
|
217
|
+
padding: 16px;
|
|
218
|
+
background: #fff;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.content-bottom {
|
|
222
|
+
height: 150px;
|
|
223
|
+
min-height: 100px;
|
|
224
|
+
padding: 16px;
|
|
225
|
+
background: #f8f9fa;
|
|
226
|
+
border-top: 1px solid #dee2e6;
|
|
227
|
+
}
|
|
228
|
+
</style>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Split Properties
|
|
232
|
+
|
|
233
|
+
| Property | Type | Default | Description |
|
|
234
|
+
|----------|------|---------|-------------|
|
|
235
|
+
| `direction` | `'horizontal' \| 'vertical'` | `'vertical'` | Split orientation |
|
|
236
|
+
| `width` | `number` | `2` | Splitter thickness in pixels |
|
|
237
|
+
| `bindingPanel` | `HTMLElement \| null` | `null` | Panel element to resize |
|
|
238
|
+
| `reverse` | `boolean` | `false` | Reverse resize direction |
|
|
239
|
+
|
|
240
|
+
## Drawer Component
|
|
241
|
+
|
|
242
|
+
The Drawer component provides a slide-out panel that can be positioned on the left or right side of the screen.
|
|
243
|
+
|
|
244
|
+
### Features
|
|
245
|
+
|
|
246
|
+
- **Side Positioning**: Left or right side positioning
|
|
247
|
+
- **Smooth Animations**: Fly-in/fly-out transitions with configurable duration
|
|
248
|
+
- **Customizable Width**: Adjustable drawer width
|
|
249
|
+
- **Backdrop Interaction**: Click outside to close
|
|
250
|
+
- **Slot Support**: Flexible content through slots
|
|
251
|
+
|
|
252
|
+
### Basic Usage
|
|
253
|
+
|
|
254
|
+
```svelte
|
|
255
|
+
<script lang="ts">
|
|
256
|
+
import Drawer from '@ticatec/uniface-element/Drawer';
|
|
257
|
+
|
|
258
|
+
let leftDrawerVisible = false;
|
|
259
|
+
let rightDrawerVisible = false;
|
|
260
|
+
|
|
261
|
+
const toggleLeftDrawer = () => {
|
|
262
|
+
leftDrawerVisible = !leftDrawerVisible;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const toggleRightDrawer = () => {
|
|
266
|
+
rightDrawerVisible = !rightDrawerVisible;
|
|
267
|
+
};
|
|
268
|
+
</script>
|
|
269
|
+
|
|
270
|
+
<div class="drawer-demo">
|
|
271
|
+
<h2>Drawer Component Demo</h2>
|
|
272
|
+
|
|
273
|
+
<div class="buttons">
|
|
274
|
+
<button on:click={toggleLeftDrawer}>
|
|
275
|
+
Toggle Left Drawer
|
|
276
|
+
</button>
|
|
277
|
+
|
|
278
|
+
<button on:click={toggleRightDrawer}>
|
|
279
|
+
Toggle Right Drawer
|
|
280
|
+
</button>
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<p>Click the buttons above to open/close drawers.</p>
|
|
284
|
+
</div>
|
|
285
|
+
|
|
286
|
+
<!-- Left Drawer -->
|
|
287
|
+
<Drawer bind:visible={leftDrawerVisible} position="left" width={300}>
|
|
288
|
+
<div class="drawer-content">
|
|
289
|
+
<h3>Left Navigation</h3>
|
|
290
|
+
<nav>
|
|
291
|
+
<a href="#home">Home</a>
|
|
292
|
+
<a href="#about">About</a>
|
|
293
|
+
<a href="#services">Services</a>
|
|
294
|
+
<a href="#contact">Contact</a>
|
|
295
|
+
</nav>
|
|
296
|
+
</div>
|
|
297
|
+
</Drawer>
|
|
298
|
+
|
|
299
|
+
<!-- Right Drawer -->
|
|
300
|
+
<Drawer bind:visible={rightDrawerVisible} position="right" width={350}>
|
|
301
|
+
<div class="drawer-content">
|
|
302
|
+
<h3>Settings Panel</h3>
|
|
303
|
+
<div class="settings">
|
|
304
|
+
<label>
|
|
305
|
+
<input type="checkbox" /> Dark Mode
|
|
306
|
+
</label>
|
|
307
|
+
<label>
|
|
308
|
+
<input type="checkbox" checked /> Notifications
|
|
309
|
+
</label>
|
|
310
|
+
<label>
|
|
311
|
+
<input type="checkbox" /> Auto Save
|
|
312
|
+
</label>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
</Drawer>
|
|
316
|
+
|
|
317
|
+
<style>
|
|
318
|
+
.drawer-demo {
|
|
319
|
+
padding: 40px;
|
|
320
|
+
text-align: center;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.buttons {
|
|
324
|
+
margin: 20px 0;
|
|
325
|
+
display: flex;
|
|
326
|
+
gap: 16px;
|
|
327
|
+
justify-content: center;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.buttons button {
|
|
331
|
+
padding: 10px 20px;
|
|
332
|
+
border: 1px solid #007bff;
|
|
333
|
+
background: #007bff;
|
|
334
|
+
color: white;
|
|
335
|
+
border-radius: 4px;
|
|
336
|
+
cursor: pointer;
|
|
337
|
+
transition: background-color 0.2s;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.buttons button:hover {
|
|
341
|
+
background: #0056b3;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.drawer-content {
|
|
345
|
+
padding: 20px;
|
|
346
|
+
height: 100%;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.drawer-content h3 {
|
|
350
|
+
margin: 0 0 20px 0;
|
|
351
|
+
color: #333;
|
|
352
|
+
border-bottom: 1px solid #eee;
|
|
353
|
+
padding-bottom: 10px;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.drawer-content nav {
|
|
357
|
+
display: flex;
|
|
358
|
+
flex-direction: column;
|
|
359
|
+
gap: 12px;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.drawer-content nav a {
|
|
363
|
+
padding: 8px 12px;
|
|
364
|
+
color: #007bff;
|
|
365
|
+
text-decoration: none;
|
|
366
|
+
border-radius: 4px;
|
|
367
|
+
transition: background-color 0.2s;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.drawer-content nav a:hover {
|
|
371
|
+
background: #f8f9fa;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.settings {
|
|
375
|
+
display: flex;
|
|
376
|
+
flex-direction: column;
|
|
377
|
+
gap: 12px;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.settings label {
|
|
381
|
+
display: flex;
|
|
382
|
+
align-items: center;
|
|
383
|
+
gap: 8px;
|
|
384
|
+
cursor: pointer;
|
|
385
|
+
}
|
|
386
|
+
</style>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Mobile Menu Example
|
|
390
|
+
|
|
391
|
+
```svelte
|
|
392
|
+
<script lang="ts">
|
|
393
|
+
import Drawer from '@ticatec/uniface-element/Drawer';
|
|
394
|
+
|
|
395
|
+
let menuVisible = false;
|
|
396
|
+
|
|
397
|
+
const toggleMenu = () => {
|
|
398
|
+
menuVisible = !menuVisible;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const closeMenu = () => {
|
|
402
|
+
menuVisible = false;
|
|
403
|
+
};
|
|
404
|
+
</script>
|
|
405
|
+
|
|
406
|
+
<!-- Mobile Header -->
|
|
407
|
+
<header class="mobile-header">
|
|
408
|
+
<button class="menu-button" on:click={toggleMenu}>
|
|
409
|
+
<span class="hamburger">☰</span>
|
|
410
|
+
</button>
|
|
411
|
+
<h1>My App</h1>
|
|
412
|
+
<div class="header-actions">
|
|
413
|
+
<!-- Header actions -->
|
|
414
|
+
</div>
|
|
415
|
+
</header>
|
|
416
|
+
|
|
417
|
+
<!-- Mobile Navigation Drawer -->
|
|
418
|
+
<Drawer bind:visible={menuVisible} position="left" width={280}>
|
|
419
|
+
<div class="mobile-menu">
|
|
420
|
+
<div class="menu-header">
|
|
421
|
+
<h2>Menu</h2>
|
|
422
|
+
<button class="close-button" on:click={closeMenu}>×</button>
|
|
423
|
+
</div>
|
|
424
|
+
|
|
425
|
+
<nav class="menu-nav">
|
|
426
|
+
<a href="#dashboard" on:click={closeMenu}>Dashboard</a>
|
|
427
|
+
<a href="#projects" on:click={closeMenu}>Projects</a>
|
|
428
|
+
<a href="#team" on:click={closeMenu}>Team</a>
|
|
429
|
+
<a href="#settings" on:click={closeMenu}>Settings</a>
|
|
430
|
+
|
|
431
|
+
<div class="menu-divider"></div>
|
|
432
|
+
|
|
433
|
+
<a href="#help" on:click={closeMenu}>Help & Support</a>
|
|
434
|
+
<a href="#logout" on:click={closeMenu}>Logout</a>
|
|
435
|
+
</nav>
|
|
436
|
+
</div>
|
|
437
|
+
</Drawer>
|
|
438
|
+
|
|
439
|
+
<style>
|
|
440
|
+
.mobile-header {
|
|
441
|
+
display: flex;
|
|
442
|
+
align-items: center;
|
|
443
|
+
padding: 12px 16px;
|
|
444
|
+
background: #fff;
|
|
445
|
+
border-bottom: 1px solid #eee;
|
|
446
|
+
position: sticky;
|
|
447
|
+
top: 0;
|
|
448
|
+
z-index: 100;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.menu-button {
|
|
452
|
+
background: none;
|
|
453
|
+
border: none;
|
|
454
|
+
font-size: 20px;
|
|
455
|
+
cursor: pointer;
|
|
456
|
+
padding: 8px;
|
|
457
|
+
margin-right: 12px;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.mobile-header h1 {
|
|
461
|
+
flex: 1;
|
|
462
|
+
margin: 0;
|
|
463
|
+
font-size: 1.2em;
|
|
464
|
+
color: #333;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.mobile-menu {
|
|
468
|
+
height: 100%;
|
|
469
|
+
background: #fff;
|
|
470
|
+
display: flex;
|
|
471
|
+
flex-direction: column;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.menu-header {
|
|
475
|
+
display: flex;
|
|
476
|
+
justify-content: space-between;
|
|
477
|
+
align-items: center;
|
|
478
|
+
padding: 16px 20px;
|
|
479
|
+
border-bottom: 1px solid #eee;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
.menu-header h2 {
|
|
483
|
+
margin: 0;
|
|
484
|
+
color: #333;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.close-button {
|
|
488
|
+
background: none;
|
|
489
|
+
border: none;
|
|
490
|
+
font-size: 24px;
|
|
491
|
+
cursor: pointer;
|
|
492
|
+
color: #666;
|
|
493
|
+
width: 32px;
|
|
494
|
+
height: 32px;
|
|
495
|
+
display: flex;
|
|
496
|
+
align-items: center;
|
|
497
|
+
justify-content: center;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.menu-nav {
|
|
501
|
+
flex: 1;
|
|
502
|
+
padding: 16px 0;
|
|
503
|
+
display: flex;
|
|
504
|
+
flex-direction: column;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.menu-nav a {
|
|
508
|
+
padding: 12px 20px;
|
|
509
|
+
color: #333;
|
|
510
|
+
text-decoration: none;
|
|
511
|
+
border-bottom: 1px solid #f5f5f5;
|
|
512
|
+
transition: background-color 0.2s;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.menu-nav a:hover {
|
|
516
|
+
background: #f8f9fa;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.menu-divider {
|
|
520
|
+
height: 1px;
|
|
521
|
+
background: #ddd;
|
|
522
|
+
margin: 8px 20px;
|
|
523
|
+
}
|
|
524
|
+
</style>
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### Drawer Properties
|
|
528
|
+
|
|
529
|
+
| Property | Type | Default | Description |
|
|
530
|
+
|----------|------|---------|-------------|
|
|
531
|
+
| `visible` | `boolean` | `false` | Controls drawer visibility |
|
|
532
|
+
| `width` | `number` | `300` | Drawer width in pixels |
|
|
533
|
+
| `position` | `'left' \| 'right'` | `'left'` | Drawer position |
|
|
534
|
+
|
|
535
|
+
## Tag Component
|
|
536
|
+
|
|
537
|
+
The Tag component displays labeled information with optional remove functionality.
|
|
538
|
+
|
|
539
|
+
### Features
|
|
540
|
+
|
|
541
|
+
- **Multiple Sizes**: Big, middle, and small size variants
|
|
542
|
+
- **Style Variants**: Borderless, border, and round styles
|
|
543
|
+
- **Removable**: Optional remove button with custom handlers
|
|
544
|
+
- **Color Support**: Customizable colors and color classes
|
|
545
|
+
- **Flexible Text**: Display any text content
|
|
546
|
+
|
|
547
|
+
### Basic Usage
|
|
548
|
+
|
|
549
|
+
```svelte
|
|
550
|
+
<script lang="ts">
|
|
551
|
+
import Tag from '@ticatec/uniface-element/Tag';
|
|
552
|
+
|
|
553
|
+
let tags = [
|
|
554
|
+
{ id: 1, text: 'JavaScript', color: 'blue' },
|
|
555
|
+
{ id: 2, text: 'TypeScript', color: 'blue' },
|
|
556
|
+
{ id: 3, text: 'Svelte', color: 'orange' },
|
|
557
|
+
{ id: 4, text: 'CSS', color: 'green' }
|
|
558
|
+
];
|
|
559
|
+
|
|
560
|
+
const removeTag = (tagId: number) => {
|
|
561
|
+
tags = tags.filter(tag => tag.id !== tagId);
|
|
562
|
+
};
|
|
563
|
+
</script>
|
|
564
|
+
|
|
565
|
+
<div class="tag-demo">
|
|
566
|
+
<h3>Default Tags</h3>
|
|
567
|
+
<div class="tag-group">
|
|
568
|
+
{#each tags as tag}
|
|
569
|
+
<Tag
|
|
570
|
+
text={tag.text}
|
|
571
|
+
removable={true}
|
|
572
|
+
removeHandler={() => removeTag(tag.id)}
|
|
573
|
+
/>
|
|
574
|
+
{/each}
|
|
575
|
+
</div>
|
|
576
|
+
|
|
577
|
+
<h3>Size Variants</h3>
|
|
578
|
+
<div class="tag-group">
|
|
579
|
+
<Tag text="Small Tag" size="small" />
|
|
580
|
+
<Tag text="Middle Tag" size="middle" />
|
|
581
|
+
<Tag text="Big Tag" size="big" />
|
|
582
|
+
</div>
|
|
583
|
+
|
|
584
|
+
<h3>Style Variants</h3>
|
|
585
|
+
<div class="tag-group">
|
|
586
|
+
<Tag text="Borderless" variant="borderless" />
|
|
587
|
+
<Tag text="Border" variant="border" />
|
|
588
|
+
<Tag text="Round" variant="round" />
|
|
589
|
+
</div>
|
|
590
|
+
|
|
591
|
+
<h3>Non-removable Tags</h3>
|
|
592
|
+
<div class="tag-group">
|
|
593
|
+
<Tag text="Status: Active" removable={false} color="green" />
|
|
594
|
+
<Tag text="Priority: High" removable={false} color="red" />
|
|
595
|
+
<Tag text="Type: Bug" removable={false} color="orange" />
|
|
596
|
+
</div>
|
|
597
|
+
</div>
|
|
598
|
+
|
|
599
|
+
<style>
|
|
600
|
+
.tag-demo {
|
|
601
|
+
padding: 20px;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.tag-group {
|
|
605
|
+
display: flex;
|
|
606
|
+
flex-wrap: wrap;
|
|
607
|
+
gap: 8px;
|
|
608
|
+
margin: 12px 0 24px 0;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.tag-demo h3 {
|
|
612
|
+
margin: 20px 0 8px 0;
|
|
613
|
+
color: #333;
|
|
614
|
+
font-size: 1.1em;
|
|
615
|
+
}
|
|
616
|
+
</style>
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### Dynamic Tag Management
|
|
620
|
+
|
|
621
|
+
```svelte
|
|
622
|
+
<script lang="ts">
|
|
623
|
+
import Tag from '@ticatec/uniface-element/Tag';
|
|
624
|
+
|
|
625
|
+
let newTagText = '';
|
|
626
|
+
let tags = [
|
|
627
|
+
{ id: 1, text: 'Frontend', color: 'blue' },
|
|
628
|
+
{ id: 2, text: 'Backend', color: 'green' },
|
|
629
|
+
{ id: 3, text: 'Database', color: 'purple' }
|
|
630
|
+
];
|
|
631
|
+
let nextId = 4;
|
|
632
|
+
|
|
633
|
+
const addTag = () => {
|
|
634
|
+
if (newTagText.trim()) {
|
|
635
|
+
tags = [...tags, {
|
|
636
|
+
id: nextId++,
|
|
637
|
+
text: newTagText.trim(),
|
|
638
|
+
color: getRandomColor()
|
|
639
|
+
}];
|
|
640
|
+
newTagText = '';
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
const removeTag = (tagId: number) => {
|
|
645
|
+
tags = tags.filter(tag => tag.id !== tagId);
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
const getRandomColor = () => {
|
|
649
|
+
const colors = ['blue', 'green', 'red', 'orange', 'purple', 'pink'];
|
|
650
|
+
return colors[Math.floor(Math.random() * colors.length)];
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
const handleKeyPress = (event: KeyboardEvent) => {
|
|
654
|
+
if (event.key === 'Enter') {
|
|
655
|
+
addTag();
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
</script>
|
|
659
|
+
|
|
660
|
+
<div class="tag-manager">
|
|
661
|
+
<h3>Skill Tags Manager</h3>
|
|
662
|
+
|
|
663
|
+
<!-- Add new tag -->
|
|
664
|
+
<div class="add-tag-form">
|
|
665
|
+
<input
|
|
666
|
+
type="text"
|
|
667
|
+
bind:value={newTagText}
|
|
668
|
+
placeholder="Enter a skill..."
|
|
669
|
+
on:keypress={handleKeyPress}
|
|
670
|
+
/>
|
|
671
|
+
<button on:click={addTag} disabled={!newTagText.trim()}>
|
|
672
|
+
Add Tag
|
|
673
|
+
</button>
|
|
674
|
+
</div>
|
|
675
|
+
|
|
676
|
+
<!-- Tag list -->
|
|
677
|
+
<div class="tag-list">
|
|
678
|
+
{#each tags as tag (tag.id)}
|
|
679
|
+
<Tag
|
|
680
|
+
text={tag.text}
|
|
681
|
+
color={tag.color}
|
|
682
|
+
variant="round"
|
|
683
|
+
removable={true}
|
|
684
|
+
removeHandler={() => removeTag(tag.id)}
|
|
685
|
+
/>
|
|
686
|
+
{/each}
|
|
687
|
+
|
|
688
|
+
{#if tags.length === 0}
|
|
689
|
+
<p class="empty-state">No tags yet. Add some skills above!</p>
|
|
690
|
+
{/if}
|
|
691
|
+
</div>
|
|
692
|
+
|
|
693
|
+
<!-- Tag count -->
|
|
694
|
+
<div class="tag-stats">
|
|
695
|
+
<small>Total skills: {tags.length}</small>
|
|
696
|
+
</div>
|
|
697
|
+
</div>
|
|
698
|
+
|
|
699
|
+
<style>
|
|
700
|
+
.tag-manager {
|
|
701
|
+
max-width: 500px;
|
|
702
|
+
padding: 20px;
|
|
703
|
+
border: 1px solid #ddd;
|
|
704
|
+
border-radius: 8px;
|
|
705
|
+
background: #fff;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.add-tag-form {
|
|
709
|
+
display: flex;
|
|
710
|
+
gap: 8px;
|
|
711
|
+
margin-bottom: 16px;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.add-tag-form input {
|
|
715
|
+
flex: 1;
|
|
716
|
+
padding: 8px 12px;
|
|
717
|
+
border: 1px solid #ddd;
|
|
718
|
+
border-radius: 4px;
|
|
719
|
+
font-size: 14px;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.add-tag-form button {
|
|
723
|
+
padding: 8px 16px;
|
|
724
|
+
background: #007bff;
|
|
725
|
+
color: white;
|
|
726
|
+
border: none;
|
|
727
|
+
border-radius: 4px;
|
|
728
|
+
cursor: pointer;
|
|
729
|
+
font-size: 14px;
|
|
730
|
+
transition: background-color 0.2s;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.add-tag-form button:hover:not(:disabled) {
|
|
734
|
+
background: #0056b3;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
.add-tag-form button:disabled {
|
|
738
|
+
background: #6c757d;
|
|
739
|
+
cursor: not-allowed;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
.tag-list {
|
|
743
|
+
display: flex;
|
|
744
|
+
flex-wrap: wrap;
|
|
745
|
+
gap: 8px;
|
|
746
|
+
min-height: 40px;
|
|
747
|
+
margin-bottom: 12px;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
.empty-state {
|
|
751
|
+
color: #666;
|
|
752
|
+
font-style: italic;
|
|
753
|
+
margin: 0;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
.tag-stats {
|
|
757
|
+
text-align: right;
|
|
758
|
+
color: #666;
|
|
759
|
+
}
|
|
760
|
+
</style>
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### Tag Properties
|
|
764
|
+
|
|
765
|
+
| Property | Type | Default | Description |
|
|
766
|
+
|----------|------|---------|-------------|
|
|
767
|
+
| `size` | `'big' \| 'middle' \| 'small'` | `'middle'` | Tag size variant |
|
|
768
|
+
| `variant` | `'borderless' \| 'border' \| 'round'` | `'border'` | Visual style variant |
|
|
769
|
+
| `removable` | `boolean` | `true` | Show remove button |
|
|
770
|
+
| `text` | `string` | `''` | Tag text content |
|
|
771
|
+
| `style` | `string` | `''` | Custom CSS styles |
|
|
772
|
+
| `class` | `string` | `''` | CSS class name |
|
|
773
|
+
| `removeHandler` | `MouseClickHandler` | - | Remove button click handler |
|
|
774
|
+
| `color` | `string` | - | Color class identifier |
|
|
775
|
+
|
|
776
|
+
## Card Component
|
|
777
|
+
|
|
778
|
+
The Card component provides a container with optional header, content, and action areas.
|
|
779
|
+
|
|
780
|
+
### Features
|
|
781
|
+
|
|
782
|
+
- **Flexible Layout**: Header, content, and action sections
|
|
783
|
+
- **Style Variants**: Plain and 3D shadow variants
|
|
784
|
+
- **Action Support**: Built-in action bar with configurable actions
|
|
785
|
+
- **Slot System**: Flexible content through named slots
|
|
786
|
+
- **Data Binding**: Pass data context to actions
|
|
787
|
+
|
|
788
|
+
### Basic Usage
|
|
789
|
+
|
|
790
|
+
```svelte
|
|
791
|
+
<script lang="ts">
|
|
792
|
+
import Card from '@ticatec/uniface-element/Card';
|
|
793
|
+
import type { CardAction } from '@ticatec/uniface-element';
|
|
794
|
+
|
|
795
|
+
const user = {
|
|
796
|
+
name: 'John Doe',
|
|
797
|
+
email: 'john@example.com',
|
|
798
|
+
avatar: '/avatars/john.jpg'
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
const cardActions: CardAction[] = [
|
|
802
|
+
{
|
|
803
|
+
icon: 'icon_google_edit',
|
|
804
|
+
hint: 'Edit Profile',
|
|
805
|
+
callback: (data) => {
|
|
806
|
+
console.log('Edit user:', data);
|
|
807
|
+
}
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
icon: 'icon_google_delete',
|
|
811
|
+
hint: 'Delete User',
|
|
812
|
+
callback: (data) => {
|
|
813
|
+
console.log('Delete user:', data);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
];
|
|
817
|
+
</script>
|
|
818
|
+
|
|
819
|
+
<div class="card-demo">
|
|
820
|
+
<!-- Simple card with title -->
|
|
821
|
+
<Card title="User Profile" variant="plain">
|
|
822
|
+
<div class="profile-content">
|
|
823
|
+
<img src={user.avatar} alt={user.name} class="avatar" />
|
|
824
|
+
<div class="user-info">
|
|
825
|
+
<h3>{user.name}</h3>
|
|
826
|
+
<p>{user.email}</p>
|
|
827
|
+
</div>
|
|
828
|
+
</div>
|
|
829
|
+
</Card>
|
|
830
|
+
|
|
831
|
+
<!-- Card with actions -->
|
|
832
|
+
<Card
|
|
833
|
+
title="User Management"
|
|
834
|
+
variant="3d"
|
|
835
|
+
actions={cardActions}
|
|
836
|
+
data={user}
|
|
837
|
+
>
|
|
838
|
+
<div class="user-details">
|
|
839
|
+
<p><strong>Name:</strong> {user.name}</p>
|
|
840
|
+
<p><strong>Email:</strong> {user.email}</p>
|
|
841
|
+
<p><strong>Status:</strong> Active</p>
|
|
842
|
+
</div>
|
|
843
|
+
</Card>
|
|
844
|
+
|
|
845
|
+
<!-- Card with custom header -->
|
|
846
|
+
<Card variant="plain">
|
|
847
|
+
<div slot="header-bar" class="custom-header">
|
|
848
|
+
<h3>Custom Header</h3>
|
|
849
|
+
<span class="status-badge">Online</span>
|
|
850
|
+
</div>
|
|
851
|
+
|
|
852
|
+
<div class="card-body">
|
|
853
|
+
<p>This card has a custom header with additional elements.</p>
|
|
854
|
+
</div>
|
|
855
|
+
|
|
856
|
+
<div slot="action-bar" class="custom-actions">
|
|
857
|
+
<button class="btn-primary">Save</button>
|
|
858
|
+
<button class="btn-secondary">Cancel</button>
|
|
859
|
+
</div>
|
|
860
|
+
</Card>
|
|
861
|
+
</div>
|
|
862
|
+
|
|
863
|
+
<style>
|
|
864
|
+
.card-demo {
|
|
865
|
+
display: grid;
|
|
866
|
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
867
|
+
gap: 20px;
|
|
868
|
+
padding: 20px;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.profile-content {
|
|
872
|
+
display: flex;
|
|
873
|
+
align-items: center;
|
|
874
|
+
gap: 16px;
|
|
875
|
+
padding: 16px;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.avatar {
|
|
879
|
+
width: 60px;
|
|
880
|
+
height: 60px;
|
|
881
|
+
border-radius: 50%;
|
|
882
|
+
object-fit: cover;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
.user-info h3 {
|
|
886
|
+
margin: 0 0 4px 0;
|
|
887
|
+
color: #333;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.user-info p {
|
|
891
|
+
margin: 0;
|
|
892
|
+
color: #666;
|
|
893
|
+
font-size: 0.9em;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.user-details {
|
|
897
|
+
padding: 16px;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.user-details p {
|
|
901
|
+
margin: 8px 0;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.custom-header {
|
|
905
|
+
display: flex;
|
|
906
|
+
justify-content: space-between;
|
|
907
|
+
align-items: center;
|
|
908
|
+
padding: 12px 16px;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
.custom-header h3 {
|
|
912
|
+
margin: 0;
|
|
913
|
+
color: #333;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.status-badge {
|
|
917
|
+
background: #28a745;
|
|
918
|
+
color: white;
|
|
919
|
+
padding: 4px 8px;
|
|
920
|
+
border-radius: 12px;
|
|
921
|
+
font-size: 0.8em;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
.card-body {
|
|
925
|
+
padding: 16px;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
.custom-actions {
|
|
929
|
+
display: flex;
|
|
930
|
+
gap: 8px;
|
|
931
|
+
padding: 12px 16px;
|
|
932
|
+
background: #f8f9fa;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
.btn-primary, .btn-secondary {
|
|
936
|
+
padding: 6px 12px;
|
|
937
|
+
border-radius: 4px;
|
|
938
|
+
border: none;
|
|
939
|
+
cursor: pointer;
|
|
940
|
+
font-size: 0.9em;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
.btn-primary {
|
|
944
|
+
background: #007bff;
|
|
945
|
+
color: white;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
.btn-secondary {
|
|
949
|
+
background: #6c757d;
|
|
950
|
+
color: white;
|
|
951
|
+
}
|
|
952
|
+
</style>
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
### Card Grid Layout
|
|
956
|
+
|
|
957
|
+
```svelte
|
|
958
|
+
<script lang="ts">
|
|
959
|
+
import Card from '@ticatec/uniface-element/Card';
|
|
960
|
+
|
|
961
|
+
const projects = [
|
|
962
|
+
{
|
|
963
|
+
id: 1,
|
|
964
|
+
title: 'E-commerce Platform',
|
|
965
|
+
description: 'Modern online shopping platform with React and Node.js',
|
|
966
|
+
status: 'In Progress',
|
|
967
|
+
progress: 75
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
id: 2,
|
|
971
|
+
title: 'Mobile Banking App',
|
|
972
|
+
description: 'Secure mobile banking application for iOS and Android',
|
|
973
|
+
status: 'Completed',
|
|
974
|
+
progress: 100
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
id: 3,
|
|
978
|
+
title: 'Data Analytics Dashboard',
|
|
979
|
+
description: 'Real-time analytics dashboard with interactive charts',
|
|
980
|
+
status: 'Planning',
|
|
981
|
+
progress: 25
|
|
982
|
+
}
|
|
983
|
+
];
|
|
984
|
+
|
|
985
|
+
const getProjectActions = (project) => [
|
|
986
|
+
{
|
|
987
|
+
icon: 'icon_google_visibility',
|
|
988
|
+
hint: 'View Project',
|
|
989
|
+
callback: (data) => console.log('View project:', data.title)
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
icon: 'icon_google_edit',
|
|
993
|
+
hint: 'Edit Project',
|
|
994
|
+
callback: (data) => console.log('Edit project:', data.title)
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
icon: 'icon_google_more_vert',
|
|
998
|
+
hint: 'More Options',
|
|
999
|
+
callback: (data) => console.log('More options:', data.title)
|
|
1000
|
+
}
|
|
1001
|
+
];
|
|
1002
|
+
</script>
|
|
1003
|
+
|
|
1004
|
+
<div class="project-grid">
|
|
1005
|
+
<h2>Project Dashboard</h2>
|
|
1006
|
+
|
|
1007
|
+
<div class="grid">
|
|
1008
|
+
{#each projects as project}
|
|
1009
|
+
<Card
|
|
1010
|
+
title={project.title}
|
|
1011
|
+
variant="3d"
|
|
1012
|
+
actions={getProjectActions(project)}
|
|
1013
|
+
data={project}
|
|
1014
|
+
>
|
|
1015
|
+
<div class="project-card-content">
|
|
1016
|
+
<p class="description">{project.description}</p>
|
|
1017
|
+
|
|
1018
|
+
<div class="project-meta">
|
|
1019
|
+
<div class="status">
|
|
1020
|
+
<span class="status-label">Status:</span>
|
|
1021
|
+
<span class="status-value status-{project.status.toLowerCase().replace(' ', '-')}">
|
|
1022
|
+
{project.status}
|
|
1023
|
+
</span>
|
|
1024
|
+
</div>
|
|
1025
|
+
|
|
1026
|
+
<div class="progress">
|
|
1027
|
+
<span class="progress-label">Progress:</span>
|
|
1028
|
+
<div class="progress-bar">
|
|
1029
|
+
<div
|
|
1030
|
+
class="progress-fill"
|
|
1031
|
+
style="width: {project.progress}%"
|
|
1032
|
+
></div>
|
|
1033
|
+
</div>
|
|
1034
|
+
<span class="progress-text">{project.progress}%</span>
|
|
1035
|
+
</div>
|
|
1036
|
+
</div>
|
|
1037
|
+
</div>
|
|
1038
|
+
</Card>
|
|
1039
|
+
{/each}
|
|
1040
|
+
</div>
|
|
1041
|
+
</div>
|
|
1042
|
+
|
|
1043
|
+
<style>
|
|
1044
|
+
.project-grid {
|
|
1045
|
+
padding: 20px;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
.project-grid h2 {
|
|
1049
|
+
margin: 0 0 24px 0;
|
|
1050
|
+
color: #333;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.grid {
|
|
1054
|
+
display: grid;
|
|
1055
|
+
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
|
1056
|
+
gap: 20px;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
.project-card-content {
|
|
1060
|
+
padding: 16px;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
.description {
|
|
1064
|
+
color: #666;
|
|
1065
|
+
line-height: 1.5;
|
|
1066
|
+
margin: 0 0 16px 0;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.project-meta {
|
|
1070
|
+
display: flex;
|
|
1071
|
+
flex-direction: column;
|
|
1072
|
+
gap: 12px;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
.status, .progress {
|
|
1076
|
+
display: flex;
|
|
1077
|
+
align-items: center;
|
|
1078
|
+
gap: 8px;
|
|
1079
|
+
font-size: 0.9em;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
.status-label, .progress-label {
|
|
1083
|
+
font-weight: 500;
|
|
1084
|
+
color: #333;
|
|
1085
|
+
min-width: 60px;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
.status-value {
|
|
1089
|
+
padding: 2px 8px;
|
|
1090
|
+
border-radius: 12px;
|
|
1091
|
+
font-size: 0.8em;
|
|
1092
|
+
font-weight: 500;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
.status-completed {
|
|
1096
|
+
background: #d4edda;
|
|
1097
|
+
color: #155724;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.status-in-progress {
|
|
1101
|
+
background: #d1ecf1;
|
|
1102
|
+
color: #0c5460;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.status-planning {
|
|
1106
|
+
background: #fff3cd;
|
|
1107
|
+
color: #856404;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
.progress-bar {
|
|
1111
|
+
flex: 1;
|
|
1112
|
+
height: 6px;
|
|
1113
|
+
background: #e9ecef;
|
|
1114
|
+
border-radius: 3px;
|
|
1115
|
+
overflow: hidden;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
.progress-fill {
|
|
1119
|
+
height: 100%;
|
|
1120
|
+
background: #007bff;
|
|
1121
|
+
transition: width 0.3s ease;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
.progress-text {
|
|
1125
|
+
min-width: 35px;
|
|
1126
|
+
text-align: right;
|
|
1127
|
+
font-size: 0.8em;
|
|
1128
|
+
color: #666;
|
|
1129
|
+
}
|
|
1130
|
+
</style>
|
|
1131
|
+
```
|
|
1132
|
+
|
|
1133
|
+
### Card Properties
|
|
1134
|
+
|
|
1135
|
+
| Property | Type | Default | Description |
|
|
1136
|
+
|----------|------|---------|-------------|
|
|
1137
|
+
| `style` | `string` | `''` | Custom CSS styles |
|
|
1138
|
+
| `title` | `string` | - | Card title text |
|
|
1139
|
+
| `actions` | `CardAction[]` | `[]` | Action button configurations |
|
|
1140
|
+
| `variant` | `'plain' \| '3d'` | `'plain'` | Visual style variant |
|
|
1141
|
+
| `iconColor` | `string \| null` | `null` | Action icon color |
|
|
1142
|
+
| `data` | `any` | - | Data passed to action handlers |
|
|
1143
|
+
|
|
1144
|
+
### CardAction Interface
|
|
1145
|
+
|
|
1146
|
+
```typescript
|
|
1147
|
+
interface CardAction {
|
|
1148
|
+
icon?: string; // Icon class name
|
|
1149
|
+
img?: string; // Image source URL
|
|
1150
|
+
hint?: string; // Tooltip text
|
|
1151
|
+
disabled?: boolean; // Disable action
|
|
1152
|
+
callback: (data: any) => void; // Click handler
|
|
1153
|
+
}
|
|
1154
|
+
```
|
|
1155
|
+
|
|
1156
|
+
## Best Practices
|
|
1157
|
+
|
|
1158
|
+
### 1. Split Component Usage
|
|
1159
|
+
|
|
1160
|
+
```svelte
|
|
1161
|
+
<!-- Provide minimum sizes for panels -->
|
|
1162
|
+
<style>
|
|
1163
|
+
.resizable-panel {
|
|
1164
|
+
min-width: 200px;
|
|
1165
|
+
min-height: 150px;
|
|
1166
|
+
}
|
|
1167
|
+
</style>
|
|
1168
|
+
|
|
1169
|
+
<!-- Use appropriate binding -->
|
|
1170
|
+
<Split bindingPanel={panelElement} direction="vertical" />
|
|
1171
|
+
```
|
|
1172
|
+
|
|
1173
|
+
### 2. Drawer Accessibility
|
|
1174
|
+
|
|
1175
|
+
```svelte
|
|
1176
|
+
<!-- Add proper ARIA labels and keyboard support -->
|
|
1177
|
+
<Drawer bind:visible={drawerOpen} position="left">
|
|
1178
|
+
<div role="navigation" aria-label="Main navigation">
|
|
1179
|
+
<!-- Navigation content -->
|
|
1180
|
+
</div>
|
|
1181
|
+
</Drawer>
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
### 3. Tag Management
|
|
1185
|
+
|
|
1186
|
+
```svelte
|
|
1187
|
+
<!-- Provide clear visual feedback for removable tags -->
|
|
1188
|
+
<Tag
|
|
1189
|
+
text="Removable Tag"
|
|
1190
|
+
removable={true}
|
|
1191
|
+
removeHandler={() => handleRemove()}
|
|
1192
|
+
aria-label="Remove tag"
|
|
1193
|
+
/>
|
|
1194
|
+
```
|
|
1195
|
+
|
|
1196
|
+
### 4. Card Organization
|
|
1197
|
+
|
|
1198
|
+
```svelte
|
|
1199
|
+
<!-- Use consistent card layouts in grids -->
|
|
1200
|
+
<div class="card-grid">
|
|
1201
|
+
{#each items as item}
|
|
1202
|
+
<Card title={item.title} variant="3d">
|
|
1203
|
+
<!-- Consistent content structure -->
|
|
1204
|
+
</Card>
|
|
1205
|
+
{/each}
|
|
1206
|
+
</div>
|
|
1207
|
+
|
|
1208
|
+
<style>
|
|
1209
|
+
.card-grid {
|
|
1210
|
+
display: grid;
|
|
1211
|
+
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
1212
|
+
gap: 20px;
|
|
1213
|
+
}
|
|
1214
|
+
</style>
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
These miscellaneous components provide essential UI patterns for modern applications, offering flexibility and consistent design while maintaining usability and accessibility standards.
|