1
1
import { createProvideScope } from '@oku-ui/provide'
2
2
import type { PropType , Ref } from 'vue'
3
- import { Transition , computed , defineComponent , h , onMounted , ref , watchEffect } from 'vue'
3
+ import { Transition , defineComponent , h , onMounted , ref , toRefs , watch , watchEffect } from 'vue'
4
4
5
5
import { composeEventHandlers } from '@oku-ui/utils'
6
- import { useControllableRef , usePrevious , useSize } from '@oku-ui/use-composable'
6
+ import { useControllableRef , usePrevious , useRef , useSize } from '@oku-ui/use-composable'
7
7
import { Primitive } from '@oku-ui/primitive'
8
8
9
- // import { useComposedRefs } from '@oku-ui/compose-refs'
10
9
import type { ElementType , MergeProps , PrimitiveProps , RefElement } from '@oku-ui/primitive'
11
10
12
11
import type { Scope } from '@oku-ui/provide'
@@ -121,26 +120,30 @@ const Checkbox = defineComponent({
121
120
props : {
122
121
checked : {
123
122
type : [ Boolean , 'indeterminate' ] as PropType < boolean | 'indeterminate' > ,
124
- default : false ,
123
+ default : undefined ,
125
124
} ,
126
125
defaultChecked : {
127
126
type : [ Boolean , 'indeterminate' ] as PropType < boolean | 'indeterminate' > ,
128
- default : false ,
127
+ default : undefined ,
128
+ } ,
129
+ required : {
130
+ type : Boolean ,
131
+ default : undefined ,
129
132
} ,
130
- required : Boolean ,
131
133
onCheckedChange : Function as PropType < ( checked : CheckedState ) => void > ,
132
134
scopeCheckbox : {
133
135
type : Object as unknown as PropType < Scope > ,
134
136
required : false ,
137
+ default : undefined ,
135
138
} ,
136
139
} ,
137
140
setup ( props , { attrs, slots, expose } ) {
138
- const { checked : checkedProp , scopeCheckbox, defaultChecked, onCheckedChange, required } = props
139
- const innerRef = ref ( )
140
- const _innerRef = computed ( ( ) => innerRef . value ?. $el )
141
+ const { checked : checkedProp , scopeCheckbox, defaultChecked, onCheckedChange, required } = toRefs ( props )
142
+
143
+ const { _ref : buttonRef , refEl : buttonRefEl } = useRef < HTMLButtonElement > ( )
141
144
142
145
expose ( {
143
- innerRef : _innerRef ,
146
+ innerRef : buttonRefEl ,
144
147
} )
145
148
146
149
const {
@@ -150,60 +153,55 @@ const Checkbox = defineComponent({
150
153
...checkboxProps
151
154
} = attrs as CheckboxElement
152
155
153
- const _button = computed < HTMLButtonElement > ( ( ) => _innerRef . value )
154
- // const button = ref<HTMLButtonElement>()
155
- // TODO: Change the useComposedRefs structure here if necessary (https://github.com/radix-ui/primitives/blob/c3f2189034e690e9fb564d484733144fdcbc02d7/packages/react/checkbox/src/Checkbox.tsx#L56)
156
- // const composedRefs = useComposedRefs(innerRef, button)
157
-
158
156
const hasConsumerStoppedPropagationRef = ref ( false )
159
157
160
- const isFormControl = _button . value ? Boolean ( _button . value . closest ( 'form' ) ) : true
161
- const [ checked , setChecked ] = useControllableRef ( {
162
- prop : checkedProp ,
163
- defaultProp : defaultChecked ,
164
- onChange : onCheckedChange ,
158
+ const isFormControl = buttonRefEl . value ? Boolean ( buttonRefEl . value . closest ( 'form' ) ) : true
159
+ const { state } = useControllableRef ( {
160
+ prop : checkedProp . value ,
161
+ defaultProp : defaultChecked . value ,
162
+ onChange : onCheckedChange . value ,
165
163
} )
166
164
167
165
const initialCheckedStateRef = ref ( )
168
166
169
167
onMounted ( ( ) => {
170
- initialCheckedStateRef . value = checked . value
168
+ initialCheckedStateRef . value = state . value
171
169
} )
172
170
173
- watchEffect ( ( ) => {
174
- const form = _button . value ?. form
171
+ watch ( [ buttonRefEl , state ] , ( ) => {
172
+ const form = buttonRefEl . value ?. form
175
173
if ( form ) {
176
- const reset = ( ) => setChecked ( initialCheckedStateRef . value )
174
+ const reset = ( ) => ( state . value = initialCheckedStateRef . value )
177
175
form . addEventListener ( 'reset' , reset )
178
176
return ( ) => form . removeEventListener ( 'reset' , reset )
179
177
}
180
178
} )
181
179
182
180
CheckboxProvider ( {
183
- scope : scopeCheckbox as Scope ,
184
- state : checked as Ref < CheckedState > ,
181
+ scope : scopeCheckbox . value as Scope ,
182
+ state : state as Ref < CheckedState > ,
185
183
disabled : disabled as boolean ,
186
184
} )
187
185
188
186
const originalReturn = ( ) =>
189
187
[ h ( Primitive . button , {
190
188
'type' : 'button' ,
191
189
'role' : 'checkbox' ,
192
- 'aria-checked' : isIndeterminate ( checked . value as any ) ? 'mixed' : checked . value as any ,
193
- 'aria-required' : required ,
194
- 'data-state' : getState ( checked . value as any ) ,
190
+ 'aria-checked' : isIndeterminate ( state . value as any ) ? 'mixed' : state . value as any ,
191
+ 'aria-required' : required . value ,
192
+ 'data-state' : getState ( state . value as any ) ,
195
193
'data-disabled' : disabled ? '' : undefined ,
196
194
'disabled' : disabled ,
197
195
'value' : value ,
198
196
...checkboxProps ,
199
- 'ref' : innerRef ,
197
+ 'ref' : buttonRef ,
200
198
'onKeyDown' : composeEventHandlers ( checkboxProps . onKeydown , ( event ) => {
201
199
// According to WAI ARIA, Checkboxes don't activate on enter keypress
202
200
if ( event . key === 'Enter' )
203
201
event . preventDefault ( )
204
202
} ) ,
205
203
'onClick' : composeEventHandlers ( checkboxProps . onClick , ( event ) => {
206
- setChecked ( prevChecked => ( isIndeterminate ( prevChecked ) ? true : ! prevChecked ) )
204
+ state . value = isIndeterminate ( state . value as any ) ? true : ! ( state . value as any )
207
205
if ( isFormControl ) {
208
206
// hasConsumerStoppedPropagationRef.value.current = event.isPropagationStopped()
209
207
// if checkbox is in a form, stop propagation from the button so that we only propagate
@@ -220,11 +218,11 @@ const Checkbox = defineComponent({
220
218
isFormControl && h (
221
219
BubbleInput ,
222
220
{
223
- control : _button . value ,
221
+ control : buttonRefEl . value ,
224
222
bubbles : ! hasConsumerStoppedPropagationRef . value ,
225
223
name,
226
224
value,
227
- checked : checked . value ,
225
+ checked : state . value ,
228
226
required,
229
227
disabled,
230
228
// We transform because the input is absolutely positioned but we have
@@ -285,7 +283,7 @@ const CheckboxIndicator = defineComponent({
285
283
] )
286
284
287
285
return originalReturn as unknown as {
288
- innerRef : Ref < CheckboxIndicatorElement >
286
+ innerRef : Ref < HTMLButtonElement >
289
287
}
290
288
} ,
291
289
} )
0 commit comments