@@ -9,61 +9,64 @@ This component is made to be used inside of the [NcActions](#NcActions) componen
99```vue
1010<template>
1111 <NcActions>
12- <NcActionCheckbox @change="alert ('(un)checked !')">First choice</NcActionCheckbox>
13- <NcActionCheckbox v-model="checkboxValue" value="second" @change="alert ('(un)checked !')">Second choice (v-model) </NcActionCheckbox>
14- <NcActionCheckbox :model-value ="checkboxValue" @change="alert ('(un)checked !')">Third choice (checked)</NcActionCheckbox>
15- <NcActionCheckbox :disabled="true" @change="alert ('(un)checked !')">Fourth choice (disabled)</NcActionCheckbox>
12+ <NcActionCheckbox @change="log ('(un)checked !')">First choice</NcActionCheckbox>
13+ <NcActionCheckbox value="second" @change="log ('(un)checked !')">Second choice</NcActionCheckbox>
14+ <NcActionCheckbox v-model ="checkboxValue" @change="log ('(un)checked !')">Third choice (checked)</NcActionCheckbox>
15+ <NcActionCheckbox :disabled="true" @change="log ('(un)checked !')">Second choice (disabled)</NcActionCheckbox>
1616 </NcActions>
1717</template>
1818
1919<script>
2020export default {
2121 data() {
2222 return {
23- checkboxValue: false ,
23+ checkboxValue: true ,
2424 }
2525 },
2626
2727 methods: {
28- alert(message) {
29- alert(message)
30- }
31- }
28+ log: console.log,
29+ },
3230}
3331</script>
3432```
3533</docs >
3634
3735<template >
3836 <li class =" action" :class =" { 'action--disabled': disabled }" :role =" isInSemanticMenu && 'presentation'" >
39- <span class =" action-checkbox" :role =" isInSemanticMenu && 'menuitemcheckbox'" :aria-checked =" ariaChecked" >
40- <input
41- :id =" id"
42- ref =" checkbox"
43- :disabled =" disabled"
44- :checked =" model"
45- :value =" value"
46- :class =" { focusable: isFocusable }"
47- type =" checkbox"
48- class =" checkbox action-checkbox__checkbox"
49- @keydown.enter.exact.prevent =" checkInput"
50- @change =" onChange" >
51- <label ref =" label" :for =" id" class =" action-checkbox__label" >{{ text }}</label >
52-
53- <!-- fake slot to gather inner text -->
54- <slot v-if =" false" />
55- </span >
37+ <label class =" action-checkbox" :role =" isInSemanticMenu && 'menuitemcheckbox'" :aria-checked =" isInSemanticMenu && localModel.toString()" >
38+ <span class =" action-checkbox__icon" >
39+ <input
40+ :id =" id"
41+ v-model =" localModel"
42+ type =" checkbox"
43+ class =" action-checkbox__input"
44+ :class =" { focusable: !disabled }"
45+ :value =" value"
46+ :disabled =" disabled"
47+ @change =" onChange" >
48+ <NcIconSvgWrapper :path =" localModel ? mdiCheckboxMarked : mdiCheckboxBlankOutline" :size =" 20" />
49+ </span >
50+ <span class =" action-checkbox__text" >{{ text }}</span >
51+ </label >
5652 </li >
5753</template >
5854
5955<script >
56+ import { mdiCheckboxBlankOutline , mdiCheckboxMarked } from ' @mdi/js'
57+ import { ref , watch } from ' vue'
58+ import NcIconSvgWrapper from ' ../NcIconSvgWrapper/NcIconSvgWrapper.vue'
6059import { useModelMigration } from ' ../../composables/useModelMigration.ts'
6160import ActionGlobalMixin from ' ../../mixins/actionGlobal.js'
6261import GenRandomId from ' ../../utils/GenRandomId.js'
6362
6463export default {
6564 name: ' NcActionCheckbox' ,
6665
66+ components: {
67+ NcIconSvgWrapper,
68+ },
69+
6770 mixins: [ActionGlobalMixin],
6871
6972 inject: {
@@ -125,8 +128,11 @@ export default {
125128 },
126129
127130 emits: [
131+ /** Native change event */
128132 ' change' ,
133+ /** Checkbox is checked */
129134 ' check' ,
135+ /** Checkbox is unchecked */
130136 ' uncheck' ,
131137 /**
132138 * Removed in v9 - use `update:modelValue` (`v-model`) instead
@@ -146,63 +152,25 @@ export default {
146152
147153 setup () {
148154 const model = useModelMigration (' checked' , ' update:checked' )
149- return {
150- model,
151- }
152- },
153155
154- computed: {
155- /**
156- * determines if the action is focusable
157- *
158- * @return {boolean} is the action focusable ?
159- */
160- isFocusable () {
161- return ! this .disabled
162- },
156+ // For backward compatibility to support using without v-model binding (passive model)
157+ const localModel = ref (model .value )
158+ watch (model, (newValue ) => (localModel .value = newValue), { flush: ' sync' })
159+ watch (localModel, (newValue ) => (model .value = newValue), { flush: ' sync' })
163160
164- /**
165- * aria-checked attribute for role="menuitemcheckbox"
166- *
167- * @return {'true'|'false'|undefined} aria-checked value if needed
168- */
169- ariaChecked () {
170- if (this .isInSemanticMenu ) {
171- return this .model ? ' true' : ' false'
172- }
173- return undefined
174- },
161+ return {
162+ localModel,
163+ mdiCheckboxBlankOutline,
164+ mdiCheckboxMarked,
165+ }
175166 },
176167
177168 methods: {
178- checkInput () {
179- // by clicking we also trigger the change event
180- this .$refs .label .click ()
181- },
182-
183169 onChange (event ) {
184- this .model = this .$refs .checkbox .checked
185-
186- /**
187- * Emitted when the checkbox state is changed
188- *
189- * @type {Event}
190- */
191170 this .$emit (' change' , event )
192-
193- if (this .$refs .checkbox .checked ) {
194- /**
195- * Emitted when the checkbox is checked
196- *
197- * @type {Event}
198- */
171+ if (event .target .checked ) {
199172 this .$emit (' check' )
200173 } else {
201- /**
202- * Emitted when the checkbox is unchecked
203- *
204- * @type {Event}
205- */
206174 this .$emit (' uncheck' )
207175 }
208176 },
@@ -214,56 +182,24 @@ export default {
214182@use ' ../../assets/action.scss' as * ;
215183@include action-active ;
216184@include action--disabled ;
185+ @include action-item (' checkbox' );
217186
218- .action-checkbox {
219- display : flex ;
220- align-items : flex-start ;
221-
222- width : 100% ;
223- height : auto ;
224- margin : 0 ;
225- padding : 0 ;
226-
227- cursor : pointer ;
228- white-space : nowrap ;
229-
230- color : var (--color-main-text );
231- border : 0 ;
232- border-radius : 0 ; // otherwise Safari will cut the border-radius area
233- background-color : transparent ;
234- box-shadow : none ;
187+ .action :has (:focus-visible ) {
188+ outline : 2px solid currentColor ;
189+ }
235190
236- font-weight : normal ;
237- line-height : var (--default-clickable-area );
191+ .action-checkbox {
192+ & __icon {
193+ color : var (--color-primary-element );
194+ }
238195
239- /* checkbox/radio fixes */
240- & __checkbox {
196+ & __input {
197+ width : 20px ;
198+ height : 20px ;
199+ margin : auto ;
241200 position : absolute ;
242- inset-inline-start : 0 !important ;
243201 z-index : -1 ;
244- opacity : 0 ;
245- }
246-
247- & __label {
248- display : flex ;
249- align-items : center ; // align checkbox to text
250-
251- width : 100% ;
252- padding : 0 !important ;
253- padding-inline-end : $icon-margin !important ;
254-
255- & ::before {
256- margin-block : 0 !important ;
257- margin-inline : calc ((var (--default-clickable-area ) - 14px ) / 2 ) !important ;
258- }
259- }
260-
261- & --disabled {
262- & ,
263- .action-checkbox__label {
264- cursor : pointer ;
265- }
202+ opacity : 0 !important ;
266203 }
267204}
268-
269205 </style >
0 commit comments