@coreui/vue-pro 4.0.1 → 4.1.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 (68) 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 +22 -2
  6. package/dist/components/form/CFormInput.d.ts +17 -2
  7. package/dist/components/form/CFormRange.d.ts +15 -2
  8. package/dist/components/form/CFormSelect.d.ts +36 -2
  9. package/dist/components/form/CFormSwitch.d.ts +15 -2
  10. package/dist/components/form/CFormTextarea.d.ts +18 -2
  11. package/dist/components/index.d.ts +2 -0
  12. package/dist/components/modal/CModal.d.ts +2 -2
  13. package/dist/components/multi-select/CMultiSelect.d.ts +2 -2
  14. package/dist/components/multi-select/CMultiSelectNativeSelect.d.ts +2 -2
  15. package/dist/components/placeholder/CPlaceholder.d.ts +124 -0
  16. package/dist/components/placeholder/index.d.ts +6 -0
  17. package/dist/components/popover/CPopover.d.ts +2 -2
  18. package/dist/components/smart-table/CSmartTable.d.ts +0 -3
  19. package/dist/components/table/CTable.d.ts +2 -2
  20. package/dist/components/widgets/CWidgetStatsB.d.ts +2 -2
  21. package/dist/components/widgets/CWidgetStatsF.d.ts +2 -2
  22. package/dist/directives/index.d.ts +3 -2
  23. package/dist/directives/v-c-placeholder.d.ts +6 -0
  24. package/dist/directives/v-c-visible.d.ts +6 -0
  25. package/dist/index.es.js +902 -445
  26. package/dist/index.es.js.map +1 -1
  27. package/dist/index.js +905 -443
  28. package/dist/index.js.map +1 -1
  29. package/package.json +10 -9
  30. package/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.ts.snap +1 -1
  31. package/src/components/button/CButton.ts +2 -2
  32. package/src/components/card/CCardImage.ts +2 -3
  33. package/src/components/collapse/CCollapse.ts +49 -21
  34. package/src/components/collapse/__test__/__snapshots__/CCollapse.spec.ts.snap +1 -1
  35. package/src/components/element-cover/index.ts +10 -0
  36. package/src/components/form/CFormCheck.ts +34 -2
  37. package/src/components/form/CFormInput.ts +40 -5
  38. package/src/components/form/CFormLabel.ts +1 -2
  39. package/src/components/form/CFormRange.ts +32 -3
  40. package/src/components/form/CFormSelect.ts +63 -4
  41. package/src/components/form/CFormSwitch.ts +46 -4
  42. package/src/components/form/CFormTextarea.ts +31 -2
  43. package/src/components/form/__tests__/__snapshots__/CFormCheck.spec.ts.snap +2 -2
  44. package/src/components/form/__tests__/__snapshots__/CFormInput.spec.ts.snap +3 -3
  45. package/src/components/form/__tests__/__snapshots__/CFormRange.spec.ts.snap +1 -1
  46. package/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.ts.snap +2 -2
  47. package/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.ts.snap +1 -1
  48. package/src/components/grid/CCol.ts +8 -8
  49. package/src/components/grid/CContainer.ts +3 -3
  50. package/src/components/grid/CRow.ts +6 -6
  51. package/src/components/index.ts +2 -0
  52. package/src/components/offcanvas/COffcanvas.ts +19 -16
  53. package/src/components/offcanvas/__tests__/COffcanvas.spec.ts +1 -1
  54. package/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.ts.snap +2 -2
  55. package/src/components/pagination/CSmartPagination.ts +1 -1
  56. package/src/components/placeholder/CPlaceholder.ts +139 -0
  57. package/src/components/placeholder/__tests__/CPlaceholder.spec.ts +44 -0
  58. package/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.ts.snap +15 -0
  59. package/src/components/placeholder/index.ts +10 -0
  60. package/src/components/smart-table/CSmartTable.ts +56 -41
  61. package/src/components/smart-table/CSmartTableHead.ts +43 -42
  62. package/src/components/toast/CToastClose.ts +2 -2
  63. package/src/components/toast/__tests__/CToastClose.spec.ts +2 -2
  64. package/src/components/toast/__tests__/__snapshots__/CToastClose.spec.ts.snap +1 -1
  65. package/src/directives/index.ts +3 -2
  66. package/src/directives/v-c-placeholder.ts +32 -0
  67. package/src/directives/v-c-visible.ts +33 -0
  68. 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.1",
3
+ "version": "4.1.0",
4
4
  "description": "UI Components Library for Vue.js",
