-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
toggle.ts
100 lines (85 loc) · 2.61 KB
/
toggle.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import type { PropType } from 'vue'
import { computed, defineComponent, h, toRefs, useModel } from 'vue'
import { Primitive } from '@oku-ui/primitive'
import type { ElementType, InstanceTypeRef, MergeProps, PrimitiveProps } from '@oku-ui/primitive'
import { composeEventHandlers } from '@oku-ui/utils'
import { useControllable, useForwardRef } from '@oku-ui/use-composable'
const TOGGLE_NAME = 'Toggle'
type ToggleElement = ElementType<'button'>
export type _ToggleEl = HTMLButtonElement
interface ToggleProps extends PrimitiveProps {
/**
* The controlled state of the toggle.
*/
pressed?: boolean
/**
* The state of the toggle when initially rendered. Use `defaultPressed`
* if you do not need to control the state of the toggle.
* @defaultValue false
*/
defaultPressed?: boolean
}
const Toggle = defineComponent({
name: TOGGLE_NAME,
inheritAttrs: false,
props: {
modelValue: {
type: [Boolean, String, Number] as PropType<
boolean | string | number | undefined
>,
default: undefined,
},
pressed: {
type: Boolean,
default: undefined,
},
defaultPressed: {
type: Boolean,
default: false,
},
},
emits: ['update:pressed', 'update:modelValue'],
setup(props, { attrs, slots, emit }) {
const { pressed: pressedProp, defaultPressed } = toRefs(props)
const modelValue = useModel(props, 'modelValue')
const forwardedRef = useForwardRef()
const { state, updateValue } = useControllable({
prop: computed(() => modelValue.value ?? pressedProp.value),
defaultProp: computed(() => defaultPressed.value),
onChange: (pressed) => {
emit('update:pressed', pressed)
emit('update:modelValue', pressed)
},
})
const { disabled, ...toggleProps } = attrs as ToggleElement
const originalReturn = () => h(
Primitive.button, {
'type': 'button',
'aria-pressed': state.value,
'data-state': state.value ? 'on' : 'off',
'data-disabled': disabled ? '' : undefined,
...toggleProps,
'ref': forwardedRef,
'onClick': composeEventHandlers(toggleProps.onClick, () => {
if (!disabled)
updateValue(!state.value)
}),
},
{
default: () => slots.default?.(),
},
)
return originalReturn
},
})
type _ToggleProps = MergeProps<ToggleProps, ToggleElement>
type InstanceToggleType = InstanceTypeRef<typeof Toggle, _ToggleEl>
const OkuToggle = Toggle as typeof Toggle & (new () => { $props: _ToggleProps })
export {
OkuToggle,
}
export type {
ToggleProps,
ToggleElement,
InstanceToggleType,
}