@coreui/vue-pro 4.9.0-beta.2 → 5.0.0-alpha.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 (34) hide show
  1. package/README.md +1 -1
  2. package/dist/components/dropdown/CDropdown.d.ts +62 -4
  3. package/dist/components/dropdown/CDropdownToggle.d.ts +1 -1
  4. package/dist/components/form/CFormCheck.d.ts +26 -2
  5. package/dist/components/form/CFormInput.d.ts +6 -18
  6. package/dist/components/multi-select/CMultiSelect.d.ts +6 -6
  7. package/dist/components/popover/CPopover.d.ts +75 -6
  8. package/dist/components/toast/CToast.d.ts +1 -1
  9. package/dist/components/tooltip/CTooltip.d.ts +77 -8
  10. package/dist/composables/index.d.ts +2 -1
  11. package/dist/composables/useColorModes.d.ts +1 -1
  12. package/dist/composables/usePopper.d.ts +6 -0
  13. package/dist/index.es.js +384 -238
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/index.js +383 -236
  16. package/dist/index.js.map +1 -1
  17. package/dist/types.d.ts +1 -1
  18. package/dist/utils/getRTLPlacement.d.ts +3 -0
  19. package/dist/utils/index.d.ts +2 -1
  20. package/package.json +11 -11
  21. package/src/components/date-range-picker/CDateRangePicker.ts +6 -4
  22. package/src/components/dropdown/CDropdown.ts +116 -61
  23. package/src/components/dropdown/CDropdownMenu.ts +2 -47
  24. package/src/components/dropdown/CDropdownToggle.ts +5 -5
  25. package/src/components/form/CFormCheck.ts +53 -4
  26. package/src/components/multi-select/CMultiSelect.ts +3 -3
  27. package/src/components/popover/CPopover.ts +96 -50
  28. package/src/components/tooltip/CTooltip.ts +97 -51
  29. package/src/composables/index.ts +2 -1
  30. package/src/composables/useColorModes.ts +2 -1
  31. package/src/composables/usePopper.ts +25 -0
  32. package/src/types.ts +1 -1
  33. package/src/utils/getRTLPlacement.ts +18 -0
  34. package/src/utils/index.ts +2 -1
@@ -1,30 +1,54 @@
1
1
  import { defineComponent, h, PropType, ref, RendererElement, Teleport, Transition } from 'vue'
2
- import { createPopper, Placement } from '@popperjs/core'
2
+ import type { Placement } from '@popperjs/core'
3
3
 
4
+ import { usePopper } from '../../composables'
5
+ import type { Placements, Triggers } from '../../types'
4
6
  import { executeAfterTransition } from '../../utils/transition'
5
- import { isRTL } from '../../utils'
6
-
7
- const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
8
- switch (placement) {
9
- case 'right': {
10
- return isRTL(element) ? 'left' : 'right'
11
- }
12
- case 'left': {
13
- return isRTL(element) ? 'right' : 'left'
14
- }
15
- default: {
16
- return placement as Placement
17
- }
18
- }
19
- }
7
+ import { getRTLPlacement } from '../../utils'
20
8
 
