@@ -12,34 +12,37 @@ const { values } = defineProps<{
1212 screenreaderTitle: TranslationInput ,
1313 values: T ,
1414}>()
15- const idFirstValue = useId ()
16- const idSecondValue = useId ()
15+ const id = useId ()
1716const name = useId ()
18- const modelValue = defineModel <typeof values [number ][' key' ]>()
17+ const modelValue = defineModel <typeof values [number ][' key' ]>({ required: true })
18+ const defaultValue = modelValue .value
1919const { t : $t } = useTranslation ()
20- const thumb = useTemplateRef (' thumb' )
20+ const thumbs = useTemplateRef (' thumb' )
2121const track = useTemplateRef (' track' )
2222
2323const moveThumb = () => {
2424 const activeTrackItem = track .value ?.querySelector (' :has(input[type="radio"]:checked)' )
25+ const thumb = thumbs .value ?.[0 ]
2526 if (! activeTrackItem ) return
26- if (! thumb . value ) return
27+ if (! thumb ) return
2728
28- const { x : initialX } = thumb .value . getBoundingClientRect ()
29+ const { x : initialX } = thumb .getBoundingClientRect ()
2930 const { x } = activeTrackItem .getBoundingClientRect ()
3031
3132 // this should rather have been done via view transition api
3233 // but it currently lacks `firefox support`
3334 // and also there was a flickering issue
34- const animation = thumb .value . animate ([ {
35+ const animation = thumb .animate ([ {
3536 transform: ` translateX(${x - initialX }px) ` ,
3637 } ],
3738 { duration: 180 },
3839 )
3940 return animation .finished .then (() => {
40- activeTrackItem .appendChild (thumb .value ! )
41+ if (! thumb ) return
42+ activeTrackItem .appendChild (thumb )
4143 })
4244}
45+
4346watch (modelValue , () => {
4447 moveThumb ()
4548})
@@ -56,55 +59,36 @@ watch(modelValue, () => {
5659 v-bind =" $attrs"
5760 >
5861 <label
59- :for =" idFirstValue"
62+ v-for =" (value, index) in values"
63+ :key =" value.key"
64+ :for =" `${id}-${index}`"
6065 :class =" classList?.trackItem"
6166 class =" relative"
6267 >
6368 <span class =" relative z-10" >
6469 <slot
65- name =" first "
66- :label =" values[0 ]?.label"
70+ : name =" value.key "
71+ :label =" values[index ]?.label"
6772 >
68- {{ values[0 ]?.label }}
73+ {{ values[index ]?.label }}
6974 </slot >
7075 </span >
7176 <input
72- :id =" idFirstValue "
77+ :id =" `${id}-${index}` "
7378 v-model =" modelValue"
74- :value =" values[0 ]?.key"
79+ :value =" values[index ]?.key"
7580 type =" radio"
7681 class =" sr-only"
7782 :name
7883 >
7984 <span
85+ v-if =" value.key === defaultValue"
8086 ref =" thumb"
8187 class =" absolute inset-[0] z-0"
8288 aria-hidden =" true"
8389 :class =" classList?.thumb"
8490 />
8591 </label >
86- <label
87- class =" relative"
88- :class =" classList?.trackItem"
89- :for =" idSecondValue"
90- >
91- <span class =" relative z-10" >
92- <slot
93- name =" second"
94- :label =" values[1]?.label"
95- >
96- {{ values[1]?.label }}
97- </slot >
98- </span >
99- <input
100- :id =" idSecondValue"
101- v-model =" modelValue"
102- :value =" values[1]?.key"
103- class =" sr-only"
104- type =" radio"
105- :name
106- >
107- </label >
10892 </div >
10993 </fieldset >
11094</template >
0 commit comments