@volverjs/ui-vue 0.0.9-beta.1 → 0.0.9-beta.10

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 (134) hide show
  1. package/README.md +3 -3
  2. package/auto-imports.d.ts +2 -0
  3. package/dist/components/VvAccordion/VvAccordion.es.js +7 -0
  4. package/dist/components/VvAccordionGroup/VvAccordionGroup.es.js +7 -0
  5. package/dist/components/VvAction/VvAction.es.js +9 -1
  6. package/dist/components/VvAction/VvAction.umd.js +1 -1
  7. package/dist/components/VvAction/VvAction.vue.d.ts +9 -0
  8. package/dist/components/VvAction/index.d.ts +4 -0
  9. package/dist/components/VvAlert/VvAlert.es.js +14 -6
  10. package/dist/components/VvAlert/VvAlert.umd.js +1 -1
  11. package/dist/components/VvAlert/VvAlert.vue.d.ts +6 -6
  12. package/dist/components/VvAlert/index.d.ts +3 -3
  13. package/dist/components/VvAlertGroup/VvAlertGroup.es.js +14 -6
  14. package/dist/components/VvAlertGroup/VvAlertGroup.umd.js +1 -1
  15. package/dist/components/VvAvatar/VvAvatar.es.js +7 -0
  16. package/dist/components/VvAvatarGroup/VvAvatarGroup.es.js +7 -0
  17. package/dist/components/VvBadge/VvBadge.es.js +7 -0
  18. package/dist/components/VvBreadcrumb/VvBreadcrumb.es.js +7 -0
  19. package/dist/components/VvButton/VvButton.es.js +11 -2
  20. package/dist/components/VvButton/VvButton.umd.js +1 -1
  21. package/dist/components/VvButton/VvButton.vue.d.ts +9 -0
  22. package/dist/components/VvButton/index.d.ts +4 -0
  23. package/dist/components/VvButtonGroup/VvButtonGroup.es.js +7 -0
  24. package/dist/components/VvCard/VvCard.es.js +7 -0
  25. package/dist/components/VvCheckbox/VvCheckbox.es.js +91 -14
  26. package/dist/components/VvCheckbox/VvCheckbox.umd.js +1 -1
  27. package/dist/components/VvCheckbox/VvCheckbox.vue.d.ts +4 -4
  28. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.es.js +97 -15
  29. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.umd.js +1 -1
  30. package/dist/components/VvCheckboxGroup/VvCheckboxGroup.vue.d.ts +4 -4
  31. package/dist/components/VvCombobox/VvCombobox.es.js +127 -84
  32. package/dist/components/VvCombobox/VvCombobox.umd.js +1 -1
  33. package/dist/components/VvCombobox/VvCombobox.vue.d.ts +35 -14
  34. package/dist/components/VvCombobox/index.d.ts +24 -7
  35. package/dist/components/VvDialog/VvDialog.es.js +34 -26
  36. package/dist/components/VvDialog/VvDialog.umd.js +1 -1
  37. package/dist/components/VvDropdown/VvDropdown.es.js +21 -10
  38. package/dist/components/VvDropdown/VvDropdown.umd.js +1 -1
  39. package/dist/components/VvDropdown/VvDropdown.vue.d.ts +4 -11
  40. package/dist/components/VvDropdown/VvDropdownAction.vue.d.ts +9 -0
  41. package/dist/components/VvDropdown/index.d.ts +1 -7
  42. package/dist/components/VvDropdownAction/VvDropdownAction.es.js +9 -1
  43. package/dist/components/VvDropdownAction/VvDropdownAction.umd.js +1 -1
  44. package/dist/components/VvDropdownOptgroup/VvDropdownOptgroup.es.js +7 -0
  45. package/dist/components/VvDropdownOption/VvDropdownOption.es.js +7 -0
  46. package/dist/components/VvInputText/VvInputText.es.js +87 -14
  47. package/dist/components/VvInputText/VvInputText.umd.js +1 -1
  48. package/dist/components/VvInputText/VvInputText.vue.d.ts +4 -4
  49. package/dist/components/VvNav/VvNav.es.js +10 -2
  50. package/dist/components/VvNav/VvNav.umd.js +1 -1
  51. package/dist/components/VvNav/index.d.ts +1 -1
  52. package/dist/components/VvProgress/VvProgress.es.js +7 -0
  53. package/dist/components/VvRadio/VvRadio.es.js +91 -14
  54. package/dist/components/VvRadio/VvRadio.umd.js +1 -1
  55. package/dist/components/VvRadio/VvRadio.vue.d.ts +4 -4
  56. package/dist/components/VvRadioGroup/VvRadioGroup.es.js +97 -15
  57. package/dist/components/VvRadioGroup/VvRadioGroup.umd.js +1 -1
  58. package/dist/components/VvRadioGroup/VvRadioGroup.vue.d.ts +4 -4
  59. package/dist/components/VvSelect/VvSelect.es.js +87 -14
  60. package/dist/components/VvSelect/VvSelect.umd.js +1 -1
  61. package/dist/components/VvSelect/VvSelect.vue.d.ts +4 -4
  62. package/dist/components/VvTab/VvTab.es.js +10 -2
  63. package/dist/components/VvTab/VvTab.umd.js +1 -1
  64. package/dist/components/VvTextarea/VvTextarea.es.js +87 -14
  65. package/dist/components/VvTextarea/VvTextarea.umd.js +1 -1
  66. package/dist/components/VvTextarea/VvTextarea.vue.d.ts +4 -4
  67. package/dist/components/VvTooltip/VvTooltip.es.js +7 -0
  68. package/dist/components/common/HintSlot.d.ts +4 -3
  69. package/dist/components/index.d.ts +5 -0
  70. package/dist/components/index.es.js +905 -437
  71. package/dist/components/index.umd.js +1 -1
  72. package/dist/composables/alert/useAlert.d.ts +27 -0
  73. package/dist/composables/index.d.ts +1 -0
  74. package/dist/composables/index.es.js +81 -0
  75. package/dist/composables/index.umd.js +1 -0
  76. package/dist/constants.d.ts +10 -0
  77. package/dist/directives/index.es.js +7 -0
  78. package/dist/directives/v-tooltip.es.js +7 -0
  79. package/dist/icons.es.js +3 -3
  80. package/dist/icons.umd.js +1 -1
  81. package/dist/props/index.d.ts +7 -0
  82. package/dist/resolvers/unplugin.es.js +3 -0
  83. package/dist/resolvers/unplugin.umd.js +1 -1
  84. package/dist/stories/AccordionGroup/AccordionGroupSlots.stories.d.ts +43 -258
  85. package/dist/stories/Alert/Alert.settings.d.ts +3 -7
  86. package/dist/stories/AlertGroup/AlertGroupSlots.stories.d.ts +2 -2
  87. package/dist/stories/AlertGroup/AlertGroupWithComposable.stories.d.ts +6 -0
  88. package/dist/stories/Button/Button.settings.d.ts +3 -13
  89. package/dist/stories/Combobox/Combobox.settings.d.ts +117 -19
  90. package/dist/stories/Nav/Nav.settings.d.ts +3 -21
  91. package/package.json +54 -46
  92. package/src/assets/icons/detailed.json +1 -1
  93. package/src/assets/icons/normal.json +1 -1
  94. package/src/assets/icons/simple.json +1 -1
  95. package/src/components/VvAction/VvAction.vue +2 -1
  96. package/src/components/VvAlert/VvAlert.vue +5 -1
  97. package/src/components/VvAlert/index.ts +3 -3
  98. package/src/components/VvAlertGroup/VvAlertGroup.vue +2 -0
  99. package/src/components/VvButton/VvButton.vue +1 -0
  100. package/src/components/VvCheckbox/VvCheckbox.vue +8 -1
  101. package/src/components/VvCheckboxGroup/VvCheckboxGroup.vue +8 -1
  102. package/src/components/VvCombobox/VvCombobox.vue +9 -4
  103. package/src/components/VvCombobox/index.ts +24 -0
  104. package/src/components/VvDialog/VvDialog.vue +16 -17
  105. package/src/components/VvDropdown/VvDropdown.vue +7 -3
  106. package/src/components/VvDropdown/index.ts +2 -8
  107. package/src/components/VvInputText/VvInputText.vue +8 -1
  108. package/src/components/VvNav/VvNav.vue +1 -1
  109. package/src/components/VvNav/index.ts +1 -1
  110. package/src/components/VvRadio/VvRadio.vue +8 -1
  111. package/src/components/VvRadioGroup/VvRadioGroup.vue +8 -1
  112. package/src/components/VvSelect/VvSelect.vue +8 -1
  113. package/src/components/VvTextarea/VvTextarea.vue +8 -1
  114. package/src/components/common/HintSlot.ts +26 -13
  115. package/src/components/index.ts +5 -0
  116. package/src/composables/alert/useAlert.ts +103 -0
  117. package/src/composables/index.ts +1 -0
  118. package/src/constants.ts +21 -0
  119. package/src/props/index.ts +7 -0
  120. package/src/resolvers/unplugin.ts +3 -0
  121. package/src/stories/Alert/Alert.settings.ts +3 -1
  122. package/src/stories/AlertGroup/AlertGroup.test.ts +13 -0
  123. package/src/stories/AlertGroup/AlertGroupSlots.stories.ts +3 -3
  124. package/src/stories/AlertGroup/AlertGroupWithComposable.stories.ts +118 -0
  125. package/src/stories/Button/Button.settings.ts +5 -3
  126. package/src/stories/Combobox/Combobox.settings.ts +119 -2
  127. package/src/stories/Nav/Nav.settings.ts +3 -1
  128. package/src/stories/Tab/Tab.stories.ts +3 -3
  129. package/src/stories/Textarea/TextareaLength.stories.ts +1 -1
  130. package/src/types/alert.d.ts +20 -0
  131. /package/dist/components/{VvNavItemTitle → VvNav}/VvNavItemTitle.vue.d.ts +0 -0
  132. /package/dist/components/{VvNavSeparator → VvNav}/VvNavSeparator.d.ts +0 -0
  133. /package/src/components/{VvNavItemTitle → VvNav}/VvNavItemTitle.vue +0 -0
  134. /package/src/components/{VvNavSeparator → VvNav}/VvNavSeparator.ts +0 -0
