@coreui/vue-pro 4.0.2 → 4.1.1

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 (53) hide show
  1. package/README.md +1 -1
  2. package/dist/components/carousel/CCarousel.d.ts +2 -2
  3. package/dist/components/collapse/CCollapse.d.ts +10 -0
  4. package/dist/components/element-cover/index.d.ts +6 -0
  5. package/dist/components/form/CFormCheck.d.ts +7 -0
  6. package/dist/components/index.d.ts +2 -0
  7. package/dist/components/modal/CModal.d.ts +2 -2
  8. package/dist/components/placeholder/CPlaceholder.d.ts +124 -0
  9. package/dist/components/placeholder/index.d.ts +6 -0
  10. package/dist/components/popover/CPopover.d.ts +2 -2
  11. package/dist/components/smart-table/CSmartTable.d.ts +5 -11
  12. package/dist/components/smart-table/CSmartTableHead.d.ts +7 -3
  13. package/dist/components/table/CTable.d.ts +2 -2
  14. package/dist/components/widgets/CWidgetStatsB.d.ts +2 -2
  15. package/dist/components/widgets/CWidgetStatsF.d.ts +2 -2
  16. package/dist/directives/index.d.ts +3 -2
  17. package/dist/directives/v-c-placeholder.d.ts +6 -0
  18. package/dist/directives/v-c-visible.d.ts +6 -0
  19. package/dist/index.es.js +693 -441
  20. package/dist/index.es.js.map +1 -1
  21. package/dist/index.js +696 -439
  22. package/dist/index.js.map +1 -1
  23. package/package.json +8 -8
  24. package/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.ts.snap +1 -1
  25. package/src/components/button/CButton.ts +1 -0
  26. package/src/components/collapse/CCollapse.ts +49 -21
  27. package/src/components/collapse/__test__/__snapshots__/CCollapse.spec.ts.snap +1 -1
  28. package/src/components/element-cover/index.ts +10 -0
  29. package/src/components/form/CFormCheck.ts +9 -19
  30. package/src/components/form/CFormInput.ts +5 -5
  31. package/src/components/form/CFormRange.ts +2 -2
  32. package/src/components/form/CFormSelect.ts +3 -4
  33. package/src/components/form/CFormSwitch.ts +1 -1
  34. package/src/components/form/CFormTextarea.ts +1 -7
  35. package/src/components/form/__tests__/__snapshots__/CFormInput.spec.ts.snap +3 -3
  36. package/src/components/grid/CCol.ts +8 -8
  37. package/src/components/grid/CContainer.ts +3 -3
  38. package/src/components/grid/CRow.ts +6 -6
  39. package/src/components/index.ts +2 -0
  40. package/src/components/modal/CModal.ts +8 -3
  41. package/src/components/offcanvas/COffcanvas.ts +30 -20
  42. package/src/components/offcanvas/__tests__/COffcanvas.spec.ts +1 -1
  43. package/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.ts.snap +2 -2
  44. package/src/components/placeholder/CPlaceholder.ts +139 -0
  45. package/src/components/placeholder/__tests__/CPlaceholder.spec.ts +44 -0
  46. package/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.ts.snap +15 -0
  47. package/src/components/placeholder/index.ts +10 -0
  48. package/src/components/smart-table/CSmartTable.ts +38 -36
  49. package/src/components/smart-table/CSmartTableHead.ts +54 -44
  50. package/src/directives/index.ts +3 -2
  51. package/src/directives/v-c-placeholder.ts +32 -0
  52. package/src/directives/v-c-visible.ts +33 -0
  53. package/src/index.ts +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreui/vue-pro",
3
- "version": "4.0.2",
3
+ "version": "4.1.1",
4
4
  "description": "UI Components Library for Vue.js",
5
5
  "keywords": [
6
6
  "vue",
@@ -35,23 +35,23 @@
35
35
  "watch": "rollup -c -w"
36
36
  },
