From 46584147783f9451514f3e98ae85c2f6e69368a4 Mon Sep 17 00:00:00 2001 From: lehju Date: Thu, 18 Dec 2025 16:30:33 +0100 Subject: [PATCH 1/5] :sparkles: add MucAccordion component --- .../Accordion/MucAccordion.stories.ts | 161 +++++++++++++++++ src/components/Accordion/MucAccordion.vue | 84 +++++++++ .../Accordion/MucAccordionItem.stories.ts | 37 ++++ src/components/Accordion/MucAccordionItem.vue | 165 ++++++++++++++++++ src/components/Accordion/index.ts | 4 + src/components/index.ts | 3 + 6 files changed, 454 insertions(+) create mode 100644 src/components/Accordion/MucAccordion.stories.ts create mode 100644 src/components/Accordion/MucAccordion.vue create mode 100644 src/components/Accordion/MucAccordionItem.stories.ts create mode 100644 src/components/Accordion/MucAccordionItem.vue create mode 100644 src/components/Accordion/index.ts diff --git a/src/components/Accordion/MucAccordion.stories.ts b/src/components/Accordion/MucAccordion.stories.ts new file mode 100644 index 00000000..0f0c984a --- /dev/null +++ b/src/components/Accordion/MucAccordion.stories.ts @@ -0,0 +1,161 @@ +import MucAccordion from "./MucAccordion.vue"; +import MucAccordionItem from "./MucAccordionItem.vue"; + +export default { + components: { MucAccordion }, + component: MucAccordion, + title: "Accordion/MucAccordion", + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: `The \`muc-accordion\` component offers the option of displaying content clearly in an accordion format.
A template with the following v-slot must be placed around the MucAccordionItems \`v-slot:default=“{onOpen, onClose, activeItems}”\`.
Each MucAccordionItem must be passed the following parameters with exactly this values: \`:active-items="activeItems"\` \`@open="onOpen"\` \`@close="onClose"\` .
For exmaple: + + + + +[🔗 Patternlab-Docs](https://patternlab.muenchen.space/?p=viewall-components-accordion) +`, + }, + }, + }, +}; + +export const Template = () => ({ + components: { MucAccordion, MucAccordionItem }, + template: ` + + + + `, +}); + +export const Multiple = () => ({ + components: { MucAccordion, MucAccordionItem }, + template: ` + + + + `, +}); diff --git a/src/components/Accordion/MucAccordion.vue b/src/components/Accordion/MucAccordion.vue new file mode 100644 index 00000000..ca738795 --- /dev/null +++ b/src/components/Accordion/MucAccordion.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/components/Accordion/MucAccordionItem.stories.ts b/src/components/Accordion/MucAccordionItem.stories.ts new file mode 100644 index 00000000..f052bf8e --- /dev/null +++ b/src/components/Accordion/MucAccordionItem.stories.ts @@ -0,0 +1,37 @@ +import MucAccordionItem from "./MucAccordionItem.vue"; + +export default { + components: { MucAccordionItem }, + component: MucAccordionItem, + title: "Accordion/MucAccordionItem", + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: `The \`muc-accordion-item\` component represents an item of an \`muc-accordion\`
Each MucAccordionItem must be passed the following parameters with exactly this values: \`:active-items="activeItems"\` \`@open="onOpen"\` \`@close="onClose"\` + +[🔗 Patternlab-Docs](https://patternlab.muenchen.space/?p=viewall-components-accordion) +`, + }, + }, + }, +}; + +export const Template = () => ({ + components: { MucAccordionItem }, + template: ` + + + + + + `, +}); diff --git a/src/components/Accordion/MucAccordionItem.vue b/src/components/Accordion/MucAccordionItem.vue new file mode 100644 index 00000000..4439757c --- /dev/null +++ b/src/components/Accordion/MucAccordionItem.vue @@ -0,0 +1,165 @@ + + + diff --git a/src/components/Accordion/index.ts b/src/components/Accordion/index.ts new file mode 100644 index 00000000..6b9f41d7 --- /dev/null +++ b/src/components/Accordion/index.ts @@ -0,0 +1,4 @@ +import MucAccordion from "./MucAccordion.vue"; +import MucAccordionItem from "./MucAccordionItem.vue"; + +export { MucAccordion, MucAccordionItem }; diff --git a/src/components/index.ts b/src/components/index.ts index 3fe021d5..d05e5a28 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -1,3 +1,4 @@ +import { MucAccordion, MucAccordionItem } from "./Accordion"; import { MucBanner } from "./Banner"; import { MucButton } from "./Button"; import { MucCalendar } from "./Calendar"; @@ -27,6 +28,8 @@ import { MucSpinner } from "./Spinner"; import { MucStepper } from "./Stepper"; export { + MucAccordion, + MucAccordionItem, MucButton, MucBanner, MucIntro, From e58c448088ccd4608460d697680984e044d90984 Mon Sep 17 00:00:00 2001 From: lehju Date: Thu, 18 Dec 2025 16:43:41 +0100 Subject: [PATCH 2/5] :green_heart: linter --- src/components/Accordion/MucAccordionItem.vue | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/Accordion/MucAccordionItem.vue b/src/components/Accordion/MucAccordionItem.vue index 4439757c..bcde3ed7 100644 --- a/src/components/Accordion/MucAccordionItem.vue +++ b/src/components/Accordion/MucAccordionItem.vue @@ -105,12 +105,14 @@ const collapsing = ref(false); watch( () => activeItems, () => { - if (!activeItems.includes(id) && !collapsed.value) { + if (!activeItems.includes(id) && !collapsed.value && section.value) { collapsed.value = true; section.value.style.height = section.value.scrollHeight + "px"; collapsing.value = true; setTimeout(() => { - section.value.style.height = "0"; + if (section.value) { + section.value.style.height = "0"; + } }, 0); } } @@ -127,14 +129,18 @@ const toggleCollapsable = () => { collapsing.value = true; emit("close", id); setTimeout(() => { - section.value.style.height = "0"; + if (section.value) { + section.value.style.height = "0"; + } }, 0); } else { section.value.style.height = "0"; collapsing.value = true; emit("open", id); setTimeout(() => { - section.value.style.height = section.value.scrollHeight + "px"; + if (section.value) { + section.value.style.height = section.value.scrollHeight + "px"; + } }, 0); } } @@ -145,7 +151,9 @@ const toggleCollapsable = () => { */ const handleTransitionEnd = () => { collapsing.value = false; - section.value.style.height = ""; + if (section.value) { + section.value.style.height = ""; + } }; onMounted(() => { From fadaa0bb6dfcdfc5d881a4ad37cfd4ea4e1e73bf Mon Sep 17 00:00:00 2001 From: lehju Date: Thu, 18 Dec 2025 16:58:54 +0100 Subject: [PATCH 3/5] :ok_hand: review feedback --- src/components/Accordion/MucAccordion.stories.ts | 2 +- src/components/Accordion/MucAccordion.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Accordion/MucAccordion.stories.ts b/src/components/Accordion/MucAccordion.stories.ts index 0f0c984a..b7072f0d 100644 --- a/src/components/Accordion/MucAccordion.stories.ts +++ b/src/components/Accordion/MucAccordion.stories.ts @@ -9,7 +9,7 @@ export default { parameters: { docs: { description: { - component: `The \`muc-accordion\` component offers the option of displaying content clearly in an accordion format.
A template with the following v-slot must be placed around the MucAccordionItems \`v-slot:default=“{onOpen, onClose, activeItems}”\`.
Each MucAccordionItem must be passed the following parameters with exactly this values: \`:active-items="activeItems"\` \`@open="onOpen"\` \`@close="onClose"\` .
For exmaple: + component: `The \`muc-accordion\` component offers the option of displaying content clearly in an accordion format.
A template with the following v-slot must be placed around the MucAccordionItems \`v-slot:default=“{onOpen, onClose, activeItems}”\`.
Each MucAccordionItem must be passed the following parameters with exactly this values: \`:active-items="activeItems"\` \`@open="onOpen"\` \`@close="onClose"\` .
For example: