@tamagui/switch 1.79.6 → 1.79.7

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.
@@ -127,157 +127,151 @@ export function createSwitch<F extends SwitchComponent, T extends SwitchThumbCom
127
127
  )
128
128
  })
129
129
 
130
- const SwitchComponent = Frame.extractable(
131
- React.forwardRef<TamaguiElement, SwitchProps>(function SwitchFrame(
132
- propsIn,
133
- forwardedRef
134
- ) {
135
- const styledContext = React.useContext(SwitchContext)
136
- const props = useProps(propsIn, {
137
- noNormalize: true,
138
- noExpand: true,
139
- resolveValues: 'none',
140
- forComponent: Frame,
141
- })
142
- const {
143
- labeledBy: ariaLabelledby,
144
- name,
145
- checked: checkedProp,
146
- defaultChecked,
147
- required,
148
- disabled,
149
- value = 'on',
150
- onCheckedChange,
151
- size = styledContext.size ?? '$true',
152
- unstyled = styledContext.unstyled ?? false,
153
- native: nativeProp,
154
- nativeProps,
155
- children,
156
- ...switchProps
157
- } = props
130
+ const SwitchComponent = Frame.styleable<SwitchExtraProps>(function SwitchFrame(
131
+ propsIn,
132
+ forwardedRef
133
+ ) {
134
+ const styledContext = React.useContext(SwitchContext)
135
+ const props = useProps(propsIn, {
136
+ noNormalize: true,
137
+ noExpand: true,
138
+ resolveValues: 'none',
139
+ forComponent: Frame,
140
+ })
141
+ const {
142
+ labeledBy: ariaLabelledby,
143
+ name,
144
+ checked: checkedProp,
145
+ defaultChecked,
146
+ required,
147
+ disabled,
148
+ value = 'on',
149
+ onCheckedChange,
150
+ size = styledContext.size ?? '$true',
151
+ unstyled = styledContext.unstyled ?? false,
152
+ native: nativeProp,
153
+ nativeProps,
154
+ children,
155
+ ...switchProps
156
+ } = props
158
157
 
159
- const native = Array.isArray(nativeProp) ? nativeProp : [nativeProp]
158
+ const native = Array.isArray(nativeProp) ? nativeProp : [nativeProp]
160
159
 
161
- const shouldRenderMobileNative =
162
- (!isWeb && nativeProp === true) ||
163
- (!isWeb && native.includes('mobile')) ||
164
- (native.includes('android') && Platform.OS === 'android') ||
165
- (native.includes('ios') && Platform.OS === 'ios')
160
+ const shouldRenderMobileNative =
161
+ (!isWeb && nativeProp === true) ||
162
+ (!isWeb && native.includes('mobile')) ||
163
+ (native.includes('android') && Platform.OS === 'android') ||
164
+ (native.includes('ios') && Platform.OS === 'ios')
166
165
 
167
- const [button, setButton] = React.useState<HTMLButtonElement | null>(null)
168
- const composedRefs = useComposedRefs(
169
- forwardedRef,
170
- // @ts-expect-error
171
- setButton
172
- )
173
- const labelId = useLabelContext(button)
174
- const labelledBy = ariaLabelledby || labelId
175
- const hasConsumerStoppedPropagationRef = React.useRef(false)
176
- // We set this to true by default so that events bubble to forms without JS (SSR)
177
- const isFormControl = isWeb
178
- ? button
179
- ? Boolean(button.closest('form'))
180
- : true
181
- : false
166
+ const [button, setButton] = React.useState<HTMLButtonElement | null>(null)
167
+ const composedRefs = useComposedRefs(forwardedRef, setButton)
168
+ const labelId = useLabelContext(button)
169
+ const labelledBy = ariaLabelledby || labelId
170
+ const hasConsumerStoppedPropagationRef = React.useRef(false)
171
+ // We set this to true by default so that events bubble to forms without JS (SSR)
172
+ const isFormControl = isWeb
173
+ ? button
174
+ ? Boolean(button.closest('form'))
175
+ : true
176
+ : false
182
177
 
183
- const [frameWidth, setFrameWidth] = React.useState(0)
178
+ const [frameWidth, setFrameWidth] = React.useState(0)
184
179
 
185
- const [checked = false, setChecked] = useControllableState({
186
- prop: checkedProp,
187
- defaultProp: defaultChecked || false,
188
- onChange: onCheckedChange,
189
- transition: true,
190
- })
180
+ const [checked = false, setChecked] = useControllableState({
181
+ prop: checkedProp,
182
+ defaultProp: defaultChecked || false,
183
+ onChange: onCheckedChange,
184
+ transition: true,
185
+ })
191
186
 
192
- if (shouldRenderMobileNative) {
193
- return (
194
- <NativeSwitch
195
- value={checkedProp}
196
- onValueChange={onCheckedChange}
197
- {...nativeProps}
198
- />
199
- )
200
- }
187
+ if (shouldRenderMobileNative) {
188
+ return (
189
+ <NativeSwitch
190
+ value={checkedProp}
191
+ onValueChange={onCheckedChange}
192
+ {...nativeProps}
193
+ />
194
+ )
195
+ }
201
196
 
202
- if (!isWeb) {
203
- // eslint-disable-next-line react-hooks/rules-of-hooks
204
- React.useEffect(() => {
205
- if (!props.id) return
206
- return registerFocusable(props.id, {
207
- focus: () => {
208
- setChecked((x) => !x)
209
- },
210
- })
211
- }, [props.id, setChecked])
212
- }
197
+ if (!isWeb) {
198
+ // eslint-disable-next-line react-hooks/rules-of-hooks
199
+ React.useEffect(() => {
200
+ if (!props.id) return
201
+ return registerFocusable(props.id, {
202
+ focus: () => {
203
+ setChecked((x) => !x)
204
+ },
205
+ })
206
+ }, [props.id, setChecked])
207
+ }
213
208
 
214
- return (
215
- <>
216
- {/* @ts-ignore */}
217
- <Frame
218
- tag="button"
219
- unstyled={unstyled}
220
- size={size}
209
+ return (
210
+ <>
211
+ {/* @ts-ignore */}
212
+ <Frame
213
+ tag="button"
214
+ unstyled={unstyled}
215
+ size={size}
216
+ checked={checked}
217
+ disabled={disabled}
218
+ frameWidth={frameWidth}
219
+ themeShallow
220
+ {...(!disableActiveTheme && {
221
+ theme: checked ? 'active' : null,
222
+ themeShallow: true,
223
+ })}
224
+ role="switch"
225
+ aria-checked={checked}
226
+ aria-labelledby={labelledBy}
227
+ aria-required={required}
228
+ data-state={getState(checked)}
229
+ data-disabled={disabled ? '' : undefined}
230
+ // @ts-ignore
231
+ tabIndex={disabled ? undefined : 0}
232
+ // @ts-ignore
233
+ value={value}
234
+ {...switchProps}
235
+ ref={composedRefs}
236
+ onPress={composeEventHandlers(props.onPress, (event) => {
237
+ setChecked((prevChecked) => !prevChecked)
238
+ if (isWeb && isFormControl) {
239
+ hasConsumerStoppedPropagationRef.current = event.isPropagationStopped()
240
+ // if switch is in a form, stop propagation from the button so that we only propagate
241
+ // one click event (from the input). We propagate changes from an input so that native
242
+ // form validation works and form events reflect switch updates.
243
+ if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation()
244
+ }
245
+ })}
246
+ >
247
+ <YStack
248
+ alignSelf="stretch"
249
+ flex={1}
250
+ onLayout={(e) => {
251
+ setFrameWidth(e.nativeEvent.layout.width)
252
+ }}
253
+ >
254
+ {typeof children === 'function' ? children(checked) : children}
255
+ </YStack>
256
+ </Frame>
257
+ {isWeb && isFormControl && (
258
+ <BubbleInput
259
+ control={button}
260
+ bubbles={!hasConsumerStoppedPropagationRef.current}
261
+ name={name}
262
+ value={value}
221
263
  checked={checked}
264
+ required={required}
222
265
  disabled={disabled}
223
- frameWidth={frameWidth}
224
- themeShallow
225
- {...(!disableActiveTheme && {
226
- theme: checked ? 'active' : null,
227
- themeShallow: true,
228
- })}
229
- role="switch"
230
- aria-checked={checked}
231
- aria-labelledby={labelledBy}
232
- aria-required={required}
233
- data-state={getState(checked)}
234
- data-disabled={disabled ? '' : undefined}
235
- // @ts-ignore
236
- tabIndex={disabled ? undefined : 0}
237
- // @ts-ignore
238
- value={value}
239
- {...switchProps}
240
- ref={composedRefs}
241
- onPress={composeEventHandlers(props.onPress, (event) => {
242
- setChecked((prevChecked) => !prevChecked)
243
- if (isWeb && isFormControl) {
244
- hasConsumerStoppedPropagationRef.current = event.isPropagationStopped()
245
- // if switch is in a form, stop propagation from the button so that we only propagate
246
- // one click event (from the input). We propagate changes from an input so that native
247
- // form validation works and form events reflect switch updates.
248
- if (!hasConsumerStoppedPropagationRef.current) event.stopPropagation()
249
- }
250
- })}
251
- >
252
- <YStack
253
- alignSelf="stretch"
254
- flex={1}
255
- onLayout={(e) => {
256
- setFrameWidth(e.nativeEvent.layout.width)
257
- }}
258
- >
259
- {typeof children === 'function' ? children(checked) : children}
260
- </YStack>
261
- </Frame>
262
- {isWeb && isFormControl && (
263
- <BubbleInput
264
- control={button}
265
- bubbles={!hasConsumerStoppedPropagationRef.current}
266
- name={name}
267
- value={value}
268
- checked={checked}
269
- required={required}
270
- disabled={disabled}
271
- // We transform because the input is absolutely positioned but we have
272
- // rendered it **after** the button. This pulls it back to sit on top
273
- // of the button.
274
- style={{ transform: 'translateX(-100%)' }}
275
- />
276
- )}
277
- </>
278
- )
279
- })
280
- )
266
+ // We transform because the input is absolutely positioned but we have
267
+ // rendered it **after** the button. This pulls it back to sit on top
268
+ // of the button.
269
+ style={{ transform: 'translateX(-100%)' }}
270
+ />
271
+ )}
272
+ </>
273
+ )
274
+ })
281
275
 
282
276
  /* ---------------------------------------------------------------------------------------------- */
283
277