37
37
  "config": {
38
- "version_short": "4.0"
38
+ "version_short": "4.1"
39
39
  },
40
40
  "devDependencies": {
41
- "@popperjs/core": "^2.10.2",
41
+ "@popperjs/core": "^2.11.0",
42
42
  "@rollup/plugin-commonjs": "^21.0.1",
43
43
  "@rollup/plugin-node-resolve": "^13.0.6",
44
44
  "@rollup/plugin-typescript": "^8.3.0",
45
45
  "@vue/test-utils": "^2.0.0-0",
46
- "rollup": "^2.58.3",
46
+ "rollup": "^2.60.2",
47
47
  "rollup-plugin-vue": "^6.0.0",
48
- "typescript": "^4.4.4",
49
- "vue": "^3.2.20",
48
+ "typescript": "^4.5.2",
49
+ "vue": "^3.2.24",
50
50
  "vue-types": "^4.1.1"
51
51
  },
52
52
  "peerDependencies": {
53
- "@coreui/coreui": "^4.0.5",
54
- "vue": "^3.2.20"
53
+ "@coreui/coreui-pro": "^4.1.0",
54
+ "vue": "^3.2.21"
55
55
  },
56
56
  "standard": {
57
57
  "ignore": [
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`Loads and display CAccordionBody component renders correctly 1`] = `
4
4
  "<transition-stub class=\\"accordion-collapse\\">
5
- <div class=\\"collapse\\" style=\\"display: none;\\">
5
+ <div class=\\"collapse\\">
6
6
  <div class=\\"accordion-body\\">Default slot</div>
7
7
  </div>
8
8
  </transition-stub>"
@@ -91,6 +91,7 @@ export const CButton = defineComponent({
91
91
  ],
92
92
  disabled: props.disabled && props.component !== 'a',
93
93
  ...(props.component === 'a' && props.disabled && { 'aria-disabled': true, tabIndex: -1 }),
94
+ ...(props.component === 'a' && props.href && { href: props.href }),
94
95
  },
95
96
  slots.default && slots.default(),
96
97
  )
@@ -1,8 +1,16 @@
1
- import { defineComponent, h, Transition, withDirectives, vShow, RendererElement } from 'vue'
1
+ import { defineComponent, h, Transition, ref, RendererElement, withDirectives } from 'vue'
2
+ import { vVisible } from '../../directives/v-c-visible'
2
3
 
3
4
  const CCollapse = defineComponent({
4
5
  name: 'CCollapse',
5
6
  props: {
7
+ /**
8
+ * Set horizontal collapsing to transition the width instead of height.
9
+ */
10
+ horizontal: {
11
+ type: Boolean,
12
+ required: false,
13
+ },
6
14
  /**
7
15
  * Toggle the visibility of component.
8
16
  */
@@ -22,46 +30,68 @@ const CCollapse = defineComponent({
22
30
  'show',
23
31
  ],
24
32
  setup(props, { slots, emit }) {
25
- const handleBeforeEnter = (el: RendererElement) => {
26
- el.classList.remove('collapse')
27
- el.classList.add('collapsing')
33
+ const collapsing = ref(false)
34
+ const show = ref(props.visible)
35
+
36
+ const handleBeforeEnter = () => {
37
+ collapsing.value = true
28
38
  }
39
+
29
40
  const handleEnter = (el: RendererElement, done: () => void) => {
30
41
  emit('show')
31
42
  el.addEventListener('transitionend', () => {
32
- el.classList.add('collapse', 'show')
33
43
  done()
34
44
  })
35
- el.style.height = `${el.scrollHeight}px`
45
+ setTimeout(() => {
46
+ if (props.horizontal) {
47
+ el.style.width = `${el.scrollWidth}px`
48
+ return
49
+ }
50
+ el.style.height = `${el.scrollHeight}px`
51
+ }, 1)
36
52
  }
53
+
37
54
  const handleAfterEnter = (el: RendererElement) => {
38
- el.classList.remove('collapsing')
39
- el.style.removeProperty('height')
55
+ show.value = true
56
+ collapsing.value = false
57
+ props.horizontal ? el.style.removeProperty('width') : el.style.removeProperty('height')
40
58
  }
59
+
41
60
  const handleBeforeLeave = (el: RendererElement) => {
42
- el.classList.add('show')
61
+ collapsing.value = true
62
+ show.value = false
63
+ if (props.horizontal) {
64
+ el.style.width = `${el.scrollWidth}px`
65
+ return
66
+ }
43
67
  el.style.height = `${el.scrollHeight}px`
44
68
  }
69
+
45
70
  const handleLeave = (el: RendererElement, done: () => void) => {
46
71
  emit('hide')
47
- el.classList.remove('collapse', 'show')
48
- el.classList.add('collapsing')
49
72
  el.addEventListener('transitionend', () => {
50
73
  done()
51
74
  })
52
- el.style.height = '0px'
75
+ setTimeout(() => {
76
+ if (props.horizontal) {
77
+ el.style.width = '0px'
78
+ return
79
+ }
80
+ el.style.height = '0px'
81
+ }, 1)
53
82
  }
83
+
54
84
  const handleAfterLeave = (el: RendererElement) => {
55
- el.classList.remove('collapsing')
56
- el.classList.add('collapse')
85
+ collapsing.value = false
86
+ props.horizontal ? el.style.removeProperty('width') : el.style.removeProperty('height')
57
87
  }
58
88
 
59
89
  return () =>
60
90
  h(
61
91
  Transition,
62
92
  {
63
- name: 'fade',
64
- onBeforeEnter: (el) => handleBeforeEnter(el),
93
+ css: false,
94
+ onBeforeEnter: () => handleBeforeEnter(),
65
95
  onEnter: (el, done) => handleEnter(el, done),
66
96
  onAfterEnter: (el) => handleAfterEnter(el),
67
97
  onBeforeLeave: (el) => handleBeforeLeave(el),
@@ -74,15 +104,13 @@ const CCollapse = defineComponent({
74
104
  'div',
75
105
  {
76
106
  class: [
77
- 'collapse',
78
- {
79
- show: props.visible,
80
- },
107
+ collapsing.value ? 'collapsing' : 'collapse',
108
+ { 'collapse-horizontal': props.horizontal, show: show.value },
81
109
  ],
82
110
  },
83
111
  slots.default && slots.default(),
84
112
  ),
85
- [[vShow, props.visible]],
113
+ [[vVisible, props.visible]],
86
114
  ),
87
115
  )
88
116
  },
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`Loads and display CCollapse component renders correctly 1`] = `
4
4
  "<transition-stub>
5
- <div class=\\"collapse\\" style=\\"display: none;\\">Default slot</div>
5
+ <div class=\\"collapse\\">Default slot</div>
6
6
  </transition-stub>"
7
7
  `;
8
8
 
@@ -0,0 +1,10 @@
1
+ import { App } from 'vue'
2
+ import { CElementCover } from './CElementCover'
3
+
4
+ const CElementCoverPlugin = {
5
+ install: (app: App): void => {
6
+ app.component(CElementCover.name, CElementCover)
7
+ },
8
+ }
9
+
10
+ export { CElementCoverPlugin, CElementCover }
@@ -1,4 +1,4 @@
1
- import { defineComponent, h, onMounted, watch, ref } from 'vue'
1
+ import { defineComponent, h } from 'vue'
2
2
  import { shape } from 'vue-types'
3
3
 
4
4
  import { Color, Shape } from '../props'
@@ -57,6 +57,10 @@ const CFormCheck = defineComponent({
57
57
  default: undefined,
58
58
  required: false,
59
59
  },
60
+ /**
61
+ * Input Checkbox indeterminate Property
62
+ */
63
+ indeterminate: Boolean,
60
64
  /**
61
65
  * Group checkboxes or radios on the same horizontal row by adding.
62
66
  */
@@ -116,31 +120,15 @@ const CFormCheck = defineComponent({
116
120
  'update:modelValue',
117
121
  ],
118
122
  setup(props, { attrs, emit, slots }) {
119
- const checked = ref(attrs.checked)
120
-
121
- onMounted(() => {
122
- if (props.modelValue && typeof props.modelValue === 'boolean') {
123
- console.log(props.modelValue)
124
- }
125
- })
126
-
127
- watch(
128
- () => props.modelValue,
129
- () => {
130
- if (typeof props.modelValue === 'boolean') checked.value = props.modelValue
131
- },
132
- )
133
-
134
123
  const handleChange = (event: InputEvent) => {
135
124
  const target = event.target as HTMLInputElement
136
- emit('change', target.checked)
125
+ emit('change', event)
137
126
  emit('update:modelValue', target.checked)
138
127
  }
139
128
 
140
129
  const formControl = () => {
141
130
  return h('input', {
142
- ...attrs,
143
- checked: checked.value,
131
+ checked: props.modelValue,
144
132
  class: [
145
133
  props.button ? 'btn-check' : 'form-check-input',
146
134
  {
@@ -149,8 +137,10 @@ const CFormCheck = defineComponent({
149
137
  },
150
138
  ],
151
139
  id: props.id,
140
+ indeterminate: props.indeterminate,
152
141
  onChange: (event: InputEvent) => handleChange(event),
153
142
  type: props.type,
143
+ ...attrs,
154
144
  })
155
145
  }
156
146
  const formLabel = () => {
@@ -87,12 +87,12 @@ const CFormInput = defineComponent({
87
87
  setup(props, { emit, slots }) {
88
88
  const handleChange = (event: InputEvent) => {
89
89
  const target = event.target as HTMLInputElement
90
- emit('change', target.value)
90
+ emit('change', event)
91
91
  emit('update:modelValue', target.value)
92
92
  }
93
93
  const handleInput = (event: InputEvent) => {
94
94
  const target = event.target as HTMLInputElement
95
- emit('input', target.value)
95
+ emit('input', event)
96
96
  emit('update:modelValue', target.value)
97
97
  }
98
98
 
@@ -100,9 +100,6 @@ const CFormInput = defineComponent({
100
100
  h(
101
101
  'input',
102
102
  {
103
- type: props.type,
104
- disabled: props.disabled,
105
- readonly: props.readonly,
106
103
  class: [
107
104
  props.plainText ? 'form-control-plaintext' : 'form-control',
108
105
  {
@@ -112,8 +109,11 @@ const CFormInput = defineComponent({
112
109
  'is-valid': props.valid,
113
110
  },
114
111
  ],
112
+ disabled: props.disabled,
115
113
  onChange: (event: InputEvent) => handleChange(event),
116
114
  onInput: (event: InputEvent) => handleInput(event),
115
+ readonly: props.readonly,
116
+ type: props.type,
117
117
  value: props.modelValue,
118
118
  },
119
119
  slots.default && slots.default(),
@@ -74,7 +74,7 @@ const CFormRange = defineComponent({
74
74
  setup(props, { emit, slots }) {
75
75
  const handleChange = (event: InputEvent) => {
76
76
  const target = event.target as HTMLInputElement
77
- emit('change', target.value)
77
+ emit('change', event)
78
78
  emit('update:modelValue', target.value)
79
79
  }
80
80
 
@@ -90,7 +90,7 @@ const CFormRange = defineComponent({
90
90
  steps: props.steps,
91
91
  readonly: props.readonly,
92
92
  type: 'range',
93
- value: props.modelValue || props.value,
93
+ value: props.modelValue,
94
94
  },
95
95
  slots.default && slots.default(),
96
96
  )
@@ -77,14 +77,11 @@ const CFormSelect = defineComponent({
77
77
  setup(props, { emit, slots }) {
78
78
  const handleChange = (event: InputEvent) => {
79
79
  const target = event.target as HTMLSelectElement
80
-
81
80
  const selected = Array.from(target.options)
82
81
  .filter((option) => option.selected)
83
82
  .map((option) => option.value)
84
-
85
83
  const value = target.multiple ? selected : selected[0]
86
-
87
- emit('change', value)
84
+ emit('change', event)
88
85
  emit('update:modelValue', value)
89
86
  }
90
87
 
@@ -96,6 +93,8 @@ const CFormSelect = defineComponent({
96
93
  'form-select',
97
94
  {
98
95
  [`form-select-${props.size}`]: props.size,
96
+ 'is-invalid': props.invalid,
97
+ 'is-valid': props.valid,
99
98
  },
100
99
  ],
101
100
  onChange: (event: InputEvent) => handleChange(event),
@@ -96,7 +96,7 @@ const CFormSwitch = defineComponent({
96
96
 
97
97
  const handleChange = (event: InputEvent) => {
98
98
  const target = event.target as HTMLInputElement
99
- emit('change', target.checked)
99
+ emit('change', event)
100
100
  emit('update:modelValue', target.checked)
101
101
  }
102
102
 
@@ -62,14 +62,9 @@ const CFormTextarea = defineComponent({
62
62
  'update:modelValue',
63
63
  ],
64
64
  setup(props, { emit, slots }) {
65
- const handleChange = (event: InputEvent) => {
66
- const target = event.target as HTMLInputElement
67
- emit('change', target.value)
68
- emit('update:modelValue', target.value)
69
- }
70
65
  const handleInput = (event: InputEvent) => {
71
66
  const target = event.target as HTMLInputElement
72
- emit('input', target.value)
67
+ emit('input', event)
73
68
  emit('update:modelValue', target.value)
74
69
  }
75
70
 
@@ -86,7 +81,6 @@ const CFormTextarea = defineComponent({
86
81
  'is-valid': props.valid,
87
82
  },
88
83
  ],
89
- onChange: (event: InputEvent) => handleChange(event),
90
84
  onInput: (event: InputEvent) => handleInput(event),
91
85
  value: props.modelValue,
92
86
  },
@@ -1,7 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`Customize (two) CFormInput component renders correctly 1`] = `"<input type=\\"color\\" disabled=\\"\\" readonly=\\"\\" class=\\"form-control form-control-color form-control-lg is-invalid is-valid\\">"`;
3
+ exports[`Customize (two) CFormInput component renders correctly 1`] = `"<input class=\\"form-control form-control-color form-control-lg is-invalid is-valid\\" disabled=\\"\\" readonly=\\"\\" type=\\"color\\">"`;
4
4
 
5
- exports[`Customize CFormInput component renders correctly 1`] = `"<input type=\\"color\\" disabled=\\"\\" readonly=\\"\\" class=\\"form-control-plaintext form-control-color form-control-lg is-invalid is-valid\\">"`;
5
+ exports[`Customize CFormInput component renders correctly 1`] = `"<input class=\\"form-control-plaintext form-control-color form-control-lg is-invalid is-valid\\" disabled=\\"\\" readonly=\\"\\" type=\\"color\\">"`;
6
6
 
7
- exports[`Loads and display CFormInput component renders correctly 1`] = `"<input type=\\"text\\" class=\\"form-control\\">"`;
7
+ exports[`Loads and display CFormInput component renders correctly 1`] = `"<input class=\\"form-control\\" type=\\"text\\">"`;
@@ -84,7 +84,7 @@ const CCol = defineComponent({
84
84
  },
85
85
  },
86
86
  setup(props, { slots }) {
87
- const repsonsiveCLassNames: string[] = []
87
+ const repsonsiveClassNames: string[] = []
88
88
 
89
89
  BREAKPOINTS.forEach((bp) => {
90
90
  const breakpoint = props[bp]
@@ -93,29 +93,29 @@ const CCol = defineComponent({
93
93
 
94
94
  if (breakpoint) {
95
95
  if (typeof breakpoint === 'number' || typeof breakpoint === 'string') {
96
- repsonsiveCLassNames.push(`col${infix}-${breakpoint}`)
96
+ repsonsiveClassNames.push(`col${infix}-${breakpoint}`)
97
97
  }
98
98
 
99
99
  if (typeof breakpoint === 'boolean') {
100
- repsonsiveCLassNames.push(`col${infix}`)
100
+ repsonsiveClassNames.push(`col${infix}`)
101
101
  }
102
102
  }
103
103
 
104
104
  if (breakpoint && typeof breakpoint === 'object') {
105
105
  if (typeof breakpoint.span === 'number' || typeof breakpoint.span === 'string') {
106
- repsonsiveCLassNames.push(`col${infix}-${breakpoint.span}`)
106
+ repsonsiveClassNames.push(`col${infix}-${breakpoint.span}`)
107
107
  }
108
108
 
109
109
  if (typeof breakpoint.span === 'boolean') {
110
- repsonsiveCLassNames.push(`col${infix}`)
110
+ repsonsiveClassNames.push(`col${infix}`)
111
111
  }
112
112
 
113
113
  if (typeof breakpoint.order === 'number' || typeof breakpoint.order === 'string') {
114
- repsonsiveCLassNames.push(`order${infix}-${breakpoint.order}`)
114
+ repsonsiveClassNames.push(`order${infix}-${breakpoint.order}`)
115
115
  }
116
116
 
117
117
  if (typeof breakpoint.offset === 'number') {
118
- repsonsiveCLassNames.push(`offset${infix}-${breakpoint.offset}`)
118
+ repsonsiveClassNames.push(`offset${infix}-${breakpoint.offset}`)
119
119
  }
120
120
  }
121
121
  })
@@ -124,7 +124,7 @@ const CCol = defineComponent({
124
124
  h(
125
125
  'div',
126
126
  {
127
- class: [repsonsiveCLassNames.length ? repsonsiveCLassNames : 'col'],
127
+ class: [repsonsiveClassNames.length ? repsonsiveClassNames : 'col'],
128
128
  },
129
129
  slots.default && slots.default(),
130
130
  )
@@ -56,18 +56,18 @@ const CContainer = defineComponent({
56
56
  },
57
57
  },
58
58
  setup(props, { slots }) {
59
- const repsonsiveCLassNames: string[] = []
59
+ const repsonsiveClassNames: string[] = []
60
60
 
61
61
  BREAKPOINTS.forEach((bp) => {
62
62
  const breakpoint = props[bp]
63
63
 
64
- breakpoint && repsonsiveCLassNames.push(`container-${bp}`)
64
+ breakpoint && repsonsiveClassNames.push(`container-${bp}`)
65
65
  })
66
66
  return () =>
67
67
  h(
68
68
  'div',
69
69
  {
70
- class: [repsonsiveCLassNames.length ? repsonsiveCLassNames : 'container'],
70
+ class: [repsonsiveClassNames.length ? repsonsiveClassNames : 'container'],
71
71
  },
72
72
  slots.default && slots.default(),
73
73
  )
@@ -81,7 +81,7 @@ const CRow = defineComponent({
81
81
  },
82
82
  },
83
83
  setup(props, { slots }) {
84
- const repsonsiveCLassNames: string[] = []
84
+ const repsonsiveClassNames: string[] = []
85
85
 
86
86
  BREAKPOINTS.forEach((bp) => {
87
87
  const breakpoint = props[bp]
@@ -89,16 +89,16 @@ const CRow = defineComponent({
89
89
 
90
90
  if (typeof breakpoint === 'object') {
91
91
  if (breakpoint.cols) {
92
- repsonsiveCLassNames.push(`row-cols${infix}-${breakpoint.cols}`)
92
+ repsonsiveClassNames.push(`row-cols${infix}-${breakpoint.cols}`)
93
93
  }
94
94
  if (typeof breakpoint.gutter === 'number') {
95
- repsonsiveCLassNames.push(`g${infix}-${breakpoint.gutter}`)
95
+ repsonsiveClassNames.push(`g${infix}-${breakpoint.gutter}`)
96
96
  }
97
97
  if (typeof breakpoint.gutterX === 'number') {
98
- repsonsiveCLassNames.push(`gx${infix}-${breakpoint.gutterX}`)
98
+ repsonsiveClassNames.push(`gx${infix}-${breakpoint.gutterX}`)
99
99
  }
100
100
  if (typeof breakpoint.gutterY === 'number') {
101
- repsonsiveCLassNames.push(`gy${infix}-${breakpoint.gutterY}`)
101
+ repsonsiveClassNames.push(`gy${infix}-${breakpoint.gutterY}`)
102
102
  }
103
103
  }
104
104
  })
@@ -107,7 +107,7 @@ const CRow = defineComponent({
107
107
  h(
108
108
  'div',
109
109
  {
110
- class: ['row', repsonsiveCLassNames],
110
+ class: ['row', repsonsiveClassNames],
111
111
  },
112
112
  slots.default && slots.default(),
113
113
  )
@@ -12,6 +12,7 @@ export * from './carousel'
12
12
  export * from './close-button'
13
13
  export * from './collapse'
14
14
  export * from './dropdown'
15
+ export * from './element-cover'
15
16
  export * from './footer'
16
17
  export * from './form'
17
18
  export * from './grid'
@@ -26,6 +27,7 @@ export * from './nav'
26
27
  export * from './navbar'
27
28
  export * from './offcanvas'
28
29
  export * from './pagination'
30
+ export * from './placeholder'
29
31
  export * from './progress'
30
32
  export * from './popover'
31
33
  export * from './sidebar'
@@ -133,7 +133,7 @@ const CModal = defineComponent({
133
133
  emit('show')
134
134
  }
135
135
  const handleAfterEnter = () => {
136
- window.addEventListener('click', handleClickOutside)
136
+ window.addEventListener('mousedown', handleMouseDown)
137
137
  window.addEventListener('keyup', handleKeyUp)
138
138
  }
139
139
  const handleLeave = (el: RendererElement, done: () => void) => {
@@ -144,7 +144,7 @@ const CModal = defineComponent({
144
144
  el.classList.remove('show')
145
145
  }
146
146
  const handleAfterLeave = (el: RendererElement) => {
147
- window.removeEventListener('click', handleClickOutside)
147
+ window.removeEventListener('mousedown', handleMouseDown)
148
148
  window.removeEventListener('keyup', handleKeyUp)
149
149
  el.style.display = 'none'
150
150
  }
@@ -168,7 +168,12 @@ const CModal = defineComponent({
168
168
  }
169
169
  }
170
170
  }
171
- const handleClickOutside = (event: Event) => {
171
+
172
+ const handleMouseDown = (event: Event) => {
173
+ window.addEventListener('mouseup', () => handleMouseUp(event), { once: true })
174
+ }
175
+
176
+ const handleMouseUp = (event: Event) => {
172
177
  if (modalContentRef.value && !modalContentRef.value.contains(event.target as HTMLElement)) {
173
178
  if (props.backdrop !== 'static') {
174
179
  handleDismiss()
@@ -1,5 +1,6 @@
1
- import { defineComponent, h, ref, RendererElement, Transition, watch } from 'vue'
1
+ import { defineComponent, h, ref, RendererElement, Transition, watch, withDirectives } from 'vue'
2
2
  import { CBackdrop } from '../backdrop'
3
+ import { vVisible } from '../../directives/v-c-visible'
3
4
 
4
5
  const COffcanvas = defineComponent({
5
6
  name: 'COffcanvas',
@@ -96,19 +97,20 @@ const COffcanvas = defineComponent({
96
97
  }, 1)
97
98
  }
98
99
  const handleAfterEnter = () => {
99
- window.addEventListener('click', handleClickOutside)
100
+ window.addEventListener('mousedown', handleMouseDown)
101
+ // window.addEventListener('click', handleClickOutside)
100
102
  window.addEventListener('keyup', handleKeyUp)
101
103
  }
102
104
  const handleLeave = (el: RendererElement, done: () => void) => {
103
105
  el.addEventListener('transitionend', () => {
104
106
  done()
105
107
  })
108
+ window.removeEventListener('mousedown', handleMouseDown)
109
+ window.removeEventListener('keyup', handleKeyUp)
106
110
  el.classList.remove('show')
107
111
  }
108
112
  const handleAfterLeave = (el: RendererElement) => {
109
113
  el.style.visibility = 'hidden'
110
- window.removeEventListener('click', handleClickOutside)
111
- window.removeEventListener('keyup', handleKeyUp)
112
114
  }
113
115
 
114
116
  const handleDismiss = () => {
@@ -123,7 +125,12 @@ const COffcanvas = defineComponent({
123
125
  }
124
126
  }
125
127
  }
126
- const handleClickOutside = (event: Event) => {
128
+
129
+ const handleMouseDown = (event: Event) => {
130
+ window.addEventListener('mouseup', () => handleMouseUp(event), { once: true })
131
+ }
132
+
133
+ const handleMouseUp = (event: Event) => {
127
134
  if (offcanvasRef.value && !offcanvasRef.value.contains(event.target as HTMLElement)) {
128
135
  props.backdrop && handleDismiss()
129
136
  }
@@ -133,31 +140,34 @@ const COffcanvas = defineComponent({
133
140
  h(
134
141
  Transition,
135
142
  {
143
+ css: false,
136
144
  onEnter: (el, done) => handleEnter(el, done),
137
145
  onAfterEnter: () => handleAfterEnter(),
138
146
  onLeave: (el, done) => handleLeave(el, done),
139
147
  onAfterLeave: (el) => handleAfterLeave(el),
140
148
  },
141
149
  () =>
142
- visible.value &&
143
- h(
144
- 'div',
145
- {
146
- class: [
147
- 'offcanvas',
148
- {
149
- [`offcanvas-${props.placement}`]: props.placement,
150
- },
151
- ],
152
- ref: offcanvasRef,
153
- role: 'dialog',
154
- },
155
- slots.default && slots.default(),
150
+ withDirectives(
151
+ h(
152
+ 'div',
153
+ {
154
+ class: [
155
+ 'offcanvas',
156
+ {
157
+ [`offcanvas-${props.placement}`]: props.placement,
158
+ },
159
+ ],
160
+ ref: offcanvasRef,
161
+ role: 'dialog',
162
+ },
163
+ slots.default && slots.default(),
164
+ ),
165
+ [[vVisible, props.visible]],
156
166
  ),
157
167
  ),
158
168
  props.backdrop &&
159
169
  h(CBackdrop, {
160
- class: 'modal-backdrop',
170
+ class: 'offcanvas-backdrop',
161
171
  visible: visible.value,
162
172
  }),
163
173
  ]
@@ -47,6 +47,6 @@ describe(`Customize ${ComponentName} component`, () => {
47
47
  expect(customWrapper.text()).toContain('Default slot')
48
48
  expect(customWrapper.find('div').classes('offcanvas')).toBe(true)
49
49
  expect(customWrapper.find('div').classes('offcanvas-bottom')).toBe(true)
50
- expect(customWrapper.find('.modal-backdrop').classes('modal-backdrop')).toBe(true)
50
+ expect(customWrapper.find('.offcanvas-backdrop').classes('offcanvas-backdrop')).toBe(true)
51
51
  })
52
52
  })