diff --git a/src/components/NcFormBox/NcFormBox.vue b/src/components/NcFormBox/NcFormBox.vue new file mode 100644 index 0000000000..6706d8903d --- /dev/null +++ b/src/components/NcFormBox/NcFormBox.vue @@ -0,0 +1,159 @@ + + + + + + + + + +### General + +Visually group form elements with a small gap and rounded corners forming a solid group for supported components. + +**Note**: if the group has a semantic meaning, consider using the `` component. + +```vue + + + +``` + +### Advanced usage + +Use scoped slots params to apply the item class to custom items. + +```vue + +``` + diff --git a/src/components/NcFormBox/index.ts b/src/components/NcFormBox/index.ts new file mode 100644 index 0000000000..552bd73343 --- /dev/null +++ b/src/components/NcFormBox/index.ts @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +export { default } from './NcFormBox.vue' diff --git a/src/components/NcFormBox/useNcFormBox.ts b/src/components/NcFormBox/useNcFormBox.ts new file mode 100644 index 0000000000..0c8a7eb149 --- /dev/null +++ b/src/components/NcFormBox/useNcFormBox.ts @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { InjectionKey } from 'vue' + +import { inject } from 'vue' + +export const NC_FORM_BOX_CONTEXT_KEY: InjectionKey<{ + isInFormBox: false + formBoxItemClass: undefined +} | { + isInFormBox: true + formBoxItemClass: string +}> = Symbol.for('NcFormBox:context') + +/** + * Get NcFormBox context with a fallback + * TODO: make it public? + */ +export function useNcFormBox() { + return inject(NC_FORM_BOX_CONTEXT_KEY, { + isInFormBox: false, + formBoxItemClass: undefined, + }) +} diff --git a/src/components/NcRadioGroup/NcRadioGroup.vue b/src/components/NcRadioGroup/NcRadioGroup.vue index 522b9a15b1..8afc1cde0c 100644 --- a/src/components/NcRadioGroup/NcRadioGroup.vue +++ b/src/components/NcRadioGroup/NcRadioGroup.vue @@ -7,7 +7,8 @@ import type { Slot } from 'vue' import { computed, provide, ref, warn } from 'vue' -import { createElementId } from '../../utils/createElementId.ts' +import NcFormBox from '../NcFormBox/NcFormBox.vue' +import NcFormGroup from '../NcFormGroup/NcFormGroup.vue' import { INSIDE_RADIO_GROUP_KEY } from './useNcRadioGroup.ts' const modelValue = defineModel({ required: false, default: '' }) @@ -40,7 +41,6 @@ defineSlots<{ default?: Slot }>() -const descriptionId = createElementId() const buttonVariant = ref() provide(INSIDE_RADIO_GROUP_KEY, computed(() => ({ @@ -72,62 +72,22 @@ function onUpdate(value: string) { diff --git a/src/components/NcRadioGroupButton/NcRadioGroupButton.vue b/src/components/NcRadioGroupButton/NcRadioGroupButton.vue index deff9b8d35..fa1f87c8dd 100644 --- a/src/components/NcRadioGroupButton/NcRadioGroupButton.vue +++ b/src/components/NcRadioGroupButton/NcRadioGroupButton.vue @@ -8,6 +8,7 @@ import type { Slot } from 'vue' import { computed, onMounted } from 'vue' import { createElementId } from '../../utils/createElementId.ts' +import { useNcFormBox } from '../NcFormBox/useNcFormBox.ts' import { useInsideRadioGroup } from '../NcRadioGroup/useNcRadioGroup.ts' const props = defineProps<{ @@ -36,6 +37,8 @@ defineSlots<{ const labelId = createElementId() const radioGroup = useInsideRadioGroup() +const { formBoxItemClass } = useNcFormBox() + onMounted(() => radioGroup!.value.register(true)) const isChecked = computed(() => radioGroup?.value.modelValue === props.value) @@ -52,7 +55,7 @@ function onUpdate() {
@@ -120,16 +123,6 @@ function onUpdate() { border: var(--radio-group-button--border-width) solid var(--color-main-text) !important; outline: calc(var(--default-grid-baseline) / 2) var(--color-main-background); } - - &:first-of-type { - border-start-start-radius: var(--border-radius-element); - border-end-start-radius: var(--border-radius-element); - } - - &:last-of-type { - border-start-end-radius: var(--border-radius-element); - border-end-end-radius: var(--border-radius-element); - } } .radioGroupButton_active { diff --git a/src/components/index.ts b/src/components/index.ts index f327b99b55..e70abdb378 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -58,6 +58,7 @@ export { default as NcDialogButton } from './NcDialogButton/index.ts' export { default as NcEllipsisedOption } from './NcEllipsisedOption/index.js' export { default as NcEmojiPicker } from './NcEmojiPicker/index.js' export { default as NcEmptyContent } from './NcEmptyContent/index.ts' +export { default as NcFormBox } from './NcFormBox/index.ts' export { default as NcFormGroup } from './NcFormGroup/index.ts' export { default as NcGuestContent } from './NcGuestContent/index.ts' export { default as NcHeaderButton } from './NcHeaderButton/index.ts'