55
66<template >
77 <div class =" pill-menu" >
8- <NcCheckboxRadioSwitch
9- v-for =" option of options "
10- :key =" option .id "
11- :aria-label =" isMobile ? option .ariaLabel : null "
8+ <NcRadioGroup
9+ :label =" groupLabel "
1210 :modelValue =" active .id "
13- :disabled =" disabled || option .disabled "
14- class="pill-menu__toggle"
15- :class =" { ' pill-menu__toggle--icon-only' : isMobile && option .icon } "
16- buttonVariant
17- buttonVariantGrouped="horizontal"
18- type="radio"
19- :value =" option .id "
20- @update :modelValue =" $emit (' update:active' , option )" >
21- <template v-if =" option .icon " #icon >
22- <NcIconSvgWrapper :svg =" option .icon " />
23- </template >
24- {{ !isMobile || !option.icon ? option.title : null }}
25- </NcCheckboxRadioSwitch >
11+ hideLabel
12+ @update :modelValue =" onUpdateActive " >
13+ <NcRadioGroupButton
14+ v-for =" option of options "
15+ :key =" option .id "
16+ :value =" option .id "
17+ :aria-label =" isMobile && option .icon ? option .ariaLabel : undefined "
18+ :label =" ! isMobile || ! option .icon ? option .title : undefined "
19+ :disabled =" disabled || option .disabled " >
20+ <template v-if =" option .icon " #icon >
21+ <NcIconSvgWrapper :svg =" option .icon " />
22+ </template >
23+ </NcRadioGroupButton >
24+ </NcRadioGroup >
2625 </div >
2726</template >
2827
2928<script >
3029import { useIsSmallMobile } from ' @nextcloud/vue'
31- import NcCheckboxRadioSwitch from ' @nextcloud/vue/components/NcCheckboxRadioSwitch'
3230import NcIconSvgWrapper from ' @nextcloud/vue/components/NcIconSvgWrapper'
31+ import NcRadioGroup from ' @nextcloud/vue/components/NcRadioGroup'
32+ import NcRadioGroupButton from ' @nextcloud/vue/components/NcRadioGroupButton'
3333
3434export default {
3535 name: ' PillMenu' ,
3636
3737 components: {
38- NcCheckboxRadioSwitch,
3938 NcIconSvgWrapper,
39+ NcRadioGroup,
40+ NcRadioGroupButton,
4041 },
4142
4243 props: {
@@ -56,6 +57,14 @@ export default {
5657 default: false ,
5758 },
5859
60+ /**
61+ * Accessible label for the radio group
62+ */
63+ groupLabel: {
64+ type: String ,
65+ required: true ,
66+ },
67+
5968 /**
6069 * List of available options
6170 * `option: {id: string, title: string, ariaLabel: string, icon?: string}`
@@ -73,27 +82,17 @@ export default {
7382 isMobile: useIsSmallMobile (),
7483 }
7584 },
76- }
77- </script >
78-
79- <style lang="scss" scoped>
80- .pill-menu {
81- align-items : center ;
82- align-self : flex-end ;
83- display : flex ;
84- justify-content : flex-end ;
8585
86- #{&} & __toggle {
87- // Make it a bit more condensed
88- :deep (.checkbox-radio-switch__content ) {
89- flex-direction : row ;
90- padding-block : 0 ;
91- }
92-
93- // Make icon only toggle round intead of elipse
94- & --icon-only :deep (.checkbox-radio-switch__content ) {
95- padding-inline : 0 ;
96- }
97- }
86+ methods: {
87+ /**
88+ * Emit the full selected option to keep PillMenu API stable
89+ *
90+ * @param {string} optionId The selected option id
91+ */
92+ onUpdateActive (optionId ) {
93+ const option = this .options .find ((entry ) => entry .id === optionId)
94+ if (option) this .$emit (' update:active' , option)
95+ },
96+ },
9897}
99- </style >
98+ </script >
0 commit comments