Skip to content

Commit 64589e8

Browse files
committed
feat: add NcFormBoxSelectNative
Signed-off-by: Grigorii K. Shartsev <[email protected]>
1 parent 150604d commit 64589e8

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<!--
2+
- SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
- SPDX-License-Identifier: AGPL-3.0-or-later
4+
-->
5+
6+
<script setup lang="ts" generic="T extends string">
7+
import { computed, useId, useTemplateRef } from 'vue'
8+
import IconUnfoldMoreHorizontal from 'vue-material-design-icons/UnfoldMoreHorizontal.vue'
9+
import NcFormBoxItem from '../NcFormBox/NcFormBoxItem.vue'
10+
11+
/** Selected value */
12+
const modelValue = defineModel<T>({ required: true })
13+
14+
const {
15+
label = undefined,
16+
options,
17+
disabled = false,
18+
} = defineProps<{
19+
/** Main label */
20+
label?: string
21+
/** Select options */
22+
options: {
23+
label: string
24+
value: T
25+
}[]
26+
/** Disabled state */
27+
disabled?: boolean
28+
}>()
29+
30+
const selectId = useId()
31+
const selectElement = useTemplateRef('select')
32+
const selectedLabel = computed(() => options.find((option) => option.value === modelValue.value)?.label)
33+
</script>
34+
35+
<template>
36+
<NcFormBoxItem
37+
tag="label"
38+
:for="selectId"
39+
:label
40+
:description="selectedLabel"
41+
:disabled
42+
inverted-accent
43+
@click.prevent="selectElement!.showPicker() /* Not available in old Safari */">
44+
<template #icon="{ descriptionId }">
45+
<IconUnfoldMoreHorizontal :size="20" />
46+
<select
47+
:id="selectId"
48+
ref="select"
49+
v-model="modelValue"
50+
class="hidden-select"
51+
:aria-describedby="descriptionId">
52+
<option v-for="option in options" :key="option.value" :value="option.value">
53+
{{ option.label }}
54+
</option>
55+
</select>
56+
</template>
57+
</NcFormBoxItem>
58+
</template>
59+
60+
<!-- TODO: module -->
61+
<style scoped>
62+
.hidden-select {
63+
position: absolute;
64+
inset: 0;
65+
margin: 0;
66+
height: auto;
67+
/* TODO: does it work well cross-browser? */
68+
opacity: 0;
69+
pointer-events: none;
70+
71+
option {
72+
pointer-events: all;
73+
}
74+
}
75+
</style>
76+
77+
<docs>
78+
### General
79+
80+
Native select wrapper to be used inside `NcFormBox`.
81+
82+
```vue
83+
<script>
84+
export default {
85+
data() {
86+
return {
87+
playSoundChat: 'always',
88+
playSoundCall: 'always',
89+
enableCallbox: 'always',
90+
notificationLevelOptions: [
91+
{ label: 'Always', value: 'always' },
92+
{ label: 'Only when away', value: 'away' },
93+
{ label: 'Never', value: 'never' },
94+
],
95+
}
96+
}
97+
}
98+
</script>
99+
100+
<template>
101+
<NcFormGroup label="Notifications and sounds">
102+
<NcFormBox>
103+
<NcFormBoxSelectNative v-model="playSoundChat" label="Play chat notification sound" :options="notificationLevelOptions" />
104+
<NcFormBoxSelectNative v-model="playSoundCall" label="Play call notification sound" :options="notificationLevelOptions" />
105+
<NcFormBoxSelectNative v-model="enableCallbox" label="Show call notification popup" :options="notificationLevelOptions" />
106+
</NcFormBox>
107+
</NcFormGroup>
108+
</template>
109+
```
110+
</docs>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
export { default } from './NcFormBoxSwitch.vue'

0 commit comments

Comments
 (0)