5
5
  "keywords": [
6
6
  "vue",
@@ -31,26 +31,27 @@
31
31
  "src/"
32
32
  ],
33
33
  "scripts": {
34
- "build": "rollup -c"
34
+ "build": "rollup -c",
35
+ "watch": "rollup -c -w"
35
36
  },
36
37
  "config": {
37
- "version_short": "4.0"
38
+ "version_short": "4.1"
38
39
  },
39
40
  "devDependencies": {
40
- "@popperjs/core": "^2.10.2",
41
+ "@popperjs/core": "^2.11.0",
41
42
  "@rollup/plugin-commonjs": "^21.0.1",
42
43
  "@rollup/plugin-node-resolve": "^13.0.6",
43
44
  "@rollup/plugin-typescript": "^8.3.0",
44
45
  "@vue/test-utils": "^2.0.0-0",
45
- "rollup": "^2.58.3",
46
+ "rollup": "^2.60.1",
46
47
  "rollup-plugin-vue": "^6.0.0",
47
- "typescript": "^4.4.4",
48
- "vue": "^3.2.20",
48
+ "typescript": "^4.5.2",
49
+ "vue": "^3.2.23",
49
50
  "vue-types": "^4.1.1"
50
51
  },
51
52
  "peerDependencies": {
52
- "@coreui/coreui": "^4.0.5",
53
- "vue": "^3.2.20"
53
+ "@coreui/coreui": "^4.1.0",
54
+ "vue": "^3.2.21"
54
55
  },
55
56
  "standard": {
56
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>"
@@ -74,12 +74,11 @@ export const CButton = defineComponent({
74
74
  },
75
75
  },
76
76
  },
