@voicenter-team/voicenter-ui-plus 3.2.0 → 3.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 (37) hide show
  1. package/README.md +502 -459
  2. package/library/assets/components/VcCheckbox/VcCheckboxButton.css +1 -0
  3. package/library/components/VcCheckbox/VcCheckbox.vue.mjs +1 -1
  4. package/library/components/VcCheckbox/VcCheckboxButton.vue.mjs +101 -0
  5. package/library/components/VcCheckbox/VcCheckboxButton.vue3.mjs +5 -0
  6. package/library/components/VcCheckbox/VcCheckboxButtonGroup.vue.mjs +89 -0
  7. package/library/components/VcCheckbox/VcCheckboxButtonGroup.vue2.mjs +4 -0
  8. package/library/components/VcDatePicker/VcDatePicker.vue.mjs +1 -1
  9. package/library/components/VcDropdown/VcDropdownItem.vue.mjs +1 -1
  10. package/library/components/VcForm/VcForm.vue.mjs +1 -1
  11. package/library/components/VcForm/VcFormItem.vue.mjs +1 -1
  12. package/library/components/VcHtmlEditor/VcHtmlEditorToolbar.vue.mjs +1 -1
  13. package/library/components/VcInput/VcInput.vue.mjs +1 -1
  14. package/library/components/VcMdEditor/VcMdEditor.vue.mjs +1 -1
  15. package/library/components/VcMdEditor/VcMdEditorToolbar.vue.mjs +1 -1
  16. package/library/components/VcRadio/VcRadio.vue.mjs +1 -1
  17. package/library/components/VcSelect/VcSelect.vue.mjs +1 -1
  18. package/library/components/VcSlider/VcSlider.vue.mjs +1 -1
  19. package/library/index.mjs +289 -284
  20. package/library/index.mjs.br +0 -0
  21. package/library/index.mjs.gz +0 -0
  22. package/library/plugin-components.gen.mjs +294 -0
  23. package/library/plugin.mjs +291 -377
  24. package/library/plugin.mjs.br +0 -0
  25. package/library/plugin.mjs.gz +0 -0
  26. package/library/style.css +2 -0
  27. package/library/style.css.br +0 -0
  28. package/library/style.css.gz +0 -0
  29. package/library/types/components/VcCheckbox/VcCheckboxButton.vue.d.ts +86 -0
  30. package/library/types/components/VcCheckbox/VcCheckboxButtonGroup.vue.d.ts +86 -0
  31. package/library/types/components/exports.d.ts +48 -2
  32. package/library/types/components.gen.d.ts +105 -0
  33. package/library/types/index.d.ts +1 -103
  34. package/library/types/plugin-components.gen.d.ts +2 -0
  35. package/library/utils/jsonSchema/helpers.mjs +1 -1
  36. package/package.json +10 -2
  37. /package/library/assets/node_modules/element-plus/theme-chalk/src/{dropdown-item.css → tooltip.css} +0 -0