21
9
  const CPopover = defineComponent({
22
10
  name: 'CPopover',
23
11
  props: {
12
+ /**
13
+ * Apply a CSS fade transition to the popover.
14
+ *
15
+ * @since 4.9.0
16
+ */
17
+ animation: {
18
+ type: Boolean,
19
+ default: true,
20
+ },
24
21
  /**
25
22
  * Content for your component. If you want to pass non-string value please use dedicated slot `<template #content>...</template>`
26
23
  */
27
24
  content: String,
25
+ /**
26
+ * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
27
+ *
28
+ * @since 4.9.0
29
+ */
30
+ delay: {
31
+ type: [Number, Object] as PropType<number | { show: number; hide: number }>,
32
+ default: 0,
33
+ },
34
+ /**
35
+ * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
36
+ *
37
+ * @since 4.9.0
38
+ */
39
+ fallbackPlacements: {
40
+ type: [String, Array] as PropType<Placements | Placements[]>,
41
+ default: () => ['top', 'right', 'bottom', 'left'],
42
+ validator: (value: Placements | Placements[]) => {
43
+ if (typeof value === 'string') {
44
+ return ['top', 'right', 'bottom', 'left'].includes(value)
45
+ }
46
+ if (Array.isArray(value)) {
47
+ return value.every((e) => ['top', 'right', 'bottom', 'left'].includes(e))
48
+ }
49
+ return false
50
+ },
51
+ },
28
52
  /**
29
53
  * Offset of the popover relative to its target.
30
54
  */
@@ -52,9 +76,9 @@ const CPopover = defineComponent({
52
76
  * @values 'click', 'focus', 'hover'
53
77
  */
54
78
  trigger: {
55
- type: [String, Array] as PropType<string | string[]>,
79
+ type: [String, Array] as PropType<Triggers | Triggers[]>,
56
80
  default: 'click',
57
- validator: (value: string | string[]) => {
81
+ validator: (value: Triggers | Triggers[]) => {
58
82
  if (typeof value === 'string') {
59
83
  return ['click', 'focus', 'hover'].includes(value)
60
84
  }
@@ -82,12 +106,39 @@ const CPopover = defineComponent({
82
106
  setup(props, { attrs, slots, emit }) {
83
107
  const togglerRef = ref()
84
108
  const popoverRef = ref()
85
- const popper = ref()
86
109
  const visible = ref(props.visible)
110
+ const { initPopper, destroyPopper } = usePopper()
111
+
112
+ const delay =
113
+ typeof props.delay === 'number' ? { show: props.delay, hide: props.delay } : props.delay
114
+
115
+ const popperConfig = {
116
+ modifiers: [
117
+ {
118
+ name: 'arrow',
119
+ options: {
120
+ element: '.popover-arrow',
121
+ },
122
+ },
123
+ {
124
+ name: 'flip',
125
+ options: {
126
+ fallbackPlacements: props.fallbackPlacements,
127
+ },
128
+ },
129
+ {
130
+ name: 'offset',
131
+ options: {
132
+ offset: props.offset,
133
+ },
134
+ },
135
+ ],
136
+ placement: getRTLPlacement(props.placement, togglerRef.value),
137
+ }
87
138
 
88
139
  const handleEnter = (el: RendererElement, done: () => void) => {
89
140
  emit('show')
90
- initPopper()
141
+ initPopper(togglerRef.value, popoverRef.value, popperConfig)
91
142
  el.classList.add('show')
92
143
  executeAfterTransition(() => done(), el as HTMLElement)
93
144
  }
@@ -101,32 +152,18 @@ const CPopover = defineComponent({
101
152
  }, el as HTMLElement)
102
153
  }
103
154
 
104
- const handleToggle = (event: Event) => {
155
+ const toggleVisible = (event: Event, _visible: boolean) => {
105
156
  togglerRef.value = event.target
106
- visible.value = !visible.value
107
- }
108
-
109
- const initPopper = () => {
110
- if (togglerRef.value) {
111
- popper.value = createPopper(togglerRef.value, popoverRef.value, {
112
- placement: getPlacement(props.placement, togglerRef.value),
113
- modifiers: [
114
- {
115
- name: 'offset',
116
- options: {
117
- offset: props.offset,
118
- },
119
- },
120
- ],
121
- })
157
+ if (_visible) {
158
+ setTimeout(() => {
159
+ visible.value = true
160
+ }, delay.show)
161
+ return
122
162
  }
123
- }
124
163
 
125
- const destroyPopper = () => {
126
- if (popper.value) {
127
- popper.value.destroy()
128
- }
129
- popper.value = undefined
164
+ setTimeout(() => {
165
+ visible.value = false
166
+ }, delay.hide)
130
167
  }
131
168
 
132
169
  return () => [
@@ -146,13 +183,19 @@ const CPopover = defineComponent({
146
183
  h(
147
184
  'div',
148
185
  {
149
- class: 'popover fade bs-popover-auto',
186
+ class: [
187
+ 'popover',
188
+ 'bs-popover-auto',
189
+ {
190
+ fade: props.animation,
191
+ },
192
+ ],
150
193
  ref: popoverRef,
151
194
  role: 'tooltip',
152
195
  ...attrs,
153
196
  },
154
197
  [
155
- h('div', { class: 'popover-arrow', 'data-popper-arrow': '' }),
198
+ h('div', { class: 'popover-arrow' }),
156
199
  (props.title || slots.title) &&
157
200
  h(
158
201
  'div',
@@ -176,11 +219,14 @@ const CPopover = defineComponent({
176
219
  slots.toggler &&
177
220
  slots.toggler({
178
221
  on: {
179
- click: (event: Event) => props.trigger.includes('click') && handleToggle(event),
180
- blur: (event: Event) => props.trigger.includes('focus') && handleToggle(event),
181
- focus: (event: Event) => props.trigger.includes('focus') && handleToggle(event),
182
- mouseenter: (event: Event) => props.trigger.includes('hover') && handleToggle(event),
183
- mouseleave: (event: Event) => props.trigger.includes('hover') && handleToggle(event),
222
+ click: (event: Event) =>
223
+ props.trigger.includes('click') && toggleVisible(event, !visible.value),
224
+ blur: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, false),
225
+ focus: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, true),
226
+ mouseenter: (event: Event) =>
227
+ props.trigger.includes('hover') && toggleVisible(event, true),
228
+ mouseleave: (event: Event) =>
229
+ props.trigger.includes('hover') && toggleVisible(event, false),
184
230
  },
185
231
  }),
186
232
  ]
@@ -1,30 +1,54 @@
1
1
  import { defineComponent, h, PropType, ref, RendererElement, Teleport, Transition } from 'vue'
2
- import { createPopper, Placement } from '@popperjs/core'
2
+ import type { Placement } from '@popperjs/core'
3
3
 
4
+ import { usePopper } from '../../composables'
5
+ import type { Placements, Triggers } from '../../types'
4
6
  import { executeAfterTransition } from '../../utils/transition'
5
- import { isRTL } from '../../utils'
6
-
7
- const getPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
8
- switch (placement) {
9
- case 'right': {
10
- return isRTL(element) ? 'left' : 'right'
11
- }
12
- case 'left': {
13
- return isRTL(element) ? 'right' : 'left'
14
- }
15
- default: {
16
- return placement as Placement
17
- }
18
- }
19
- }
7
+ import { getRTLPlacement } from '../../utils'
20
8
 
21
9
  const CTooltip = defineComponent({
22
10
  name: 'CTooltip',
23
11
  props: {
12
+ /**
13
+ * Apply a CSS fade transition to the tooltip.
14
+ *
15
+ * @since 4.9.0
16
+ */
17
+ animation: {
18
+ type: Boolean,
19
+ default: true,
20
+ },
24
21
  /**
25
22
  * Content for your component. If you want to pass non-string value please use dedicated slot `<template #content>...</template>`
26
23
  */
27
24
  content: String,
25
+ /**
26
+ * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
27
+ *
28
+ * @since 4.9.0
29
+ */
30
+ delay: {
31
+ type: [Number, Object] as PropType<number | { show: number; hide: number }>,
32
+ default: 0,
33
+ },
34
+ /**
35
+ * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
36
+ *
37
+ * @since 4.9.0
38
+ */
39
+ fallbackPlacements: {
40
+ type: [String, Array] as PropType<Placements | Placements[]>,
41
+ default: () => ['top', 'right', 'bottom', 'left'],
42
+ validator: (value: Placements | Placements[]) => {
43
+ if (typeof value === 'string') {
44
+ return ['top', 'right', 'bottom', 'left'].includes(value)
45
+ }
46
+ if (Array.isArray(value)) {
47
+ return value.every((e) => ['top', 'right', 'bottom', 'left'].includes(e))
48
+ }
49
+ return false
50
+ },
51
+ },
28
52
  /**
29
53
  * Offset of the tooltip relative to its target.
30
54
  */
@@ -48,9 +72,9 @@ const CTooltip = defineComponent({
48
72
  * @values 'click', 'focus', 'hover'
49
73
  */
50
74
  trigger: {
51
- type: [String, Array] as PropType<string | string[]>,
52
- default: 'hover',
53
- validator: (value: string | string[]) => {
75
+ type: [String, Array] as PropType<Triggers | Triggers[]>,
76
+ default: () => ['hover', 'focus'],
77
+ validator: (value: Triggers | Triggers[]) => {
54
78
  if (typeof value === 'string') {
55
79
  return ['click', 'focus', 'hover'].includes(value)
56
80
  }
@@ -78,12 +102,39 @@ const CTooltip = defineComponent({
78
102
  setup(props, { attrs, slots, emit }) {
79
103
  const togglerRef = ref()
80
104
  const tooltipRef = ref()
81
- const popper = ref()
82
105
  const visible = ref(props.visible)
106
+ const { initPopper, destroyPopper } = usePopper()
107
+
108
+ const delay =
109
+ typeof props.delay === 'number' ? { show: props.delay, hide: props.delay } : props.delay
110
+
111
+ const popperConfig = {
112
+ modifiers: [
113
+ {
114
+ name: 'arrow',
115
+ options: {
116
+ element: '.tooltip-arrow',
117
+ },
118
+ },
119
+ {
120
+ name: 'flip',
121
+ options: {
122
+ fallbackPlacements: props.fallbackPlacements,
123
+ },
124
+ },
125
+ {
126
+ name: 'offset',
127
+ options: {
128
+ offset: props.offset,
129
+ },
130
+ },
131
+ ],
132
+ placement: getRTLPlacement(props.placement, togglerRef.value),
133
+ }
83
134
 
84
135
  const handleEnter = (el: RendererElement, done: () => void) => {
85
136
  emit('show')
86
- initPopper()
137
+ initPopper(togglerRef.value, tooltipRef.value, popperConfig)
87
138
  el.classList.add('show')
88
139
  executeAfterTransition(() => done(), el as HTMLElement)
89
140
  }
@@ -97,32 +148,18 @@ const CTooltip = defineComponent({
97
148
  }, el as HTMLElement)
98
149
  }
99
150
 
100
- const handleToggle = (event: Event) => {
151
+ const toggleVisible = (event: Event, _visible: boolean) => {
101
152
  togglerRef.value = event.target
102
- visible.value = !visible.value
103
- }
104
-
105
- const initPopper = () => {
106
- if (togglerRef.value) {
107
- popper.value = createPopper(togglerRef.value, tooltipRef.value, {
108
- placement: getPlacement(props.placement, togglerRef.value),
109
- modifiers: [
110
- {
111
- name: 'offset',
112
- options: {
113
- offset: props.offset,
114
- },
115
- },
116
- ],
117
- })
153
+ if (_visible) {
154
+ setTimeout(() => {
155
+ visible.value = true
156
+ }, delay.show)
157
+ return
118
158
  }
119
- }
120
159
 
121
- const destroyPopper = () => {
122
- if (popper.value) {
123
- popper.value.destroy()
124
- }
125
- popper.value = undefined
160
+ setTimeout(() => {
161
+ visible.value = false
162
+ }, delay.hide)
126
163
  }
127
164
 
128
165
  return () => [
@@ -142,13 +179,19 @@ const CTooltip = defineComponent({
142
179
  h(
143
180
  'div',
144
181
  {
145
- class: 'tooltip fade bs-tooltip-auto',
182
+ class: [
183
+ 'tooltip',
184
+ 'bs-tooltip-auto',
185
+ {
186
+ fade: props.animation,
187
+ },
188
+ ],
146
189
  ref: tooltipRef,
147
190
  role: 'tooltip',
148
191
  ...attrs,
149
192
  },
150
193
  [
151
- h('div', { class: 'tooltip-arrow', 'data-popper-arrow': '' }),
194
+ h('div', { class: 'tooltip-arrow' }),
152
195
  (props.content || slots.content) &&
153
196
  h(
154
197
  'div',
@@ -164,11 +207,14 @@ const CTooltip = defineComponent({
164
207
  slots.toggler &&
165
208
  slots.toggler({
166
209
  on: {
167
- click: (event: Event) => props.trigger.includes('click') && handleToggle(event),
168
- blur: (event: Event) => props.trigger.includes('focus') && handleToggle(event),
169
- focus: (event: Event) => props.trigger.includes('focus') && handleToggle(event),
170
- mouseenter: (event: Event) => props.trigger.includes('hover') && handleToggle(event),
171
- mouseleave: (event: Event) => props.trigger.includes('hover') && handleToggle(event),
210
+ click: (event: Event) =>
211
+ props.trigger.includes('click') && toggleVisible(event, !visible.value),
212
+ blur: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, false),
213
+ focus: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, true),
214
+ mouseenter: (event: Event) =>
215
+ props.trigger.includes('hover') && toggleVisible(event, true),
216
+ mouseleave: (event: Event) =>
217
+ props.trigger.includes('hover') && toggleVisible(event, false),
172
218
  },
173
219
  }),
174
220
  ]
@@ -1,3 +1,4 @@
1
1
  import { useColorModes } from './useColorModes'
2
+ import { usePopper } from './usePopper'
2
3
 
3
- export { useColorModes }
4
+ export { useColorModes, usePopper }
@@ -2,6 +2,7 @@ import { onBeforeMount, ref, watch } from 'vue'
2
2
 
3
3
  const getStoredTheme = (localStorageItemName: string) =>
4
4
  typeof window !== 'undefined' && localStorage.getItem(localStorageItemName)
5
+
5
6
  const setStoredTheme = (localStorageItemName: string, colorMode: string) =>
6
7
  localStorage.setItem(localStorageItemName, colorMode)
7
8
 
@@ -53,7 +54,7 @@ export const useColorModes = (localStorageItemName = 'coreui-vue-color-scheme')
53
54
  })
54
55
 
55
56
  return {
56
- getColorMode: () => colorMode.value,
57
+ colorMode,
57
58
  isColorModeSet: () => Boolean(getStoredTheme(localStorageItemName)),
58
59
  setColorMode: (mode: string) => {
59
60
  colorMode.value = mode
@@ -0,0 +1,25 @@
1
+ import { ref } from 'vue'
2
+ import { createPopper } from '@popperjs/core'
3
+ import type { Instance, Options } from '@popperjs/core'
4
+
5
+ export const usePopper = () => {
6
+ const _popper = ref<Instance>()
7
+
8
+ const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial<Options>) => {
9
+ _popper.value = createPopper(reference, popper, options)
10
+ }
11
+
12
+ const destroyPopper = () => {
13
+ if (_popper.value) {
14
+ _popper.value.destroy()
15
+ }
16
+
17
+ _popper.value = undefined
18
+ }
19
+
20
+ return {
21
+ popper: _popper.value,
22
+ initPopper,
23
+ destroyPopper,
24
+ }
25
+ }
package/src/types.ts CHANGED
@@ -35,7 +35,7 @@ export type Placements =
35
35
  | 'left-start'
36
36
  | 'left'
37
37
  | 'left-end'
38
- | undefined
38
+ | string
39
39
 
40
40
  export type Shapes =
41
41
  | 'rounded'
@@ -0,0 +1,18 @@
1
+ import { Placement } from '@popperjs/core'
2
+ import { isRTL } from '../utils'
3
+
4
+ const getRTLPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
5
+ switch (placement) {
6
+ case 'right': {
7
+ return isRTL(element) ? 'left' : 'right'
8
+ }
9
+ case 'left': {
10
+ return isRTL(element) ? 'right' : 'left'
11
+ }
12
+ default: {
13
+ return placement as Placement
14
+ }
15
+ }
16
+ }
17
+
18
+ export default getRTLPlacement
@@ -1,6 +1,7 @@
1
+ import getRTLPlacement from './getRTLPlacement'
1
2
  import getUID from './getUID'
2
3
  import isInViewport from './isInViewport'
3
4
  import isObjectInArray from './isObjectInArray'
4
5
  import isRTL from './isRTL'
5
6
 
6
- export { getUID, isInViewport, isObjectInArray, isRTL }
7
+ export { getRTLPlacement, getUID, isInViewport, isObjectInArray, isRTL }