@@ -66,7 +66,8 @@
66
66
  const hasProps = computed(() => {
67
67
  const toReturn = {
68
68
  ...dropdownAria?.value,
69
- 'aria-pressed': pressed.value ? true : undefined,
69
+ ariaPressed: pressed.value ? true : undefined,
70
+ ariaLabel: props.ariaLabel,
70
71
  role: role?.value,
71
72
  }
72
73
  switch (hasTag.value) {
@@ -34,7 +34,11 @@
34
34
  <slot name="header">
35
35
  <!-- @slot Before title slot -->
36
36
  <slot name="title::before" />
37
- <strong :id="hasTitleId" class="vv-alert__title">
37
+ <strong
38
+ v-if="$slots.title || title"
39
+ :id="hasTitleId"
40
+ class="vv-alert__title"
41
+ >
38
42
  <!-- @slot Title slot -->
39
43
  <slot name="title">
40
44
  {{ title }}
@@ -40,7 +40,7 @@ export const VvAlertProps = {
40
40
  */
41
41
  title: {
42
42
  type: String,
43
- default: '',
43
+ default: undefined,
44
44
  },
45
45
  /**
46
46
  * The alert content
@@ -49,7 +49,7 @@ export const VvAlertProps = {
49
49
  */
50
50
  content: {
51
51
  type: String,
52
- default: '',
52
+ default: undefined,
53
53
  },
54
54
  /**
55
55
  * The alert footer
@@ -58,7 +58,7 @@ export const VvAlertProps = {
58
58
  */
59
59
  footer: {
60
60
  type: String,
61
- default: '',
61
+ default: undefined,
62
62
  },
63
63
  /**
64
64
  * The alert role
@@ -8,8 +8,10 @@
8
8
  import { useVvAlertGroup, VvAlertGroupEvents, VvAlertGroupProps } from '.'
9
9
  import VvAlert from '../VvAlert/VvAlert.vue'
10
10
 
11
+ // props and emit
11
12
  const props = defineProps(VvAlertGroupProps)
12
13
  const emit = defineEmits(VvAlertGroupEvents)
14
+
13
15
  const { hasProps, hasTransition } = useVvAlertGroup(props, emit)
14
16
 
15
17
  const alertGroupTransitionHandlers = {
@@ -118,6 +118,7 @@
118
118
  href,
119
119
  target,
120
120
  rel,
121
+ ariaLabel,
121
122
  }"
122
123
  :id="hasId"
123
124
  ref="element"
@@ -13,6 +13,13 @@
13
13
  const emit = defineEmits(VvCheckboxEvents)
14
14
  const slots = useSlots()
15
15
 
16
+ // props merged with volver defaults (now only for labels)
17
+ const propsDefaults = useDefaults<typeof VvCheckboxProps>(
18
+ 'VvCheckbox',
19
+ VvCheckboxProps,
20
+ props,
21
+ )
22
+
16
23
  // data
17
24
  const {
18
25
  id,
@@ -150,7 +157,7 @@
150
157
  hasHintLabelOrSlot,
151
158
  hasInvalidLabelOrSlot,
152
159
  hintSlotScope,
153
- } = HintSlotFactory(props, slots)
160
+ } = HintSlotFactory(propsDefaults, slots)
154
161
  </script>
155
162
 
156
163
  <template>
@@ -17,6 +17,13 @@
17
17
  const emit = defineEmits(VvCheckboxGroupEvents)
18
18
  const slots = useSlots()
19
19
 
20
+ // props merged with volver defaults (now only for labels)
21
+ const propsDefaults = useDefaults<typeof VvCheckboxGroupProps>(
22
+ 'VvCheckboxGroup',
23
+ VvCheckboxGroupProps,
24
+ props,
25
+ )
26
+
20
27
  // data
21
28
  const modelValue = useVModel(props, 'modelValue', emit)
22
29
  const { disabled, readonly, vertical, valid, invalid, modifiers } =
@@ -56,7 +63,7 @@
56
63
  value: getOptionValue(option),
57
64
  }
58
65
  }
59
- const { HintSlot, hintSlotScope } = HintSlotFactory(props, slots)
66
+ const { HintSlot, hintSlotScope } = HintSlotFactory(propsDefaults, slots)
60
67
  </script>
61
68
 
62
69
  <template>
@@ -50,7 +50,7 @@
50
50
  hasHintLabelOrSlot,
51
51
  hasInvalidLabelOrSlot,
52
52
  hintSlotScope,
53
- } = HintSlotFactory(props, slots)
53
+ } = HintSlotFactory(propsDefaults, slots)
54
54
 
55
55
  // template ref
56
56
  const inputEl: Ref<HTMLElement | null> = ref(null)
@@ -184,6 +184,12 @@
184
184
 
185
185
  // options filtered by search text
186
186
  const filteredOptions = computed(() => {
187
+ if (propsDefaults.value.searchFunction) {
188
+ return propsDefaults.value.searchFunction(
189
+ debouncedSearchText.value,
190
+ props.options,
191
+ )
192
+ }
187
193
  return props.options?.filter((option) => {
188
194
  return getOptionLabel(option)
189
195
  .toLowerCase()
@@ -334,7 +340,7 @@
334
340
  autoPlacement: propsDefaults.value.autoPlacement,
335
341
  arrow: propsDefaults.value.arrow,
336
342
  autofocusFirst: searchable.value
337
- ? false
343
+ ? true
338
344
  : propsDefaults.value.autofocusFirst,
339
345
  triggerWidth: propsDefaults.value.triggerWidth,
340
346
  modifiers: propsDefaults.value.dropdownModifiers,
@@ -390,7 +396,6 @@
390
396
  <slot name="dropdown::before" />
391
397
  <input
392
398
  v-if="searchable"
393
- v-show="expanded"
394
399
  :id="hasSearchId"
395
400
  ref="inputSearchEl"
396
401
  v-model="searchText"
@@ -579,7 +584,7 @@
579
584
  <!-- Close button if dropdown custom position is enabled and floating-ui disabled -->
580
585
  <VvButton
581
586
  v-if="dropdownEl?.customPosition"
582
- label="Close"
587
+ :label="propsDefaults.closeLabel"
583
588
  modifiers="secondary"
584
589
  @click="dropdownEl.hide()"
585
590
  />
@@ -16,6 +16,7 @@ import {
16
16
  DropdownProps,
17
17
  LabelProps,
18
18
  } from '../../props'
19
+ import type { Option } from '../../types/generic'
19
20
 
20
21
  export const VvComboboxEvents = [
21
22
  'update:modelValue',
@@ -40,6 +41,13 @@ export const VvComboboxProps = {
40
41
  ...UnselectableProps,
41
42
  ...DropdownProps,
42
43
  ...LabelProps,
44
+ /**
45
+ * Dropdown show / hide transition name
46
+ */
47
+ transitionName: {
48
+ type: String,
49
+ default: 'vv-dropdown--mobile-fade-block',
50
+ },
43
51
  /**
44
52
  * modelValue can be a string, number, boolean, object or array of string, number, boolean, object
45
53
  */
@@ -71,6 +79,10 @@ export const VvComboboxProps = {
71
79
  * Label for deselected option hint
72
80
  */
73
81
  deselectHintLabel: { type: String, default: 'Press enter to remove' },
82
+ /**
83
+ * Label close button
84
+ */
85
+ closeLabel: { type: String, default: 'Close' },
74
86
  /**
75
87
  * Select input placeholder
76
88
  */
@@ -79,6 +91,18 @@ export const VvComboboxProps = {
79
91
  * Use input text to search on options
80
92
  */
81
93
  searchable: Boolean,
94
+ /**
95
+ * Search function to filter options
96
+ */
97
+ searchFunction: {
98
+ type: Function as PropType<
99
+ (
100
+ search: string,
101
+ options?: (Option | string)[],
102
+ ) => (Option | string)[]
103
+ >,
104
+ default: undefined,
105
+ },
82
106
  /**
83
107
  * On searchable select is the input search placeholder
84
108
  */
@@ -15,16 +15,16 @@
15
15
  const dialogEl: Ref<HTMLDialogElement | undefined> = ref()
16
16
 
17
17
  // data
18
+ const modelValue = useVModel(props, 'modelValue', emit)
18
19
  const localModelValue = ref(false)
19
- const modelValue = computed({
20
- get() {
21
- return props.modelValue ?? localModelValue.value
22
- },
23
- set(value) {
24
- if (props.modelValue === undefined) {
25
- localModelValue.value = value
20
+ const isOpened = computed({
21
+ get: () => modelValue.value ?? localModelValue.value,
22
+ set: (newValue) => {
23
+ if (modelValue.value === undefined) {
24
+ localModelValue.value = newValue
25
+ return
26
26
  }
27
- emit('update:modelValue', value)
27
+ modelValue.value = newValue
28
28
  },
29
29
  })
30
30
 
@@ -81,36 +81,35 @@
81
81
  // methods
82
82
  onClickOutside(modalWrapper, () => {
83
83
  if (!props.keepOpen) {
84
- modelValue.value = false
84
+ close()
85
85
  }
86
86
  })
87
87
 
88
88
  function close() {
89
- modelValue.value = false
89
+ isOpened.value = false
90
90
  }
91
91
 
92
92
  function open() {
93
- modelValue.value = true
93
+ isOpened.value = true
94
94
  }
95
95
 
96
96
  defineExpose({ close, open })
97
97
 
98
- // keyboard
99
- onKeyStroke('Escape', (e) => {
100
- if (modelValue.value) {
101
- e.preventDefault()
98
+ const onCancel = () => {
99
+ if (!props.keepOpen) {
102
100
  close()
103
101
  }
104
- })
102
+ }
105
103
  </script>
106
104
 
107
105
  <template>
108
106
  <Transition :name="transitioName" v-on="dialogTransitionHandlers">
109
107
  <dialog
110
- v-show="modelValue"
108
+ v-show="isOpened"
111
109
  v-bind="dialogAttrs"
112
110
  ref="dialogEl"
113
111
  :class="dialogClass"
112
+ @cancel.stop.prevent="onCancel"
114
113
  >
115
114
  <article ref="modalWrapper" class="vv-dialog__wrapper">
116
115
  <header v-if="$slots.header || title" class="vv-dialog__header">
@@ -161,7 +161,11 @@
161
161
  referenceEl,
162
162
  floatingEl,
163
163
  {
164
- whileElementsMounted: autoUpdate,
164
+ whileElementsMounted: (...args) => {
165
+ return autoUpdate(...args, {
166
+ animationFrame: props.strategy === 'fixed',
167
+ })
168
+ },
165
169
  placement: computed(() => props.placement),
166
170
  strategy: computed(() => props.strategy),
167
171
  middleware,
@@ -266,7 +270,7 @@
266
270
  onClickOutside(
267
271
  floatingEl,
268
272
  () => {
269
- if (!props.keepOpen) {
273
+ if (!props.keepOpen && expanded.value) {
270
274
  expanded.value = false
271
275
  }
272
276
  },
@@ -314,7 +318,7 @@
314
318
  }
315
319
  return [
316
320
  ...element.querySelectorAll(
317
- 'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])',
321
+ 'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])',
318
322
  ),
319
323
  ].filter(
320
324
  (el) =>
@@ -1,17 +1,11 @@
1
1
  import type { PropType } from 'vue'
2
- import { DropdownProps, IdProps } from '../../props'
2
+ import { DropdownProps, IdProps, ModifiersProps } from '../../props'
3
3
  import { DropdownRole } from '../../constants'
4
4
 
5
5
  export const VvDropdownProps = {
6
6
  ...IdProps,
7
7
  ...DropdownProps,
8
- /**
9
- * Component BEM modifiers
10
- */
11
- modifiers: {
12
- type: [String, Array] as PropType<string | string[]>,
13
- default: 'mobile',
14
- },
8
+ ...ModifiersProps,
15
9
  /**
16
10
  * Show / hide dropdown programmatically
17
11
  */
@@ -22,6 +22,13 @@
22
22
  const emit = defineEmits(VvInputTextEvents)
23
23
  const slots = useSlots()
24
24
 
25
+ // props merged with volver defaults (now only for labels)
26
+ const propsDefaults = useDefaults<typeof VvInputTextProps>(
27
+ 'VvInputText',
28
+ VvInputTextProps,
29
+ props,
30
+ )
31
+
25
32
  // template refs
26
33
  const inputEl = ref()
27
34
  const innerEl = ref()
@@ -278,7 +285,7 @@
278
285
  hasHintLabelOrSlot,
279
286
  hasInvalidLabelOrSlot,
280
287
  hintSlotScope,
281
- } = HintSlotFactory(props, slots)
288
+ } = HintSlotFactory(propsDefaults, slots)
282
289
  const PasswordInputActions = VvInputTextActionsFactory(
283
290
  INPUT_TYPES.PASSWORD,
284
291
  props,
@@ -55,7 +55,7 @@
55
55
  disabled: navItem.disabled,
56
56
  }"
57
57
  class="vv-nav__item-label"
58
- v-on="navItem.on || {}"
58
+ v-on="navItem.on"
59
59
  @click="onClick(navItem)"
60
60
  >
61
61
  {{ navItem.title }}
@@ -6,7 +6,7 @@ export type NavItem = {
6
6
  to?: string | { [key: string]: unknown }
7
7
  href?: string
8
8
  disabled?: boolean
9
- on: () => void
9
+ on?: Record<string, () => void>
10
10
  }
11
11
 
12
12
  export const VvNavProps = {
@@ -13,6 +13,13 @@
13
13
  const emit = defineEmits(VvRadioEvents)
14
14
  const slots = useSlots()
15
15
 
16
+ // props merged with volver defaults (now only for labels)
17
+ const propsDefaults = useDefaults<typeof VvRadioProps>(
18
+ 'VvRadio',
19
+ VvRadioProps,
20
+ props,
21
+ )
22
+
16
23
  // data
17
24
  const { id, disabled, readonly, modelValue, valid, invalid } =
18
25
  useGroupProps(props, emit)
@@ -77,7 +84,7 @@
77
84
  hasHintLabelOrSlot,
78
85
  hasInvalidLabelOrSlot,
79
86
  hintSlotScope,
80
- } = HintSlotFactory(props, slots)
87
+ } = HintSlotFactory(propsDefaults, slots)
81
88
  </script>
82
89
 
83
90
  <template>
@@ -17,6 +17,13 @@
17
17
  const emit = defineEmits(VvRadioGroupEvents)
18
18
  const slots = useSlots()
19
19
 
20
+ // props merged with volver defaults (now only for labels)
21
+ const propsDefaults = useDefaults<typeof VvRadioGroupProps>(
22
+ 'VvRadioGroup',
23
+ VvRadioGroupProps,
24
+ props,
25
+ )
26
+
20
27
  // data
21
28
  const modelValue = useVModel(props, 'modelValue', emit)
22
29
  const { disabled, readonly, vertical, valid, invalid, modifiers } =
@@ -58,7 +65,7 @@
58
65
  }
59
66
 
60
67
  // hint
61
- const { HintSlot, hintSlotScope } = HintSlotFactory(props, slots)
68
+ const { HintSlot, hintSlotScope } = HintSlotFactory(propsDefaults, slots)
62
69
  </script>
63
70
 
64
71
  <template>
@@ -16,6 +16,13 @@
16
16
  const emit = defineEmits(VvSelectEmits)
17
17
  const slots = useSlots()
18
18
 
19
+ // props merged with volver defaults (now only for labels)
20
+ const propsDefaults = useDefaults<typeof VvSelectProps>(
21
+ 'VvSelect',
22
+ VvSelectProps,
23
+ props,
24
+ )
25
+
19
26
  // template refs
20
27
  const select = ref()
21
28
 
@@ -25,7 +32,7 @@
25
32
  hasHintLabelOrSlot,
26
33
  hasInvalidLabelOrSlot,
27
34
  hintSlotScope,
28
- } = HintSlotFactory(props, slots)
35
+ } = HintSlotFactory(propsDefaults, slots)
29
36
 
30
37
  // data
31
38
  const {
@@ -15,6 +15,13 @@
15
15
  const emit = defineEmits(VvTextareaEvents)
16
16
  const slots = useSlots()
17
17
 
18
+ // props merged with volver defaults (now only for labels)
19
+ const propsDefaults = useDefaults<typeof VvTextareaProps>(
20
+ 'VvTextarea',
21
+ VvTextareaProps,
22
+ props,
23
+ )
24
+
18
25
  // template refs
19
26
  const textarea = ref()
20
27
 
@@ -91,7 +98,7 @@
91
98
  hasHintLabelOrSlot,
92
99
  hasInvalidLabelOrSlot,
93
100
  hintSlotScope,
94
- } = HintSlotFactory(props, slots)
101
+ } = HintSlotFactory(propsDefaults, slots)
95
102
 
96
103
  // styles
97
104
  const bemCssClasses = useModifiers(
@@ -1,4 +1,5 @@
1
1
  import type { ExtractPropTypes, Slots } from 'vue'
2
+ import type { Ref } from 'vue'
2
3
 
3
4
  /**
4
5
  * Merge array of string
@@ -19,7 +20,7 @@ export type HintSlotProps = Readonly<
19
20
  default: ''
20
21
  required: true
21
22
  }
22
- modelValue: null
23
+ modelValue: unknown
23
24
  valid: BooleanConstructor
24
25
  validLabel: (StringConstructor | ArrayConstructor)[]
25
26
  invalid: BooleanConstructor
@@ -35,27 +36,39 @@ export type HintSlotProps = Readonly<
35
36
  * @param {Slots} parentSlots vue slots
36
37
  * @returns {Component} vue component
37
38
  */
38
- export function HintSlotFactory(props: HintSlotProps, slots: Slots) {
39
+ export function HintSlotFactory(
40
+ propsOrRef: HintSlotProps | Ref<HintSlotProps>,
41
+ slots: Slots,
42
+ ) {
43
+ const props = computed(() => {
44
+ if (isRef(propsOrRef)) {
45
+ return propsOrRef.value
46
+ }
47
+ return propsOrRef
48
+ })
49
+
39
50
  // label
40
- const invalidLabel = computed(() => joinLines(props.invalidLabel))
41
- const validLabel = computed(() => joinLines(props.validLabel))
42
- const loadingLabel = computed(() => props.loadingLabel)
43
- const hintLabel = computed(() => props.hintLabel)
51
+ const invalidLabel = computed(() => joinLines(props.value.invalidLabel))
52
+ const validLabel = computed(() => joinLines(props.value.validLabel))
53
+ const loadingLabel = computed(() => props.value.loadingLabel)
54
+ const hintLabel = computed(() => props.value.hintLabel)
44
55
 
45
56
  // type
46
57
  const hasLoadingLabelOrSlot = computed(() =>
47
- Boolean(props.loading && (slots.loading || loadingLabel.value)),
58
+ Boolean(props.value.loading && (slots.loading || loadingLabel.value)),
48
59
  )
49
60
  const hasInvalidLabelOrSlot = computed(
50
61
  () =>
51
62
  !hasLoadingLabelOrSlot.value &&
52
- Boolean(props.invalid && (slots.invalid || invalidLabel.value)),
63
+ Boolean(
64
+ props.value.invalid && (slots.invalid || invalidLabel.value),
65
+ ),
53
66
  )
54
67
  const hasValidLabelOrSlot = computed(
55
68
  () =>
56
69
  !hasLoadingLabelOrSlot.value &&
57
70
  !hasInvalidLabelOrSlot.value &&
58
- Boolean(props.valid && (slots.valid || validLabel.value)),
71
+ Boolean(props.value.valid && (slots.valid || validLabel.value)),
59
72
  )
60
73
  const hasHintLabelOrSlot = computed(
61
74
  () =>
@@ -72,10 +85,10 @@ export function HintSlotFactory(props: HintSlotProps, slots: Slots) {
72
85
  hasHintLabelOrSlot.value,
73
86
  )
74
87
  const hintSlotScope = computed(() => ({
75
- modelValue: props.modelValue,
76
- valid: props.valid,
77
- invalid: props.invalid,
78
- loading: props.loading,
88
+ modelValue: props.value.modelValue,
89
+ valid: props.value.valid,
90
+ invalid: props.value.invalid,
91
+ loading: props.value.loading,
79
92
  }))
80
93
  // component
81
94
  const HintSlot = defineComponent({
@@ -1,5 +1,7 @@
1
1
  export { default as VvAccordion } from './VvAccordion/VvAccordion.vue'
2
2
  export { default as VvAccordionGroup } from './VvAccordionGroup/VvAccordionGroup.vue'
3
+ export { default as VvAction } from './VvAction/VvAction.vue'
4
+ export { default as VvAlert } from './VvAlert/VvAlert.vue'
3
5
  export { default as VvBadge } from './VvBadge/VvBadge.vue'
4
6
  export { default as VvBreadcrumb } from './VvBreadcrumb/VvBreadcrumb.vue'
5
7
  export { default as VvButton } from './VvButton/VvButton.vue'
@@ -12,8 +14,11 @@ export { default as VvDialog } from './VvDialog/VvDialog.vue'
12
14
  export { default as VvDropdown } from './VvDropdown/VvDropdown.vue'
13
15
  export { default as VvIcon } from './VvIcon/VvIcon.vue'
14
16
  export { default as VvInputText } from './VvInputText/VvInputText.vue'
17
+ export { default as VvNav } from './VvNav/VvNav.vue'
15
18
  export { default as VvProgress } from './VvProgress/VvProgress.vue'
16
19
  export { default as VvRadio } from './VvRadio/VvRadio.vue'
17
20
  export { default as VvRadioGroup } from './VvRadioGroup/VvRadioGroup.vue'
18
21
  export { default as VvSelect } from './VvSelect/VvSelect.vue'
22
+ export { default as VvTab } from './VvTab/VvTab.vue'
19
23
  export { default as VvTextarea } from './VvTextarea/VvTextarea.vue'
24
+ export { default as VvTooltip } from './VvTooltip/VvTooltip.vue'
@@ -0,0 +1,103 @@
1
+ import {
2
+ DEFAULT_ALERT_AUTO_CLOSE,
3
+ DEFAULT_ALERT_DISMISSABLE,
4
+ DEFAULT_ALERT_GROUP,
5
+ DEFAULT_ALERT_MODIFIERS,
6
+ DEFAULT_ALERT_INFO_ICON,
7
+ DefaultAlertIconMap,
8
+ } from '@/constants'
9
+ import type { Alert, AlertModifiers } from '@/types/alert'
10
+
11
+ const groups = reactive(
12
+ new Map<string, Map<string, Alert>>([
13
+ [DEFAULT_ALERT_GROUP, new Map<string, Alert>()],
14
+ ]),
15
+ )
16
+
17
+ /**
18
+ * @description Composable to access alert groups, alerts and functions to add, remove and get alerts by group.
19
+ * @example
20
+ * const { groups, alerts, addAlert, removeAlert, getAlerts } = useAlert()
21
+ * addAlert({
22
+ * title: 'Success!',
23
+ * modifiers: 'success',
24
+ * })
25
+ *
26
+ * `<vv-alert-group :items="alerts" :onClose="removeAlert" />`
27
+ *
28
+ * @returns {
29
+ * alerts: ComputedRef<Alert[]> reactive list of alerts default group,
30
+ * groups: ReactiveRef<Map<string, Map<string, Alert>>>,
31
+ * addAlert: Function to add alert,
32
+ * removeAlert: Function to remove alert,
33
+ * getAlerts: Function to get alerts by group
34
+ * }
35
+ */
36
+ export const useAlert = () => {
37
+ const addAlert = (
38
+ {
39
+ id = crypto.randomUUID(),
40
+ group = DEFAULT_ALERT_GROUP,
41
+ title,
42
+ icon = DEFAULT_ALERT_INFO_ICON,
43
+ content,
44
+ footer,
45
+ modifiers = DEFAULT_ALERT_MODIFIERS,
46
+ dismissable = DEFAULT_ALERT_DISMISSABLE,
47
+ autoClose = DEFAULT_ALERT_AUTO_CLOSE,
48
+ } = {} as Partial<Alert>,
49
+ ) => {
50
+ if (!groups.has(group)) {
51
+ groups.set(group, new Map<string, Alert>())
52
+ }
53
+ const groupMap = groups.get(group)
54
+ const normalizedModifiers =
55
+ typeof modifiers === 'string' ? modifiers.split(' ') : modifiers
56
+
57
+ if (!icon) {
58
+ const alertModifier = normalizedModifiers.find((modifier) =>
59
+ DefaultAlertIconMap.has(modifier as AlertModifiers),
60
+ ) as AlertModifiers | undefined
61
+
62
+ if (alertModifier) {
63
+ icon = DefaultAlertIconMap.get(alertModifier) as string
64
+ }
65
+ }
66
+ groupMap?.set(id.toString(), {
67
+ id,
68
+ group,
69
+ title,
70
+ icon,
71
+ content,
72
+ footer,
73
+ modifiers,
74
+ dismissable,
75
+ autoClose,
76
+ timestamp: Date.now(),
77
+ })
78
+ }
79
+
80
+ const removeAlert = (id: string | number, group = DEFAULT_ALERT_GROUP) => {
81
+ const groupMap = groups.get(group)
82
+ groupMap?.delete(id.toString())
83
+ }
84
+
85
+ const getAlerts = (group = DEFAULT_ALERT_GROUP) => {
86
+ return computed(() => {
87
+ const groupMap = groups.get(group)
88
+ return groupMap && groupMap instanceof Map
89
+ ? Array.from(groupMap?.values()).sort(
90
+ (a, b) => a.timestamp - b.timestamp,
91
+ )
92
+ : []
93
+ })
94
+ }
95
+
96
+ return {
97
+ groups,
98
+ alerts: getAlerts(),
99
+ addAlert,
100
+ removeAlert,
101
+ getAlerts,
102
+ }
103
+ }
@@ -0,0 +1 @@
1
+ export { useAlert } from './alert/useAlert'