package/README.md CHANGED
@@ -1,459 +1,502 @@
1
- # Voicenter UI library for Vue
2
- This is Vue 3.x + Typescript component library made for Voicenter systems.
3
-
4
- > **v3.0.0 is a tree-shaking release with breaking changes.** See [`MIGRATION_v3.md`](./MIGRATION_v3.md). The separate `*-extended` package is gone — every component lives in this package now.
5
-
6
- ## Installation
7
-
8
- ```bash
9
- npm i @voicenter-team/voicenter-ui-plus
10
- npm i vue@^3.5 element-plus @vueuse/core dayjs lodash-es libphonenumber-js maska
11
- ```
12
-
13
- ### Sass compiler (build-time)
14
-
15
- This library customizes element-plus theming via SCSS variable injection at build time. Your bundler needs to be able to compile SCSS. If your project doesn't already use Sass, add it as a dev dependency:
16
-
17
- ```bash
18
- npm i -D sass-embedded
19
- ```
20
-
21
- This is a **build-time only** requirement — it doesn't add anything to your runtime bundle. Most Vue 3 / Vite projects already have it.
22
-
23
- Optional peer deps — install only for the heavy components you use:
24
-
25
- | Component | Peer deps |
26
- |---|---|
27
- | `VcPdfDocument` | `pdfjs-dist@^2.9.359` |
28
- | `VcSoundPlayer` | `wavesurfer.js` |
29
- | `VcExcelFileUploader` | `xlsx` |
30
- | `VcImageUploader` | `vue-advanced-cropper` |
31
- | `VcHtmlEditor` / `VcJsonSchema` | `codemirror @codemirror/lang-html @codemirror/lang-json @codemirror/lang-markdown vue-codemirror6` |
32
- | `VcMdEditor` | `@milkdown/crepe @milkdown/kit @milkdown/vue @prosemirror-adapter/vue` |
33
-
34
- ### If you're on Vite 8 / rolldown (and skipping some optional peers)
35
-
36
- Vite 8's rolldown-based bundler validates named imports against optional-peer-dep stubs and fails the build with `MISSING_EXPORT` errors when a heavy component's peer is uninstalled — even when you don't use that component. Add the unused optional peers to `build.rollupOptions.external` in your `vite.config.ts`:
37
-
38
- ```ts
39
- // vite.config.ts
40
- import { defineConfig } from 'vite'
41
- import vue from '@vitejs/plugin-vue'
42
-
43
- export default defineConfig({
44
- plugins: [ vue() ],
45
- build: {
46
- rollupOptions: {
47
- external: [
48
- // List only the heavy peers you DON'T install
49
- /^@milkdown\//, /^@prosemirror/, /^@codemirror\//, /^codemirror/,
50
- /^vue-codemirror6/, /^vue-advanced-cropper/,
51
- 'wavesurfer.js', 'xlsx', 'pdfjs-dist', /^pdfjs-dist\//
52
- ]
53
- }
54
- }
55
- })
56
- ```
57
-
58
- Earlier Vite versions (5, 6, 7 with rollup) and webpack 5+ don't require this — the older rollup variant warns but doesn't error on optional-peer named imports.
59
-
60
- ## Usage
61
-
62
- ### Tree-shake mode (recommended)
63
- ```ts
64
- import { VcButton, VcInput } from '@voicenter-team/voicenter-ui-plus'
65
- // Use as local components — no app.use() needed.
66
- ```
67
- Bundlers drop unused components and their CSS. A consumer importing only `VcButton` ships ~50–150 KB JS + ~10–30 KB CSS.
68
-
69
- If you use `useConfirmModal`, `useConfirmPopup`, or `NotifyService`, mount global overlays in `App.vue`:
70
-
71
- ```vue
72
- <script setup lang="ts">
73
- import { VcPluginOverlays } from '@voicenter-team/voicenter-ui-plus'
74
- </script>
75
-
76
- <template>
77
- <RouterView />
78
- <VcPluginOverlays />
79
- </template>
80
- ```
81
-
82
- ### Plugin mode (global registration)
83
- ```ts
84
- import VoicenterUI from '@voicenter-team/voicenter-ui-plus/plugin'
85
- import '@voicenter-team/voicenter-ui-plus/style.css'
86
-
87
- // Overlay composables can be imported from the same entry:
88
- // import { useConfirmModal, useConfirmPopup, VcPluginOverlays } from '@voicenter-team/voicenter-ui-plus/plugin'
89
-
90
- app.use(VoicenterUI, {
91
- themeConfig, // theme config (see below)
92
- lang: 'en', // localization
93
- injectIconFont: true // inject icon-font <link> tags into <head>
94
- })
95
- // Confirm modals/popovers/notifications: auto-mounted via VcPluginOverlays
96
- // (mountOverlays: true by default). Opt out with mountOverlays: false and
97
- // add <VcPluginOverlays /> to App.vue — also registered globally by the plugin.
98
- ```
99
-
100
- ### Global overlays
101
-
102
- Several APIs are **state-only** — they update global reactive singletons but do not render UI by themselves:
103
-
104
- | API | Overlay component |
105
- |---|---|
106
- | `useConfirmModal` | `VcConfirmModal` |
107
- | `useConfirmPopup` | `VcConfirmPopover` |
108
- | `NotifyService` / `$notify` | `VcNotification` |
109
-
110
- **Plugin mode:** mounted automatically on `app.use()` (default). Pass `mountOverlays: false` to mount manually.
111
-
112
- **Notifications:** one top-right host by default. For multiple positions, use `overlayNotifications` in plugin config or mount your own:
113
-
114
- ```ts
115
- app.use(VoicenterUI, {
116
- overlayNotifications: [
117
- { group: 'top-right', position: 'top-right' },
118
- { group: 'bottom-right', position: 'bottom-right' },
119
- ],
120
- })
121
- // NotifyService.add({ group: 'bottom-right', ... })
122
- ```
123
-
124
- Or `overlayNotifications: 'none'` and put `<VcNotification />` in App.vue (confirms still auto-mount).
125
-
126
- **Tree-shake mode:** add `<VcPluginOverlays />` to `App.vue` (bundles confirm hosts; configure via `notifications` prop).
127
-
128
- Entity components such as `VcEntityListTable` call `useConfirmModal` internally — delete confirmations require overlays to be mounted.
129
-
130
- 2.1. If you are using tailwind update your `tailwind.config.js` with:
131
- ```js
132
- const voiceTailwindScheme = require('@voicenter-team/voicenter-ui-plus/src/theme/tailwindScheme')
133
-
134
- module.exports = {
135
- ...yourConfiguration,
136
- theme: {
137
- colors: {
138
- ...voiceTailwindScheme
139
- },
140
- borderColor: {
141
- ...voiceTailwindScheme
142
- }
143
- }
144
- }
145
- ```
146
-
147
- ### Theming specification
148
- The `themeConfig` which is passed as options to the VoicenterUI `vue.use` data could have the following specifications:
149
-
150
- ### Local
151
- **Config:**
152
- ```js
153
- {
154
- type: 'local'
155
- themeName: 'red' | 'blue' | '...'
156
- onSetupCallback: () => {
157
- console.log('Loaded!')
158
- }
159
- }
160
- ```
161
- **Description:**
162
-
163
- Such configuration will append to the document element the CSS variables from one of the configuration passed in `themeName` parameter which it will get from theme specification delivered alongside with library
164
-
165
- **Params:**
166
- - **themeName**
167
- - The name of the theme to be injected
168
- - **onSetupCallback**
169
- - The function which will be called right after the variables will be injected into the document element. First parameter of which is the theme object which was set up
170
-
171
- ### Remote
172
- **Config:**
173
- ```js
174
- {
175
- type: 'remote'
176
- brandingSectionName: 'someName'
177
- apiUrl: 'someUrl'
178
- brandingSectionName: {
179
- property: 'data'
180
- }
181
- onSetupCallback: () => {
182
- console.log('Loaded!')
183
- }
184
- }
185
- ```
186
- **Description:**
187
-
188
- Such configuration will initiate the call to the specified apiUrl in order to retrieve the JSON object with key-value properties of the CSS variables to inject to document element
189
-
190
- **Params:**
191
- - **brandingSectionName**
192
- - [Optional] The name of the section (tagSection) in the database configuration which will be passed to the API in payload and on response retrieved replaced from resulted values
193
- - **apiUrl**
194
- - The API url to which the POST request will be initiated
195
- - **onSetupCallback**
196
- - The function which will be called right after the variables will be injected into the document element. First parameter of which is the theme object which was set up
197
- - **brandingSectionName**
198
- - [Optional] The payload data that will be sent to the request
199
-
200
- ### Custom JSON
201
- **Config:**
202
- ```js
203
- {
204
- type: 'customJson'
205
- config: {
206
- black: '#000000'
207
- }
208
- onSetupCallback: () => {
209
- console.log('Loaded!')
210
- }
211
- }
212
- ```
213
- **Description:**
214
-
215
- Such configuration will initiate the styling with custom provided theme
216
-
217
- **Params:**
218
- - **config**
219
- - The object where the key is the variable to be set and the value is the variable value. Check the [themes object](https://github.com/VoicenterTeam/voicenter-ui-plus/blob/master/src/theme/themes.json) to check existing variables
220
- - **onSetupCallback**
221
- - The function which will be called right after the variables will be injected into the document element. First parameter of which is the theme object which was set up
222
-
223
- ## Date Handling
224
-
225
- This library uses **dayjs** for all date operations and formatting. When working with date-related components, use dayjs format tokens (NOT date-fns format tokens).
226
-
227
- ### Format Tokens
228
-
229
- **Important**: Use dayjs format tokens:
230
- - `DD` - Day of month (2 digits) - **NOT** `dd`
231
- - `YYYY` - 4-digit year - **NOT** `yyyy`
232
- - `MM` - Month (2 digits)
233
- - `HH` - 24-hour format
234
- - `mm` - Minutes
235
- - `ss` - Seconds
236
-
237
- ### Common Formats
238
-
239
- ```typescript
240
- 'DD/MM/YYYY' // 31/12/2024
241
- 'DD-MM-YYYY' // 31-12-2024
242
- 'YYYY-MM-DD' // 2024-12-31
243
- 'DD/MM/YYYY, HH:mm' // 31/12/2024, 14:30
244
- 'DD/MM/YYYY HH:mm:ss' // 31/12/2024 14:30:45
245
- ```
246
-
247
- ### Usage Example
248
-
249
- ```vue
250
- <VcDatePicker
251
- v-model="date"
252
- format="DD/MM/YYYY"
253
- input-date-format="DD/MM/YYYY"
254
- input-time-format="HH:mm"
255
- />
256
- ```
257
-
258
- ## Date Utility Functions
259
-
260
- The library provides a comprehensive set of date utility functions built on dayjs. These utilities are available for use in external projects.
261
-
262
- ### Import Date Utilities
263
-
264
- ```typescript
265
- import {
266
- formatDate,
267
- parseDate,
268
- addDays,
269
- subtractDays,
270
- getHours,
271
- getMinutes,
272
- getSeconds,
273
- setTime,
274
- isAfter,
275
- isSameAfter,
276
- isBefore,
277
- isSameBefore,
278
- format,
279
- add,
280
- sub,
281
- addFp,
282
- subFp
283
- } from '@voicenter-team/voicenter-ui-plus'
284
- ```
285
-
286
- ### Basic Date Operations
287
-
288
- #### Formatting Dates
289
-
290
- ```typescript
291
- // Format a date with default format (YYYY-MM-DD)
292
- const formatted = formatDate(new Date())
293
- // Result: "2024-12-31"
294
-
295
- // Format with custom format
296
- const custom = formatDate(new Date(), 'DD/MM/YYYY')
297
- // Result: "31/12/2024"
298
-
299
- // Using format function (alias)
300
- const formatted2 = format(new Date(), 'DD/MM/YYYY HH:mm')
301
- // Result: "31/12/2024 14:30"
302
- ```
303
-
304
- #### Parsing Dates
305
-
306
- ```typescript
307
- // Parse a date string with format
308
- const date = parseDate('31/12/2024', 'DD/MM/YYYY')
309
- // Returns: Date object
310
- ```
311
-
312
- ### Date Arithmetic
313
-
314
- #### Adding/Subtracting Days
315
-
316
- ```typescript
317
- // Add days
318
- const futureDate = addDays(new Date(), 7)
319
- // Returns: Date 7 days from now
320
-
321
- // Subtract days
322
- const pastDate = subtractDays(new Date(), 5)
323
- // Returns: Date 5 days ago
324
- ```
325
-
326
- #### Adding/Subtracting Time Units
327
-
328
- ```typescript
329
- // Add multiple time units
330
- const newDate = add(new Date(), {
331
- years: 1,
332
- months: 2,
333
- days: 5,
334
- hours: 3,
335
- minutes: 30
336
- })
337
-
338
- // Subtract multiple time units
339
- const earlierDate = sub(new Date(), {
340
- weeks: 2,
341
- days: 3,
342
- hours: 12
343
- })
344
-
345
- // Functional programming style (reversed arguments)
346
- const fpDate = addFp({ days: 7 }, new Date())
347
- const fpDate2 = subFp({ hours: 5 }, new Date())
348
- ```
349
-
350
- ### Time Operations
351
-
352
- #### Getting Time Components
353
-
354
- ```typescript
355
- const date = new Date('2024-12-31T14:30:45')
356
-
357
- const hours = getHours(date) // 14
358
- const minutes = getMinutes(date) // 30
359
- const seconds = getSeconds(date) // 45
360
- ```
361
-
362
- #### Setting Time
363
-
364
- ```typescript
365
- // Set time on a date (returns new Date object)
366
- const newDate = setTime(new Date(), {
367
- hours: 14,
368
- minutes: 30,
369
- seconds: 0
370
- })
371
- ```
372
-
373
- ### Date Comparisons
374
-
375
- ```typescript
376
- const date1 = new Date('2024-12-31')
377
- const date2 = new Date('2025-01-01')
378
-
379
- // Check if date1 is after date2
380
- const isLater = isAfter(date1, date2, 'day')
381
- // Returns: false
382
-
383
- // Check if date1 is same or after date2
384
- const isSameOrLater = isSameAfter(date1, date2, 'day')
385
- // Returns: false
386
-
387
- // Check if date1 is before date2
388
- const isEarlier = isBefore(date1, date2, 'day')
389
- // Returns: true
390
-
391
- // Check if date1 is same or before date2
392
- const isSameOrEarlier = isSameBefore(date1, date2, 'day')
393
- // Returns: true
394
- ```
395
-
396
- **Comparison Units**: The comparison functions accept a `units` parameter (default: `'minute'`). Valid units:
397
- - `'year'`, `'month'`, `'week'`, `'day'`
398
- - `'hour'`, `'minute'`, `'second'`
399
-
400
- ### Complete Usage Example
401
-
402
- ```typescript
403
- import {
404
- formatDate,
405
- addDays,
406
- isAfter,
407
- format,
408
- add,
409
- getHours,
410
- setTime
411
- } from '@voicenter-team/voicenter-ui-plus'
412
-
413
- // Format today's date
414
- const today = formatDate(new Date(), 'DD/MM/YYYY')
415
-
416
- // Get date 30 days from now
417
- const futureDate = addDays(new Date(), 30)
418
-
419
- // Check if a date is in the future
420
- const isFuture = isAfter(futureDate, new Date(), 'day')
421
-
422
- // Add 2 weeks and 3 days
423
- const deadline = add(new Date(), {
424
- weeks: 2,
425
- days: 3
426
- })
427
-
428
- // Get current hour
429
- const currentHour = getHours(new Date())
430
-
431
- // Set specific time
432
- const meetingTime = setTime(new Date(), {
433
- hours: 14,
434
- minutes: 30
435
- })
436
-
437
- // Format the result
438
- const formattedDeadline = format(deadline, 'DD/MM/YYYY HH:mm')
439
- ```
440
-
441
- ### Notes
442
-
443
- - All functions accept `Date`, `string`, or `number` as date input
444
- - All date manipulation functions return new `Date` objects (immutable)
445
- - Format strings use dayjs format tokens (see Format Tokens section above)
446
- - These utilities are built on dayjs and maintain compatibility with dayjs format patterns
447
-
448
- ## Documentation
449
-
450
- ### Live Documentation
451
- Visit [documentation](https://voicenter-ui.netlify.app/) for interactive component examples and demos.
452
-
453
- ## Project Documentation
454
- For detailed technical documentation, see the [`docs/`](./docs/) directory:
455
-
456
- - **[Quick Start Guide](./docs/AGENTS_QUICK_START.md)** - For developers working on the library
457
- - **[Integration Guide](./docs/AGENTS_INTEGRATION_GUIDE.md)** - For using the library in other projects
458
- - **[Architecture Overview](./docs/ARCHITECTURE.md)** - Project structure and technical details
459
- - **[Documentation Guide](./docs/DOCUMENTATION_GUIDE.md)** - Working with the documentation system
1
+ # Voicenter UI library for Vue
2
+ This is Vue 3.x + Typescript component library made for Voicenter systems.
3
+
4
+ > **v3.0.0 is a tree-shaking release with breaking changes.** See [`MIGRATION_v3.md`](./MIGRATION_v3.md). The separate `*-extended` package is gone — every component lives in this package now.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ npm i @voicenter-team/voicenter-ui-plus
10
+ npm i vue@^3.5 element-plus @vueuse/core dayjs lodash-es libphonenumber-js maska
11
+ ```
12
+
13
+ ### Sass compiler (build-time)
14
+
15
+ This library customizes element-plus theming via SCSS variable injection at build time. Your bundler needs to be able to compile SCSS. If your project doesn't already use Sass, add it as a dev dependency:
16
+
17
+ ```bash
18
+ npm i -D sass-embedded
19
+ ```
20
+
21
+ This is a **build-time only** requirement — it doesn't add anything to your runtime bundle. Most Vue 3 / Vite projects already have it.
22
+
23
+ Optional peer deps — install only for the heavy components you use:
24
+
25
+ | Component | Peer deps |
26
+ |---|---|
27
+ | `VcPdfDocument` | `pdfjs-dist@^2.9.359` |
28
+ | `VcSoundPlayer` | `wavesurfer.js` |
29
+ | `VcExcelFileUploader` | `xlsx` |
30
+ | `VcImageUploader` | `vue-advanced-cropper` |
31
+ | `VcHtmlEditor` / `VcJsonSchema` | `codemirror @codemirror/lang-html @codemirror/lang-json @codemirror/lang-markdown vue-codemirror6` |
32
+ | `VcMdEditor` | `@milkdown/crepe @milkdown/kit @milkdown/vue @prosemirror-adapter/vue` |
33
+
34
+ ### If you're on Vite 8 / rolldown (and skipping some optional peers)
35
+
36
+ Vite 8's rolldown-based bundler validates named imports against optional-peer-dep stubs and fails the build with `MISSING_EXPORT` errors when a heavy component's peer is uninstalled — even when you don't use that component. Add the unused optional peers to `build.rollupOptions.external` in your `vite.config.ts`:
37
+
38
+ ```ts
39
+ // vite.config.ts
40
+ import { defineConfig } from 'vite'
41
+ import vue from '@vitejs/plugin-vue'
42
+
43
+ export default defineConfig({
44
+ plugins: [ vue() ],
45
+ build: {
46
+ rollupOptions: {
47
+ external: [
48
+ // List only the heavy peers you DON'T install
49
+ /^@milkdown\//, /^@prosemirror/, /^@codemirror\//, /^codemirror/,
50
+ /^vue-codemirror6/, /^vue-advanced-cropper/,
51
+ 'wavesurfer.js', 'xlsx', 'pdfjs-dist', /^pdfjs-dist\//
52
+ ]
53
+ }
54
+ }
55
+ })
56
+ ```
57
+
58
+ Earlier Vite versions (5, 6, 7 with rollup) and webpack 5+ don't require this — the older rollup variant warns but doesn't error on optional-peer named imports.
59
+
60
+ ## Usage
61
+
62
+ ### Tree-shake mode (recommended)
63
+ ```ts
64
+ import { VcButton, VcInput } from '@voicenter-team/voicenter-ui-plus'
65
+ // Use as local components — no app.use() needed.
66
+ ```
67
+ Bundlers drop unused components and their CSS. A consumer importing only `VcButton` ships ~50–150 KB JS + ~10–30 KB CSS.
68
+
69
+ If you use `useConfirmModal`, `useConfirmPopup`, or `NotifyService`, mount global overlays in `App.vue`:
70
+
71
+ ```vue
72
+ <script setup lang="ts">
73
+ import { VcPluginOverlays } from '@voicenter-team/voicenter-ui-plus'
74
+ </script>
75
+
76
+ <template>
77
+ <RouterView />
78
+ <VcPluginOverlays />
79
+ </template>
80
+ ```
81
+
82
+ ### Plugin mode (global registration)
83
+ ```ts
84
+ import VoicenterUI from '@voicenter-team/voicenter-ui-plus/plugin'
85
+ import '@voicenter-team/voicenter-ui-plus/style.css'
86
+
87
+ // Overlay composables can be imported from the same entry:
88
+ // import { useConfirmModal, useConfirmPopup, VcPluginOverlays } from '@voicenter-team/voicenter-ui-plus/plugin'
89
+
90
+ app.use(VoicenterUI, {
91
+ themeConfig, // theme config (see below)
92
+ lang: 'en', // localization
93
+ injectIconFont: true // inject icon-font <link> tags into <head>
94
+ })
95
+ // Confirm modals/popovers/notifications: auto-mounted via VcPluginOverlays
96
+ // (mountOverlays: true by default). Opt out with mountOverlays: false and
97
+ // add <VcPluginOverlays /> to App.vue — also registered globally by the plugin.
98
+ ```
99
+
100
+ ### Global overlays
101
+
102
+ Several APIs are **state-only** — they update global reactive singletons but do not render UI by themselves:
103
+
104
+ | API | Overlay component |
105
+ |---|---|
106
+ | `useConfirmModal` | `VcConfirmModal` |
107
+ | `useConfirmPopup` | `VcConfirmPopover` |
108
+ | `NotifyService` / `$notify` | `VcNotification` |
109
+
110
+ **Plugin mode:** mounted automatically on `app.use()` (default). Pass `mountOverlays: false` to mount manually.
111
+
112
+ **Notifications:** one top-right host by default. For multiple positions, use `overlayNotifications` in plugin config or mount your own:
113
+
114
+ ```ts
115
+ app.use(VoicenterUI, {
116
+ overlayNotifications: [
117
+ { group: 'top-right', position: 'top-right' },
118
+ { group: 'bottom-right', position: 'bottom-right' },
119
+ ],
120
+ })
121
+ // NotifyService.add({ group: 'bottom-right', ... })
122
+ ```
123
+
124
+ Or `overlayNotifications: 'none'` and put `<VcNotification />` in App.vue (confirms still auto-mount).
125
+
126
+ **Tree-shake mode:** add `<VcPluginOverlays />` to `App.vue` (bundles confirm hosts; configure via `notifications` prop).
127
+
128
+ Entity components such as `VcEntityListTable` call `useConfirmModal` internally — delete confirmations require overlays to be mounted.
129
+
130
+ 2.1. If you are using tailwind update your `tailwind.config.js` with:
131
+ ```js
132
+ const voiceTailwindScheme = require('@voicenter-team/voicenter-ui-plus/src/theme/tailwindScheme')
133
+
134
+ module.exports = {
135
+ ...yourConfiguration,
136
+ theme: {
137
+ colors: {
138
+ ...voiceTailwindScheme
139
+ },
140
+ borderColor: {
141
+ ...voiceTailwindScheme
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### Theming specification
148
+ The `themeConfig` which is passed as options to the VoicenterUI `vue.use` data could have the following specifications:
149
+
150
+ ### Local
151
+ **Config:**
152
+ ```js
153
+ {
154
+ type: 'local'
155
+ themeName: 'red' | 'blue' | '...'
156
+ onSetupCallback: () => {
157
+ console.log('Loaded!')
158
+ }
159
+ }
160
+ ```
161
+ **Description:**
162
+
163
+ Such configuration will append to the document element the CSS variables from one of the configuration passed in `themeName` parameter which it will get from theme specification delivered alongside with library
164
+
165
+ **Params:**
166
+ - **themeName**
167
+ - The name of the theme to be injected
168
+ - **onSetupCallback**
169
+ - The function which will be called right after the variables will be injected into the document element. First parameter of which is the theme object which was set up
170
+
171
+ ### Remote
172
+ **Config:**
173
+ ```js
174
+ {
175
+ type: 'remote'
176
+ brandingSectionName: 'someName'
177
+ apiUrl: 'someUrl'
178
+ brandingSectionName: {
179
+ property: 'data'
180
+ }
181
+ onSetupCallback: () => {
182
+ console.log('Loaded!')
183
+ }
184
+ }
185
+ ```
186
+ **Description:**
187
+
188
+ Such configuration will initiate the call to the specified apiUrl in order to retrieve the JSON object with key-value properties of the CSS variables to inject to document element
189
+
190
+ **Params:**
191
+ - **brandingSectionName**
192
+ - [Optional] The name of the section (tagSection) in the database configuration which will be passed to the API in payload and on response retrieved replaced from resulted values
193
+ - **apiUrl**
194
+ - The API url to which the POST request will be initiated
195
+ - **onSetupCallback**
196
+ - The function which will be called right after the variables will be injected into the document element. First parameter of which is the theme object which was set up
197
+ - **brandingSectionName**
198
+ - [Optional] The payload data that will be sent to the request
199
+
200
+ ### Custom JSON
201
+ **Config:**
202
+ ```js
203
+ {
204
+ type: 'customJson'
205
+ config: {
206
+ black: '#000000'
207
+ }
208
+ onSetupCallback: () => {
209
+ console.log('Loaded!')
210
+ }
211
+ }
212
+ ```
213
+ **Description:**
214
+
215
+ Such configuration will initiate the styling with custom provided theme
216
+
217
+ **Params:**
218
+ - **config**
219
+ - The object where the key is the variable to be set and the value is the variable value. Check the [themes object](https://github.com/VoicenterTeam/voicenter-ui-plus/blob/master/src/theme/themes.json) to check existing variables
220
+ - **onSetupCallback**
221
+ - The function which will be called right after the variables will be injected into the document element. First parameter of which is the theme object which was set up
222
+
223
+ ## Date Handling
224
+
225
+ This library uses **dayjs** for all date operations and formatting. When working with date-related components, use dayjs format tokens (NOT date-fns format tokens).
226
+
227
+ ### Format Tokens
228
+
229
+ **Important**: Use dayjs format tokens:
230
+ - `DD` - Day of month (2 digits) - **NOT** `dd`
231
+ - `YYYY` - 4-digit year - **NOT** `yyyy`
232
+ - `MM` - Month (2 digits)
233
+ - `HH` - 24-hour format
234
+ - `mm` - Minutes
235
+ - `ss` - Seconds
236
+
237
+ ### Common Formats
238
+
239
+ ```typescript
240
+ 'DD/MM/YYYY' // 31/12/2024
241
+ 'DD-MM-YYYY' // 31-12-2024
242
+ 'YYYY-MM-DD' // 2024-12-31
243
+ 'DD/MM/YYYY, HH:mm' // 31/12/2024, 14:30
244
+ 'DD/MM/YYYY HH:mm:ss' // 31/12/2024 14:30:45
245
+ ```
246
+
247
+ ### Usage Example
248
+
249
+ ```vue
250
+ <VcDatePicker
251
+ v-model="date"
252
+ format="DD/MM/YYYY"
253
+ input-date-format="DD/MM/YYYY"
254
+ input-time-format="HH:mm"
255
+ />
256
+ ```
257
+
258
+ ## Date Utility Functions
259
+
260
+ The library provides a comprehensive set of date utility functions built on dayjs. These utilities are available for use in external projects.
261
+
262
+ ### Import Date Utilities
263
+
264
+ ```typescript
265
+ import {
266
+ formatDate,
267
+ parseDate,
268
+ addDays,
269
+ subtractDays,
270
+ getHours,
271
+ getMinutes,
272
+ getSeconds,
273
+ setTime,
274
+ isAfter,
275
+ isSameAfter,
276
+ isBefore,
277
+ isSameBefore,
278
+ format,
279
+ add,
280
+ sub,
281
+ addFp,
282
+ subFp
283
+ } from '@voicenter-team/voicenter-ui-plus'
284
+ ```
285
+
286
+ ### Basic Date Operations
287
+
288
+ #### Formatting Dates
289
+
290
+ ```typescript
291
+ // Format a date with default format (YYYY-MM-DD)
292
+ const formatted = formatDate(new Date())
293
+ // Result: "2024-12-31"
294
+
295
+ // Format with custom format
296
+ const custom = formatDate(new Date(), 'DD/MM/YYYY')
297
+ // Result: "31/12/2024"
298
+
299
+ // Using format function (alias)
300
+ const formatted2 = format(new Date(), 'DD/MM/YYYY HH:mm')
301
+ // Result: "31/12/2024 14:30"
302
+ ```
303
+
304
+ #### Parsing Dates
305
+
306
+ ```typescript
307
+ // Parse a date string with format
308
+ const date = parseDate('31/12/2024', 'DD/MM/YYYY')
309
+ // Returns: Date object
310
+ ```
311
+
312
+ ### Date Arithmetic
313
+
314
+ #### Adding/Subtracting Days
315
+
316
+ ```typescript
317
+ // Add days
318
+ const futureDate = addDays(new Date(), 7)
319
+ // Returns: Date 7 days from now
320
+
321
+ // Subtract days
322
+ const pastDate = subtractDays(new Date(), 5)
323
+ // Returns: Date 5 days ago
324
+ ```
325
+
326
+ #### Adding/Subtracting Time Units
327
+
328
+ ```typescript
329
+ // Add multiple time units
330
+ const newDate = add(new Date(), {
331
+ years: 1,
332
+ months: 2,
333
+ days: 5,
334
+ hours: 3,
335
+ minutes: 30
336
+ })
337
+
338
+ // Subtract multiple time units
339
+ const earlierDate = sub(new Date(), {
340
+ weeks: 2,
341
+ days: 3,
342
+ hours: 12
343
+ })
344
+
345
+ // Functional programming style (reversed arguments)
346
+ const fpDate = addFp({ days: 7 }, new Date())
347
+ const fpDate2 = subFp({ hours: 5 }, new Date())
348
+ ```
349
+
350
+ ### Time Operations
351
+
352
+ #### Getting Time Components
353
+
354
+ ```typescript
355
+ const date = new Date('2024-12-31T14:30:45')
356
+
357
+ const hours = getHours(date) // 14
358
+ const minutes = getMinutes(date) // 30
359
+ const seconds = getSeconds(date) // 45
360
+ ```
361
+
362
+ #### Setting Time
363
+
364
+ ```typescript
365
+ // Set time on a date (returns new Date object)
366
+ const newDate = setTime(new Date(), {
367
+ hours: 14,
368
+ minutes: 30,
369
+ seconds: 0
370
+ })
371
+ ```
372
+
373
+ ### Date Comparisons
374
+
375
+ ```typescript
376
+ const date1 = new Date('2024-12-31')
377
+ const date2 = new Date('2025-01-01')
378
+
379
+ // Check if date1 is after date2
380
+ const isLater = isAfter(date1, date2, 'day')
381
+ // Returns: false
382
+
383
+ // Check if date1 is same or after date2
384
+ const isSameOrLater = isSameAfter(date1, date2, 'day')
385
+ // Returns: false
386
+
387
+ // Check if date1 is before date2
388
+ const isEarlier = isBefore(date1, date2, 'day')
389
+ // Returns: true
390
+
391
+ // Check if date1 is same or before date2
392
+ const isSameOrEarlier = isSameBefore(date1, date2, 'day')
393
+ // Returns: true
394
+ ```
395
+
396
+ **Comparison Units**: The comparison functions accept a `units` parameter (default: `'minute'`). Valid units:
397
+ - `'year'`, `'month'`, `'week'`, `'day'`
398
+ - `'hour'`, `'minute'`, `'second'`
399
+
400
+ ### Complete Usage Example
401
+
402
+ ```typescript
403
+ import {
404
+ formatDate,
405
+ addDays,
406
+ isAfter,
407
+ format,
408
+ add,
409
+ getHours,
410
+ setTime
411
+ } from '@voicenter-team/voicenter-ui-plus'
412
+
413
+ // Format today's date
414
+ const today = formatDate(new Date(), 'DD/MM/YYYY')
415
+
416
+ // Get date 30 days from now
417
+ const futureDate = addDays(new Date(), 30)
418
+
419
+ // Check if a date is in the future
420
+ const isFuture = isAfter(futureDate, new Date(), 'day')
421
+
422
+ // Add 2 weeks and 3 days
423
+ const deadline = add(new Date(), {
424
+ weeks: 2,
425
+ days: 3
426
+ })
427
+
428
+ // Get current hour
429
+ const currentHour = getHours(new Date())
430
+
431
+ // Set specific time
432
+ const meetingTime = setTime(new Date(), {
433
+ hours: 14,
434
+ minutes: 30
435
+ })
436
+
437
+ // Format the result
438
+ const formattedDeadline = format(deadline, 'DD/MM/YYYY HH:mm')
439
+ ```
440
+
441
+ ### Notes
442
+
443
+ - All functions accept `Date`, `string`, or `number` as date input
444
+ - All date manipulation functions return new `Date` objects (immutable)
445
+ - Format strings use dayjs format tokens (see Format Tokens section above)
446
+ - These utilities are built on dayjs and maintain compatibility with dayjs format patterns
447
+
448
+ ## Contributing: adding a new component
449
+
450
+ The public component surface is defined in **one place**: [`script/components-manifest.mjs`](./script/components-manifest.mjs) — one line per component.
451
+
452
+ ```js
453
+ { name: 'VcMyThing', path: 'components/VcMyThing/VcMyThing.vue' },
454
+ ```
455
+
456
+ `npm run generate:entries` materializes the manifest into three fully
457
+ generated files (never edit them by hand — the next generator run
458
+ overwrites them, and the verifier fails the build until they match):
459
+
460
+ - `src/components.gen.ts` — named exports, re-exported by `src/index.ts`
461
+ (tree-shake mode);
462
+ - `src/plugin-components.gen.ts` — `registerComponents(app)`, called by
463
+ the plugin's install (global registration mode);
464
+ - `src/components/exports.ts` — the `GlobalComponents` template typing.
465
+
466
+ `src/index.ts` and `src/plugin.ts` themselves stay hand-written and small.
467
+ The `.gen` modules are safe to route through only because
468
+ `rewriteCssImports()` in `vite.config.ts` strips the CSS imports that
469
+ `vite-plugin-lib-inject-css` aggregates onto them — each component's CSS
470
+ stays in its own chunk, so per-component CSS tree-shaking survives. Don't
471
+ rename the `.gen` files without updating that strip list (the verifier
472
+ guards this wiring too).
473
+
474
+ Typical flows:
475
+
476
+ - **New component**: `node script/create-component.mjs` — scaffolds the
477
+ component folder, adds the manifest line, and regenerates all entries.
478
+ - **Existing .vue file**: add one line to the manifest, then
479
+ `npm run generate:entries`.
480
+
481
+ Every manifest entry is exported from the package root AND registered
482
+ globally in plugin mode — there are no partial modes.
483
+
484
+ `npm run verify:entries` is the safety net: it independently cross-checks
485
+ the manifest, the three generated files and the filesystem (a component
486
+ file that exists but is missing from the manifest fails too). It runs in
487
+ the pre-commit hook (together with `lint-staged` and `ts-check`; hooks are
488
+ installed automatically by `npm install` via husky) and in CI, so an
489
+ inconsistent component surface cannot reach `master`.
490
+
491
+ ## Documentation
492
+
493
+ ### Live Documentation
494
+ Visit [documentation](https://voicenter-ui.netlify.app/) for interactive component examples and demos.
495
+
496
+ ## Project Documentation
497
+ For detailed technical documentation, see the [`docs/`](./docs/) directory:
498
+
499
+ - **[Quick Start Guide](./docs/AGENTS_QUICK_START.md)** - For developers working on the library
500
+ - **[Integration Guide](./docs/AGENTS_INTEGRATION_GUIDE.md)** - For using the library in other projects
501
+ - **[Architecture Overview](./docs/ARCHITECTURE.md)** - Project structure and technical details
502
+ - **[Documentation Guide](./docs/DOCUMENTATION_GUIDE.md)** - Working with the documentation system