diff --git a/.changeset/sour-shrimps-turn.md b/.changeset/sour-shrimps-turn.md new file mode 100644 index 0000000000..f8cccffe4b --- /dev/null +++ b/.changeset/sour-shrimps-turn.md @@ -0,0 +1,5 @@ +--- +"sit-onyx": minor +--- + +feat: implement fallthrough attribute forwarding diff --git a/apps/docs/playwright/snapshots/principles-contributing-patterns-edge-linux.png b/apps/docs/playwright/snapshots/principles-contributing-patterns-edge-linux.png new file mode 100644 index 0000000000..9f181a0fdc Binary files /dev/null and b/apps/docs/playwright/snapshots/principles-contributing-patterns-edge-linux.png differ diff --git a/apps/docs/playwright/snapshots/principles-contributing-patterns-firefox-linux.png b/apps/docs/playwright/snapshots/principles-contributing-patterns-firefox-linux.png new file mode 100644 index 0000000000..e4d575903a Binary files /dev/null and b/apps/docs/playwright/snapshots/principles-contributing-patterns-firefox-linux.png differ diff --git a/apps/docs/playwright/snapshots/principles-contributing-patterns-webkit-linux.png b/apps/docs/playwright/snapshots/principles-contributing-patterns-webkit-linux.png new file mode 100644 index 0000000000..ac71b457dd Binary files /dev/null and b/apps/docs/playwright/snapshots/principles-contributing-patterns-webkit-linux.png differ diff --git a/apps/docs/src/.vitepress/config.ts b/apps/docs/src/.vitepress/config.ts index c7186f7b1d..d4998d58da 100644 --- a/apps/docs/src/.vitepress/config.ts +++ b/apps/docs/src/.vitepress/config.ts @@ -182,6 +182,7 @@ export const CONFIG = { { text: "Stories", link: "/stories" }, { text: "Styling", link: "/styling" }, { text: "Testing", link: "/testing" }, + { text: "Patterns", link: "/patterns" }, ], }, { diff --git a/apps/docs/src/principles/contributing/patterns.md b/apps/docs/src/principles/contributing/patterns.md new file mode 100644 index 0000000000..6908197b8f --- /dev/null +++ b/apps/docs/src/principles/contributing/patterns.md @@ -0,0 +1,16 @@ +# Patterns + +This page explains which common patterns we follow when developing onyx and how to use them. +These patterns are implemented through [**composables**](https://vuejs.org/guide/reusability/composables.html) and enforced through [**linting rules**](https://eslint.org/docs/latest/extend/custom-rules), where possible. + +## Root Attribute Forwarding + +For implementing necessary layout, styling and ARIA requirements, it is often necessary to wrap interactive HTML elements. +To enable the developers to be able to set custom attributes and event-listeners on these, we forward most attributes to the relevant (e.g. input or button) element. +The only attributes that are not forwarded are `style` and `class` with the assumption being, that these are only useful and intended to be set on the root element of the component. + +<<< ../../../../../packages/sit-onyx/src/utils/attrs.ts#docs + +::: info +Your use-case is not covered? Head over to our GitHub [discussion page](https://github.com/SchwarzIT/onyx/discussions) to make suggestions or ask questions! +::: diff --git a/packages/sit-onyx/src/components/OnyxCheckbox/OnyxCheckbox.vue b/packages/sit-onyx/src/components/OnyxCheckbox/OnyxCheckbox.vue index 6c13c1e50b..7e00d25b3c 100644 --- a/packages/sit-onyx/src/components/OnyxCheckbox/OnyxCheckbox.vue +++ b/packages/sit-onyx/src/components/OnyxCheckbox/OnyxCheckbox.vue @@ -6,6 +6,7 @@ import { useAutofocus } from "../../composables/useAutoFocus"; import { useCustomValidity } from "../../composables/useCustomValidity"; import { SKELETON_INJECTED_SYMBOL, useSkeletonContext } from "../../composables/useSkeletonState"; import type { SelectOptionValue } from "../../types"; +import { useRootAttrs } from "../../utils/attrs"; import OnyxErrorTooltip from "../OnyxErrorTooltip/OnyxErrorTooltip.vue"; import { FORM_INJECTED_SYMBOL, useFormContext } from "../OnyxForm/OnyxForm.core"; import OnyxLoadingIndicator from "../OnyxLoadingIndicator/OnyxLoadingIndicator.vue"; @@ -31,6 +32,9 @@ const emit = defineEmits<{ validityChange: [validity: ValidityState]; }>(); +defineOptions({ inheritAttrs: false }); +const { rootAttrs, restAttrs } = useRootAttrs(); + const isChecked = computed({ get: () => props.modelValue, set: (value) => emit("update:modelValue", value), @@ -53,12 +57,16 @@ useAutofocus(input, props);