77
- setup(props, { slots, attrs }) {
77
+ setup(props, { slots }) {
78
78
  return () =>
79
79
  h(
80
80
  props.component,
81
81
  {
82
- ...attrs,
83
82
  class: [
84
83
  'btn',
85
84
  props.variant ? `btn-${props.variant}-${props.color}` : `btn-${props.color}`,
@@ -92,6 +91,7 @@ export const CButton = defineComponent({
92
91
  ],
93
92
  disabled: props.disabled && props.component !== 'a',
94
93
  ...(props.component === 'a' && props.disabled && { 'aria-disabled': true, tabIndex: -1 }),
94
+ ...(props.component === 'a' && props.href && { href: props.href }),
95
95
  },
96
96
  slots.default && slots.default(),
97
97
  )
@@ -25,13 +25,12 @@ const CCardImage = defineComponent({
25
25
  },
26
26
  },
27
27
  },
28
- setup(props, { slots, attrs }) {
28
+ setup(props, { slots }) {
29
29
  return () =>
30
30
  h(
31
31
  props.component,
32
32
  {
33
- ...attrs,
34
- class: [props.orientation ? `card-img-${props.orientation}` : 'card-img'],
33
+ class: `card-img${props.orientation ? `-${props.orientation}` : ''}`,
35
34
  },
36
35
  slots.default && slots.default(),
37
36
  )
@@ -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 }
@@ -6,6 +6,7 @@ import { CFormLabel } from './CFormLabel'
6
6
 
7
7
  const CFormCheck = defineComponent({
8
8
  name: 'CFormCheck',
9
+ inheritAttrs: false,
9
10
  props: {
10
11
  /**
11
12
  * Create button-like checkboxes and radio buttons.
@@ -56,6 +57,10 @@ const CFormCheck = defineComponent({
56
57
  default: undefined,
57
58
  required: false,
58
59
  },
60
+ /**
61
+ * Input Checkbox indeterminate Property
62
+ */
63
+ indeterminate: Boolean,
59
64
  /**
60
65
  * Group checkboxes or radios on the same horizontal row by adding.
61
66
  */
@@ -78,6 +83,14 @@ const CFormCheck = defineComponent({
78
83
  default: undefined,
79
84
  required: false,
80
85
  },
86
+ /**
87
+ * The default name for a value passed using v-model.
88
+ */
89
+ modelValue: {
90
+ type: [Boolean, String],
91
+ value: undefined,
92
+ required: false,
93
+ },
81
94
  /**
82
95
  * Specifies the type of component.
83
96
  *
@@ -96,10 +109,26 @@ const CFormCheck = defineComponent({
96
109
  required: false,
97
110
  },
98
111
  },
99
- setup(props, { slots, attrs }) {
112
+ emits: [
113
+ /**
114
+ * Event occurs when the checked value has been changed.
115
+ */
116
+ 'change',
117
+ /**
118
+ * Emit the new value whenever there’s a change event.
119
+ */
120
+ 'update:modelValue',
121
+ ],
122
+ setup(props, { attrs, emit, slots }) {
123
+ const handleChange = (event: InputEvent) => {
124
+ const target = event.target as HTMLInputElement
125
+ emit('change', event)
126
+ emit('update:modelValue', target.checked)
127
+ }
128
+
100
129
  const formControl = () => {
101
130
  return h('input', {
102
- ...attrs,
131
+ checked: props.modelValue,
103
132
  class: [
104
133
  props.button ? 'btn-check' : 'form-check-input',
105
134
  {
@@ -108,7 +137,10 @@ const CFormCheck = defineComponent({
108
137
  },
109
138
  ],
110
139
  id: props.id,
140
+ indeterminate: props.indeterminate,
141
+ onChange: (event: InputEvent) => handleChange(event),
111
142
  type: props.type,
143
+ ...attrs,
112
144
  })
113
145
  }
114
146
  const formLabel = () => {
@@ -17,6 +17,14 @@ const CFormInput = defineComponent({
17
17
  type: Boolean,
18
18
  required: false,
19
19
  },
20
+ /**
21
+ * The default name for a value passed using v-model.
22
+ */
23
+ modelValue: {
24
+ type: String,
25
+ default: undefined,
26
+ require: false,
27
+ },
20
28
  /**
21
29
  * Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`.
22
30
  */
@@ -62,15 +70,36 @@ const CFormInput = defineComponent({
62
70
  required: false,
63
71
  },
64
72
  },
65
- setup(props, { attrs, slots }) {
73
+ emits: [
74
+ /**
75
+ * Event occurs when the element loses focus, after the content has been changed.
76
+ */
77
+ 'change',
78
+ /**
79
+ * Event occurs immediately after the value of a component has changed.
80
+ */
81
+ 'input',
82
+ /**
83
+ * Emit the new value whenever there’s an input or change event.
84
+ */
85
+ 'update:modelValue',
86
+ ],
87
+ setup(props, { emit, slots }) {
88
+ const handleChange = (event: InputEvent) => {
89
+ const target = event.target as HTMLInputElement
90
+ emit('change', event)
91
+ emit('update:modelValue', target.value)
92
+ }
93
+ const handleInput = (event: InputEvent) => {
94
+ const target = event.target as HTMLInputElement
95
+ emit('input', event)
96
+ emit('update:modelValue', target.value)
97
+ }
98
+
66
99
  return () =>
67
100
  h(
68
101
  'input',
69
102
  {
70
- type: props.type,
71
- disabled: props.disabled,
72
- readonly: props.readonly,
73
- ...attrs,
74
103
  class: [
75
104
  props.plainText ? 'form-control-plaintext' : 'form-control',
76
105
  {
@@ -80,6 +109,12 @@ const CFormInput = defineComponent({
80
109
  'is-valid': props.valid,
81
110
  },
82
111
  ],
112
+ disabled: props.disabled,
113
+ onChange: (event: InputEvent) => handleChange(event),
114
+ onInput: (event: InputEvent) => handleInput(event),
115
+ readonly: props.readonly,
116
+ type: props.type,
117
+ value: props.modelValue,
83
118
  },
84
119
  slots.default && slots.default(),
85
120
  )
@@ -12,12 +12,11 @@ const CFormLabel = defineComponent({
12
12
  required: false,
13
13
  },
14
14
  },
15
- setup(props, { attrs, slots }) {
15
+ setup(props, { slots }) {
16
16
  return () =>
17
17
  h(
18
18
  'label',
19
19
  {
20
- ...attrs,
21
20
  class: props.customClassName ? props.customClassName : 'form-label',
22
21
  },
23
22
  slots.default && slots.default(),
@@ -27,6 +27,14 @@ const CFormRange = defineComponent({
27
27
  default: undefined,
28
28
  required: false,
29
29
  },
30
+ /**
31
+ * The default name for a value passed using v-model.
32
+ */
33
+ modelValue: {
34
+ type: String,
35
+ value: undefined,
36
+ required: false,
37
+ },
30
38
  /**
31
39
  * Toggle the readonly state for the component.
32
40
  */
@@ -53,15 +61,36 @@ const CFormRange = defineComponent({
53
61
  required: false,
54
62
  },
55
63
  },
56
- setup(props, { attrs, slots }) {
64
+ emits: [
65
+ /**
66
+ * Event occurs when the value has been changed.
67
+ */
68
+ 'change',
69
+ /**
70
+ * Emit the new value whenever there’s a change event.
71
+ */
72
+ 'update:modelValue',
73
+ ],
74
+ setup(props, { emit, slots }) {
75
+ const handleChange = (event: InputEvent) => {
76
+ const target = event.target as HTMLInputElement
77
+ emit('change', event)
78
+ emit('update:modelValue', target.value)
79
+ }
80
+
57
81
  return () =>
58
82
  h(
59
83
  'input',
60
84
  {
61
85
  class: 'form-range',
86
+ disabled: props.disabled,
87
+ max: props.max,
88
+ min: props.min,
89
+ onChange: (event: InputEvent) => handleChange(event),
90
+ steps: props.steps,
91
+ readonly: props.readonly,
62
92
  type: 'range',
63
- ...attrs,
64
- ...props,
93
+ value: props.modelValue,
65
94
  },
66
95
  slots.default && slots.default(),
67
96
  )
@@ -1,4 +1,10 @@
1
- import { defineComponent, h } from 'vue'
1
+ import { defineComponent, h, PropType } from 'vue'
2
+
3
+ type Option = {
4
+ disabled?: boolean
5
+ label?: string
6
+ value?: string
7
+ }
2
8
 
3
9
  const CFormSelect = defineComponent({
4
10
  name: 'CFormSelect',
@@ -18,6 +24,25 @@ const CFormSelect = defineComponent({
18
24
  type: Boolean,
19
25
  required: false,
20
26
  },
27
+ /**
28
+ * The default name for a value passed using v-model.
29
+ */
30
+ modelValue: {
31
+ type: String,
32
+ default: undefined,
33
+ require: false,
34
+ },
35
+ /**
36
+ * Options list of the select component. Available keys: `label`, `value`, `disabled`.
37
+ * Examples:
38
+ * - `:options="[{ value: 'js', label: 'JavaScript' }, { value: 'html', label: 'HTML', disabled: true }]"`
39
+ * - `:options="['js', 'html']"`
40
+ */
41
+ options: {
42
+ type: Array as PropType<Option[] | string[]>,
43
+ default: undefined,
44
+ required: false,
45
+ },
21
46
  /**
22
47
  * Size the component small or large.
23
48
  *
@@ -39,21 +64,55 @@ const CFormSelect = defineComponent({
39
64
  required: false,
40
65
  },
41
66
  },
42
- setup(props, { attrs, slots }) {
67
+ emits: [
68
+ /**
69
+ * Event occurs when when a user changes the selected option of a `<select>` element.
70
+ */
71
+ 'change',
72
+ /**
73
+ * Emit the new value whenever there’s a change event.
74
+ */
75
+ 'update:modelValue',
76
+ ],
77
+ setup(props, { emit, slots }) {
78
+ const handleChange = (event: InputEvent) => {
79
+ const target = event.target as HTMLSelectElement
80
+ const selected = Array.from(target.options)
81
+ .filter((option) => option.selected)
82
+ .map((option) => option.value)
83
+ const value = target.multiple ? selected : selected[0]
84
+ emit('change', event)
85
+ emit('update:modelValue', value)
86
+ }
87
+
43
88
  return () =>
44
89
  h(
45
90
  'select',
46
91
  {
47
- ...attrs,
48
92
  class: [
49
93
  'form-select',
50
94
  {
51
95
  [`form-select-${props.size}`]: props.size,
96
+ 'is-invalid': props.invalid,
97
+ 'is-valid': props.valid,
52
98
  },
53
99
  ],
100
+ onChange: (event: InputEvent) => handleChange(event),
54
101
  size: props.htmlSize,
55
102
  },
56
- slots.default && slots.default(),
103
+ props.options
104
+ ? props.options.map((option: Option | string) => {
105
+ return h(
106
+ 'option',
107
+ {
108
+ ...(typeof option === 'object' &&
109
+ option.disabled && { disabled: option.disabled }),
110
+ ...(typeof option === 'object' && option.value && { value: option.value }),
111
+ },
112
+ typeof option === 'string' ? option : option.label,
113
+ )
114
+ })
115
+ : slots.default && slots.default(),
57
116
  )
58
117
  },
59
118
  })
@@ -1,9 +1,10 @@
1
- import { defineComponent, h } from 'vue'
1
+ import { defineComponent, h, onMounted, watch, ref } from 'vue'
2
2
 
3
3
  import { CFormLabel } from './CFormLabel'
4
4
 
5
5
  const CFormSwitch = defineComponent({
6
6
  name: 'CFormSwitch',
7
+ inheritAttrs: false,
7
8
  props: {
8
9
  /**
9
10
  * The id global attribute defines an identifier (ID) that must be unique in the whole document
@@ -28,6 +29,14 @@ const CFormSwitch = defineComponent({
28
29
  default: undefined,
29
30
  required: false,
30
31
  },
32
+ /**
33
+ * The default name for a value passed using v-model.
34
+ */
35
+ modelValue: {
36
+ type: [Boolean, String],
37
+ value: undefined,
38
+ required: false,
39
+ },
31
40
  /**
32
41
  * Size the component large or extra large. Works only with `switch`.
33
42
  *
@@ -59,7 +68,38 @@ const CFormSwitch = defineComponent({
59
68
  required: false,
60
69
  },
61
70
  },
62
- setup(props, { attrs }) {
71
+ emits: [
72
+ /**
73
+ * Event occurs when the checked value has been changed.
74
+ */
75
+ 'change',
76
+ /**
77
+ * Emit the new value whenever there’s a change event.
78
+ */
79
+ 'update:modelValue',
80
+ ],
81
+ setup(props, { attrs, emit }) {
82
+ const checked = ref(attrs.checked)
83
+
84
+ onMounted(() => {
85
+ if (props.modelValue && typeof props.modelValue === 'boolean') {
86
+ console.log(props.modelValue)
87
+ }
88
+ })
89
+
90
+ watch(
91
+ () => props.modelValue,
92
+ () => {
93
+ if (typeof props.modelValue === 'boolean') checked.value = props.modelValue
94
+ },
95
+ )
96
+
97
+ const handleChange = (event: InputEvent) => {
98
+ const target = event.target as HTMLInputElement
99
+ emit('change', event)
100
+ emit('update:modelValue', target.checked)
101
+ }
102
+
63
103
  return () =>
64
104
  h(
65
105
  'div',
@@ -76,8 +116,7 @@ const CFormSwitch = defineComponent({
76
116
  [
77
117
  h('input', {
78
118
  ...attrs,
79
- id: props.id,
80
- type: props.type,
119
+ checked: checked.value,
81
120
  class: [
82
121
  'form-check-input',
83
122
  {
@@ -85,6 +124,9 @@ const CFormSwitch = defineComponent({
85
124
  'is-valid': props.valid,
86
125
  },
87
126
  ],
127
+ id: props.id,
128
+ onChange: (event: InputEvent) => handleChange(event),
129
+ type: props.type,
88
130
  }),
89
131
  props.label &&
90
132
  h(
@@ -17,6 +17,14 @@ const CFormTextarea = defineComponent({
17
17
  type: Boolean,
18
18
  required: false,
19
19
  },
20
+ /**
21
+ * The default name for a value passed using v-model.
22
+ */
23
+ modelValue: {
24
+ type: String,
25
+ default: undefined,
26
+ require: false,
27
+ },
20
28
  /**
21
29
  * Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`.
22
30
  */
@@ -39,12 +47,31 @@ const CFormTextarea = defineComponent({
39
47
  required: false,
40
48
  },
41
49
  },
42
- setup(props, { attrs, slots }) {
50
+ emits: [
51
+ /**
52
+ * Event occurs when the element loses focus, after the content has been changed.
53
+ */
54
+ 'change',
55
+ /**
56
+ * Event occurs immediately after the value of a component has changed.
57
+ */
58
+ 'input',
59
+ /**
60
+ * Emit the new value whenever there’s an input or change event.
61
+ */
62
+ 'update:modelValue',
63
+ ],
64
+ setup(props, { emit, slots }) {
65
+ const handleInput = (event: InputEvent) => {
66
+ const target = event.target as HTMLInputElement
67
+ emit('input', event)
68
+ emit('update:modelValue', target.value)
69
+ }
70
+
43
71
  return () =>
44
72
  h(
45
73
  'textarea',
46
74
  {
47
- ...attrs,
48
75
  disabled: props.disabled,
49
76
  readonly: props.readonly,
50
77
  class: [
@@ -54,6 +81,8 @@ const CFormTextarea = defineComponent({
54
81
  'is-valid': props.valid,
55
82
  },
56
83
  ],
84
+ onInput: (event: InputEvent) => handleInput(event),
85
+ value: props.modelValue,
57
86
  },
58
87
  slots.default && slots.default(),
59
88
  )