@mlightcad/ui-components 0.1.1 → 0.1.3

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 ADDED
@@ -0,0 +1,329 @@
1
+ # Common UI Component Libaray
2
+
3
+ This is one common UI component library based on Element Plus.
4
+
5
+ ## Components
6
+
7
+ The following components are included in this package.
8
+
9
+ - Tool Palette: one dockable, resizable, and floating window, which is quite similar to AutoCAD Tool Palette.
10
+ - Toolbar: one toolbar which can be easily customized by one array of button data.
11
+
12
+ [**🌐 Live Demo**](https://mlightcad.gitlab.io/ui-components/).
13
+
14
+ ### Tool Palette
15
+
16
+ AutoCAD uses [tool palettes](https://help.autodesk.com/view/ACD/2025/ENU/?guid=GUID-167A8594-92CB-4FCC-B72C-0F546383E97C) to organize blocks, hatches, and custom tools in a tabbed window. Tool Palette component is quite similar to one in AutoCAD. It supports the following features.
17
+
18
+ - Dockable: dock to the left or right side of the window
19
+ - Folderable: roll open or closed as your need
20
+ - Auto-hide: roll open and closed as the cursor moves across it. When this option is cleared, the full tool palette stays open continuously.
21
+
22
+ <img src="./doc/palette.jpg" alt="Tool Palette Example">
23
+
24
+ You can customize tool palette by the following properties.
25
+
26
+ ```javascript
27
+ /**
28
+ * Properties of MlToolPalette component
29
+ */
30
+ interface Props {
31
+ /**
32
+ * The title of tool palette dialog
33
+ */
34
+ title?: string
35
+ /**
36
+ * Array of tab definitions. If provided, the tool palette will display tabs.
37
+ */
38
+ tabs?: MlToolPaletteTab[]
39
+ /**
40
+ * The minimum distance from the left side of the tool palette to the left side of the window
41
+ */
42
+ leftOffset?: number
43
+ /**
44
+ * The minimum distance from the right side of the tool palette to the right side of the window
45
+ */
46
+ rightOffset?: number
47
+ /**
48
+ * The minimum distance from the top side of the tool palette to the top side of the window
49
+ */
50
+ topOffset?: number
51
+ /**
52
+ * The minimum distance from the bottom side of the tool palette to the bottom side of the window
53
+ */
54
+ bottomOffset?: number
55
+ }
56
+ ```
57
+
58
+ Tabs in tool palette are described by the following data structure.
59
+
60
+ ```javascript
61
+ /**
62
+ * Tab definition for tool palette
63
+ */
64
+ export interface MlToolPaletteTab {
65
+ /**
66
+ * Unique name identifier for the tab
67
+ */
68
+ name: string
69
+ /**
70
+ * Display label for the tab
71
+ */
72
+ label: string
73
+ /**
74
+ * Title to display in the title bar when this tab is active
75
+ */
76
+ title?: string
77
+ }
78
+ ```
79
+
80
+ Four `offsetXXX` properties are used to set the minimum distance from the side of the tool palette to the side of the window. It is quite useful if you want the tool palette is shown within certain area. For example, one web page has one title bar at the top of window, one status bar at the bottom of window, and one canvas area between the title bar and the status bar. The height of the title bar is 60px and the height of the status bar is 20px. Then you can set `topOffset` to 60 and `bottomOffset` to 20 to let the tool palette are shown and moved within canvas area only.
81
+
82
+ #### Basic Usage
83
+
84
+ ```javascript
85
+ <script lang="ts" setup>
86
+ import { MlToolPalette } from '@mlightcad/ui-components'
87
+ const toolPaletteVisible = ref<boolean>(false)
88
+ </script>
89
+
90
+ <template>
91
+ <ml-tool-palette
92
+ class="tool-palette"
93
+ v-model="toolPaletteVisible"
94
+ title="Tool Palette Test"
95
+ :top-offset="60"
96
+ :bottom-offset="20"
97
+ >
98
+ <span>Tool Palette Test</span>
99
+ </ml-tool-palette>
100
+ </template>
101
+
102
+ <style scoped>
103
+ .tool-palette {
104
+ position: fixed;
105
+ top: 55px;
106
+ width: 400px;
107
+ }
108
+ </style>
109
+ ```
110
+
111
+ #### Using Tabs
112
+
113
+ Tool Palette supports multiple tabs to organize different content. Each tab can have its own content and title. When a tab becomes active, its `title` (if provided) will be displayed in the title bar of the tool palette.
114
+
115
+ ```javascript
116
+ <script lang="ts" setup>
117
+ import { MlToolPalette, MlToolPaletteTab } from '@mlightcad/ui-components'
118
+ import { ref, reactive } from 'vue'
119
+
120
+ const toolPaletteVisible = ref<boolean>(true)
121
+ const activeTab = ref<string>('blocks')
122
+
123
+ const tabs = reactive<MlToolPaletteTab[]>([
124
+ {
125
+ name: 'blocks',
126
+ label: 'Blocks',
127
+ title: 'Blocks Palette'
128
+ },
129
+ {
130
+ name: 'hatches',
131
+ label: 'Hatches',
132
+ title: 'Hatches Palette'
133
+ },
134
+ {
135
+ name: 'tools',
136
+ label: 'Tools',
137
+ title: 'Custom Tools'
138
+ }
139
+ ])
140
+
141
+ const handleTabChange = (tabName: string) => {
142
+ console.log('Tab changed to:', tabName)
143
+ }
144
+
145
+ const handleTabClose = (tabName: string) => {
146
+ console.log('Tab closed:', tabName)
147
+ const index = tabs.findIndex(t => t.name === tabName)
148
+ if (index >= 0) {
149
+ tabs.splice(index, 1)
150
+ // If the closed tab was active, switch to another tab
151
+ if (activeTab.value === tabName && tabs.length > 0) {
152
+ activeTab.value = tabs[0].name
153
+ }
154
+ }
155
+ }
156
+ </script>
157
+
158
+ <template>
159
+ <ml-tool-palette
160
+ class="tool-palette"
161
+ v-model="toolPaletteVisible"
162
+ v-model:active-tab="activeTab"
163
+ title="Tool Palette"
164
+ :tabs="tabs"
165
+ :top-offset="60"
166
+ :bottom-offset="20"
167
+ @tab-change="handleTabChange"
168
+ @tab-close="handleTabClose"
169
+ >
170
+ <template #tab-blocks>
171
+ <div class="tab-content">
172
+ <h3>Blocks</h3>
173
+ <p>This is the Blocks tab content.</p>
174
+ <el-button>Block 1</el-button>
175
+ <el-button>Block 2</el-button>
176
+ </div>
177
+ </template>
178
+ <template #tab-hatches>
179
+ <div class="tab-content">
180
+ <h3>Hatches</h3>
181
+ <p>This is the Hatches tab content.</p>
182
+ <el-button>Hatch Pattern 1</el-button>
183
+ <el-button>Hatch Pattern 2</el-button>
184
+ </div>
185
+ </template>
186
+ <template #tab-tools>
187
+ <div class="tab-content">
188
+ <h3>Custom Tools</h3>
189
+ <p>This is the Tools tab content.</p>
190
+ <el-button>Custom Tool 1</el-button>
191
+ <el-button>Custom Tool 2</el-button>
192
+ </div>
193
+ </template>
194
+ </ml-tool-palette>
195
+ </template>
196
+
197
+ <style scoped>
198
+ .tool-palette {
199
+ position: fixed;
200
+ top: 55px;
201
+ width: 400px;
202
+ height: 500px;
203
+ }
204
+
205
+ .tab-content {
206
+ padding: 16px;
207
+ display: flex;
208
+ flex-direction: column;
209
+ gap: 12px;
210
+ }
211
+ </style>
212
+ ```
213
+
214
+ **Tab Features:**
215
+ - **Closeable tabs**: Each tab has a close icon that can be clicked to close the tab
216
+ - **Active tab title**: When a tab is active, its `title` property (if provided) is displayed in the title bar
217
+ - **Tab switching**: Use `v-model:active-tab` to control which tab is active
218
+ - **Tab events**:
219
+ - `@tab-change`: Emitted when the active tab changes
220
+ - `@tab-close`: Emitted when a tab is closed
221
+ - **Tab content**: Use named slots `#tab-{name}` to provide content for each tab
222
+ - **Overflow handling**: When there are many tabs, Element Plus automatically handles overflow with a dropdown menu
223
+
224
+ ### Toolbar
225
+
226
+ Toolbar component has the followiing features.
227
+
228
+ - Define button list by one array of `MlButtonData`
229
+ - Arrange button vertically or horizontally
230
+ - Support three kind of button size
231
+
232
+ <img src="./doc/toolbar.jpg" width="423" height="223" alt="ViewCube Example">
233
+
234
+ Features above can be customized by the following properties.
235
+
236
+ ```javascript
237
+ /**
238
+ * Properties of MLToolBar components
239
+ */
240
+ interface Props {
241
+ /**
242
+ * An array of button data
243
+ */
244
+ items: MlButtonData[]
245
+ /**
246
+ * Button size.
247
+ * - small: 30px
248
+ * - medium: 50px
249
+ * - large: 70px
250
+ */
251
+ size?: 'small' | 'medium'| 'large'
252
+ /**
253
+ * Layout type.
254
+ * - vertical: arrange button vertically
255
+ * - horizontal: arrange button horizontally
256
+ */
257
+ direction?: 'vertical' | 'horizontal'
258
+ }
259
+ ```
260
+
261
+ Buttons in toolbar are described by the following data. Property `icon` can be icon provided by Element Plus or icon imported through `vite-svg-loader`.
262
+
263
+ ```javascript
264
+ /**
265
+ * Data to descibe button appearance
266
+ */
267
+ export interface MlButtonData {
268
+ /**
269
+ * Icon represented by one vue component
270
+ */
271
+ icon: Component
272
+ /**
273
+ * Text shown below icon
274
+ */
275
+ text: string
276
+ /**
277
+ * Command string which will be passed to click event as event arguments
278
+ */
279
+ command: string
280
+ /**
281
+ * Tooltips content when hover
282
+ */
283
+ description?: string
284
+ }
285
+ ```
286
+
287
+ Usage of this component is as follows.
288
+
289
+ ```javascript
290
+ <script setup lang="ts">
291
+ import '@mlightcad/ui-components/dist/style.css'
292
+ import { MlButtonData, MlToolbar } from '@mlightcad/ui-components'
293
+ import { reactive } from 'vue'
294
+ import { Delete, Edit, Search } from '@element-plus/icons-vue'
295
+
296
+ const data = reactive<MlButtonData[]>([
297
+ {
298
+ icon: Edit,
299
+ text: 'Edit',
300
+ command: 'edit',
301
+ description: 'This is description for edit button'
302
+ },
303
+ {
304
+ icon: Delete,
305
+ text: 'Delete',
306
+ command: 'delete',
307
+ description: 'This is description for delete button'
308
+ },
309
+ {
310
+ icon: Search,
311
+ text: 'Search',
312
+ command: 'search',
313
+ description: 'This is description for search button'
314
+ }
315
+ ])
316
+
317
+ const handleCommand = (command: string) => {
318
+ console.log(command)
319
+ }
320
+ </script>
321
+
322
+ <template>
323
+ <div>
324
+ <ml-toolbar :items="data" layout="vertical" @click="handleCommand"/>
325
+ </div>
326
+ </template>
327
+
328
+ <style></style>
329
+ ```