From 25e5ea12a23951fc4779b2d720cf6066f3639913 Mon Sep 17 00:00:00 2001 From: Nils Date: Fri, 15 Nov 2024 07:51:48 +0100 Subject: [PATCH 01/53] add toggle to popover --- .../mt-bare-popover/mt-bare-popover.spec.ts | 104 ++++++++++++++++++ .../mt-bare-popover.stories.ts | 26 +++++ .../mt-bare-popover/mt-bare-popover.vue | 13 +++ 3 files changed, 143 insertions(+) create mode 100644 packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts create mode 100644 packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts create mode 100644 packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts new file mode 100644 index 000000000..251406c70 --- /dev/null +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts @@ -0,0 +1,104 @@ +import { userEvent } from "@storybook/test"; +import { screen, render } from "@testing-library/vue"; +import MtBarePopover from "./mt-bare-popover.vue"; + +describe("mt-bare-popover", () => { + it("does not show the popover by default", () => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + `, + }); + + // ASSERT + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + + it("shows the popover when the trigger is clicked", async () => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + `, + }); + + // ACT + await userEvent.click(screen.getByRole("button")); + + // ASSERT + expect(screen.getByRole("dialog")).toBeVisible(); + }); + + it("hides the popover when the trigger is clicked again", async () => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + `, + }); + + await userEvent.click(screen.getByRole("button")); + + // ACT + await userEvent.click(screen.getByRole("button")); + + // ASSERT + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + + it.each(["{Enter}", " "])( + 'opens the popover when pressing "%s" on the trigger', + async (keyCode) => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + `, + }); + + // ACT + await userEvent.tab(); + await userEvent.keyboard(keyCode); + + // ASSERT + expect(screen.getByRole("dialog")).toBeVisible(); + }, + ); +}); diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts new file mode 100644 index 000000000..ae16ad840 --- /dev/null +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts @@ -0,0 +1,26 @@ +import type { SlottedMeta } from "@/_internal/story-helper"; +import MtBarePopover from "./mt-bare-popover.vue"; +import MtButton from "../../form/mt-button/mt-button.vue"; + +export type MtBarePopoverMeta = SlottedMeta; + +export default { + title: "Components/Overlay/mt-bare-popover", + render: (args) => ({ + setup: () => args, + components: { MtBarePopover, MtButton }, + template: ` + + + + + +`, + }), +} satisfies MtBarePopoverMeta; + +export const Default = {}; diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue new file mode 100644 index 000000000..f5043701f --- /dev/null +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue @@ -0,0 +1,13 @@ + + + From 3e129eb7cff437a1b0abc4042bd3bf08e5f81835 Mon Sep 17 00:00:00 2001 From: Nils Date: Fri, 15 Nov 2024 09:15:53 +0100 Subject: [PATCH 02/53] wip --- .../mt-bare-popover/mt-bare-popover.spec.ts | 58 +++++ .../mt-bare-popover.stories.ts | 11 +- .../mt-bare-popover/mt-bare-popover.vue | 112 ++++++++- .../sub-components/mt-bare-popover-item.vue | 7 + pnpm-lock.yaml | 223 ++++++------------ 5 files changed, 253 insertions(+), 158 deletions(-) create mode 100644 packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts index 251406c70..d9175af3c 100644 --- a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts @@ -1,6 +1,7 @@ import { userEvent } from "@storybook/test"; import { screen, render } from "@testing-library/vue"; import MtBarePopover from "./mt-bare-popover.vue"; +import { flushPromises } from "@vue/test-utils"; describe("mt-bare-popover", () => { it("does not show the popover by default", () => { @@ -101,4 +102,61 @@ describe("mt-bare-popover", () => { expect(screen.getByRole("dialog")).toBeVisible(); }, ); + + it("closes the popover when clicking outside of it", async () => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + +
+ `, + }); + + await userEvent.click(screen.getByRole("button")); + + // ACT + await userEvent.click(screen.getByTestId("element-outside-of-popover")); + + // ASSERT + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + + it("closes the popover when pressing the Escape key", async () => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + `, + }); + + await userEvent.click(screen.getByRole("button")); + + // ACT + await userEvent.keyboard("{Escape}"); + + // ASSERT + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + expect(document.activeElement?.getAttribute("id")).toBe( + screen.getByRole("button").getAttribute("id"), + ); + }); }); diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts index ae16ad840..95856f05f 100644 --- a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.stories.ts @@ -1,6 +1,8 @@ import type { SlottedMeta } from "@/_internal/story-helper"; import MtBarePopover from "./mt-bare-popover.vue"; import MtButton from "../../form/mt-button/mt-button.vue"; +import MtBarePopoverItem from "./sub-components/mt-bare-popover-item.vue"; +import { userEvent, within } from "@storybook/test"; export type MtBarePopoverMeta = SlottedMeta; @@ -8,7 +10,7 @@ export default { title: "Components/Overlay/mt-bare-popover", render: (args) => ({ setup: () => args, - components: { MtBarePopover, MtButton }, + components: { MtBarePopover, MtButton, MtBarePopoverItem }, template: ` `, }), + async play({ canvasElement }) { + const canvas = within(canvasElement); + + await userEvent.click(canvas.getByRole("button", { name: "Open popover" })); + }, } satisfies MtBarePopoverMeta; export const Default = {}; diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue index f5043701f..5046964d3 100644 --- a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue @@ -1,13 +1,115 @@ + + diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue b/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue new file mode 100644 index 000000000..bc8638c35 --- /dev/null +++ b/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a247f3ec4..312cd4b1b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -136,10 +136,10 @@ importers: version: 0.14.1 vue: specifier: ^3.5.0 - version: 3.5.0(typescript@5.6.2) + version: 3.5.13(typescript@5.6.2) vue-router: specifier: 4.4.5 - version: 4.4.5(vue@3.5.0(typescript@5.6.2)) + version: 4.4.5(vue@3.5.13(typescript@5.6.2)) devDependencies: typescript: specifier: ^5.6.2 @@ -180,13 +180,13 @@ importers: version: link:../../packages/component-library nuxt: specifier: ^3.10.3 - version: 3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)) + version: 3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)) vue: specifier: ^3.5.0 - version: 3.5.0(typescript@5.6.2) + version: 3.5.13(typescript@5.6.2) vue-router: specifier: ^4.3.0 - version: 4.3.3(vue@3.5.0(typescript@5.6.2)) + version: 4.3.3(vue@3.5.13(typescript@5.6.2)) devDependencies: '@playwright/test': specifier: ^1.45.0 @@ -4303,14 +4303,11 @@ packages: '@vue/compiler-core@3.4.29': resolution: {integrity: sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==} - '@vue/compiler-core@3.5.0': - resolution: {integrity: sha512-ja7cpqAOfw4tyFAxgBz70Z42miNDeaqTxExTsnXDLomRpqfyCgyvZvFp482fmsElpfvsoMJUsvzULhvxUTW6Iw==} - '@vue/compiler-core@3.5.13': resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} - '@vue/compiler-dom@3.5.0': - resolution: {integrity: sha512-xYjUybWZXl+1R/toDy815i4PbeehL2hThiSGkcpmIOCy2HoYyeeC/gAWK/Y/xsoK+GSw198/T5O31bYuQx5uvQ==} + '@vue/compiler-dom@3.4.29': + resolution: {integrity: sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==} '@vue/compiler-dom@3.5.13': resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} @@ -4318,14 +4315,14 @@ packages: '@vue/compiler-sfc@2.7.16': resolution: {integrity: sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==} - '@vue/compiler-sfc@3.5.0': - resolution: {integrity: sha512-B9DgLtrqok2GLuaFjLlSL15ZG3ZDBiitUH1ecex9guh/ZcA5MCdwuVE6nsfQxktuZY/QY0awJ35/ripIviCQTQ==} + '@vue/compiler-sfc@3.4.29': + resolution: {integrity: sha512-zygDcEtn8ZimDlrEQyLUovoWgKQic6aEQqRXce2WXBvSeHbEbcAsXyCk9oG33ZkyWH4sl9D3tkYc1idoOkdqZQ==} '@vue/compiler-sfc@3.5.13': resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} - '@vue/compiler-ssr@3.5.0': - resolution: {integrity: sha512-E263QZmA1dqRd7c3u/sWTLRMpQOT0aZ8av/L9SoD/v/BVMZaWFHPUUBswS+bzrfvG2suJF8vSLKx6k6ba5SUdA==} + '@vue/compiler-ssr@3.4.29': + resolution: {integrity: sha512-rFbwCmxJ16tDp3N8XCx5xSQzjhidYjXllvEcqX/lopkoznlNPz3jyy0WGJCyhAaVQK677WWFt3YO/WUEkMMUFQ==} '@vue/compiler-ssr@3.5.13': resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} @@ -4387,29 +4384,15 @@ packages: typescript: optional: true - '@vue/reactivity@3.5.0': - resolution: {integrity: sha512-Ew3F5riP3B3ZDGjD3ZKb9uZylTTPSqt8hAf4sGbvbjrjDjrFb3Jm15Tk1/w7WwTE5GbQ2Qhwxx1moc9hr8A/OQ==} - '@vue/reactivity@3.5.13': resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} - '@vue/runtime-core@3.5.0': - resolution: {integrity: sha512-mQyW0F9FaNRdt8ghkAs+BMG3iQ7LGgWKOpkzUzR5AI5swPNydHGL5hvVTqFaeMzwecF1g0c86H4yFQsSxJhH1w==} - '@vue/runtime-core@3.5.13': resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} - '@vue/runtime-dom@3.5.0': - resolution: {integrity: sha512-NQQXjpdXgyYVJ2M56FJ+lSJgZiecgQ2HhxhnQBN95FymXegRNY/N2htI7vOTwpP75pfxhIeYOJ8mE8sW8KAW6A==} - '@vue/runtime-dom@3.5.13': resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} - '@vue/server-renderer@3.5.0': - resolution: {integrity: sha512-HyDIFUg+l7L4PKrEnJlCYWHUOlm6NxZhmSxIefZ5MTYjkIPfDfkwhX7hqxAQHfgIAE1uLMLQZwuNR/ozI0NhZg==} - peerDependencies: - vue: 3.5.0 - '@vue/server-renderer@3.5.13': resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} peerDependencies: @@ -4418,9 +4401,6 @@ packages: '@vue/shared@3.4.29': resolution: {integrity: sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA==} - '@vue/shared@3.5.0': - resolution: {integrity: sha512-m9IgiteBpCkFaMNwCOBkFksA7z8QiKc30ooRuoXWUFRDu0mGyNPlFHmbncF0/Kra1RlX8QrmBbRaIxVvikaR0Q==} - '@vue/shared@3.5.13': resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} @@ -8734,8 +8714,8 @@ packages: magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - magic-string@0.30.14: - resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} + magic-string@0.30.15: + resolution: {integrity: sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==} magicast@0.3.4: resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} @@ -12672,14 +12652,6 @@ packages: resolution: {integrity: sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==} deprecated: Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details. - vue@3.5.0: - resolution: {integrity: sha512-1t70favYoFijwfWJ7g81aTd32obGaAnKYE9FNyMgnEzn3F4YncRi/kqAHHKloG0VXTD8vBYMhbgLKCA+Sk6QDw==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - vue@3.5.13: resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} peerDependencies: @@ -13241,7 +13213,7 @@ snapshots: '@babel/generator': 7.24.7 '@babel/helper-module-transforms': 7.24.7(@babel/core@7.12.9) '@babel/helpers': 7.24.7 - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@babel/template': 7.24.7 '@babel/traverse': 7.24.7 '@babel/types': 7.24.7 @@ -16198,12 +16170,12 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@1.3.3(magicast@0.3.4)(nuxt@3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)))(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))': + '@nuxt/devtools-kit@1.3.3(magicast@0.3.4)(nuxt@3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)))(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))': dependencies: '@nuxt/kit': 3.12.2(magicast@0.3.4)(rollup@4.18.0) '@nuxt/schema': 3.12.2(rollup@4.18.0) execa: 7.2.0 - nuxt: 3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)) + nuxt: 3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)) vite: 5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1) transitivePeerDependencies: - magicast @@ -16223,13 +16195,13 @@ snapshots: rc9: 2.1.2 semver: 7.6.2 - '@nuxt/devtools@1.3.3(kp24w7dirm5sk46yjklo4malpi)': + '@nuxt/devtools@1.3.3(u6sbqw2rjfgzaaghhojmlr5bqq)': dependencies: '@antfu/utils': 0.7.8 - '@nuxt/devtools-kit': 1.3.3(magicast@0.3.4)(nuxt@3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)))(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)) + '@nuxt/devtools-kit': 1.3.3(magicast@0.3.4)(nuxt@3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)))(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)) '@nuxt/devtools-wizard': 1.3.3 '@nuxt/kit': 3.12.2(magicast@0.3.4)(rollup@4.18.0) - '@vue/devtools-applet': 7.1.3(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue@3.5.13(typescript@5.6.2)) + '@vue/devtools-applet': 7.1.3(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue@3.5.13(typescript@5.6.2)) '@vue/devtools-core': 7.1.3(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue@3.5.13(typescript@5.6.2)) '@vue/devtools-kit': 7.1.3(vue@3.5.13(typescript@5.6.2)) birpc: 0.2.17 @@ -16247,7 +16219,7 @@ snapshots: launch-editor: 2.7.0 local-pkg: 0.5.0 magicast: 0.3.4 - nuxt: 3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)) + nuxt: 3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)) nypm: 0.3.8 ohash: 1.1.3 pacote: 18.0.6 @@ -17480,7 +17452,7 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@babel/types': 7.24.7 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 @@ -17492,7 +17464,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@babel/types': 7.24.7 '@types/babel__traverse@7.20.6': @@ -18325,7 +18297,7 @@ snapshots: colorette: 2.0.20 consola: 3.2.3 fast-glob: 3.3.2 - magic-string: 0.30.14 + magic-string: 0.30.10 pathe: 1.1.2 perfect-debounce: 1.0.0 transitivePeerDependencies: @@ -18356,7 +18328,7 @@ snapshots: '@unocss/rule-utils': 0.61.0 css-tree: 2.3.1 fast-glob: 3.3.2 - magic-string: 0.30.14 + magic-string: 0.30.10 postcss: 8.4.49 '@unocss/preset-attributify@0.61.0': @@ -18409,7 +18381,7 @@ snapshots: '@unocss/rule-utils@0.61.0': dependencies: '@unocss/core': 0.61.0 - magic-string: 0.30.14 + magic-string: 0.30.10 '@unocss/scope@0.61.0': {} @@ -18451,7 +18423,7 @@ snapshots: '@unocss/transformer-directives': 0.61.0 chokidar: 3.6.0 fast-glob: 3.3.2 - magic-string: 0.30.14 + magic-string: 0.30.10 vite: 5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1) transitivePeerDependencies: - rollup @@ -18602,7 +18574,7 @@ snapshots: dependencies: '@babel/types': 7.24.7 '@rollup/pluginutils': 5.1.0(rollup@4.18.0) - '@vue/compiler-sfc': 3.5.13 + '@vue/compiler-sfc': 3.4.29 ast-kit: 0.12.2 local-pkg: 0.5.0 magic-string-ast: 0.6.1 @@ -18637,8 +18609,8 @@ snapshots: '@babel/core': 7.24.7 '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.24.7 - '@babel/parser': 7.26.3 - '@vue/compiler-sfc': 3.5.13 + '@babel/parser': 7.24.7 + '@vue/compiler-sfc': 3.4.29 '@vue/compiler-core@3.4.29': dependencies: @@ -18648,14 +18620,6 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-core@3.5.0': - dependencies: - '@babel/parser': 7.26.3 - '@vue/shared': 3.5.0 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.2.1 - '@vue/compiler-core@3.5.13': dependencies: '@babel/parser': 7.26.3 @@ -18664,10 +18628,10 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.0': + '@vue/compiler-dom@3.4.29': dependencies: - '@vue/compiler-core': 3.5.0 - '@vue/shared': 3.5.0 + '@vue/compiler-core': 3.4.29 + '@vue/shared': 3.4.29 '@vue/compiler-dom@3.5.13': dependencies: @@ -18682,15 +18646,15 @@ snapshots: optionalDependencies: prettier: 2.8.8 - '@vue/compiler-sfc@3.5.0': + '@vue/compiler-sfc@3.4.29': dependencies: - '@babel/parser': 7.26.3 - '@vue/compiler-core': 3.5.0 - '@vue/compiler-dom': 3.5.0 - '@vue/compiler-ssr': 3.5.0 - '@vue/shared': 3.5.0 + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.29 + '@vue/compiler-dom': 3.4.29 + '@vue/compiler-ssr': 3.4.29 + '@vue/shared': 3.4.29 estree-walker: 2.0.2 - magic-string: 0.30.14 + magic-string: 0.30.10 postcss: 8.4.49 source-map-js: 1.2.1 @@ -18702,14 +18666,14 @@ snapshots: '@vue/compiler-ssr': 3.5.13 '@vue/shared': 3.5.13 estree-walker: 2.0.2 - magic-string: 0.30.14 + magic-string: 0.30.15 postcss: 8.4.49 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.0': + '@vue/compiler-ssr@3.4.29': dependencies: - '@vue/compiler-dom': 3.5.0 - '@vue/shared': 3.5.0 + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 '@vue/compiler-ssr@3.5.13': dependencies: @@ -18720,12 +18684,12 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-applet@7.1.3(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue@3.5.13(typescript@5.6.2))': + '@vue/devtools-applet@7.1.3(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue@3.5.13(typescript@5.6.2))': dependencies: '@vue/devtools-core': 7.1.3(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue@3.5.13(typescript@5.6.2)) '@vue/devtools-kit': 7.1.3(vue@3.5.13(typescript@5.6.2)) '@vue/devtools-shared': 7.3.1 - '@vue/devtools-ui': 7.3.1(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vue@3.5.13(typescript@5.6.2)) + '@vue/devtools-ui': 7.3.1(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vue@3.5.13(typescript@5.6.2)) lodash-es: 4.17.21 perfect-debounce: 1.0.0 shiki: 1.3.0 @@ -18775,7 +18739,7 @@ snapshots: dependencies: rfdc: 1.4.1 - '@vue/devtools-ui@7.3.1(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vue@3.5.13(typescript@5.6.2))': + '@vue/devtools-ui@7.3.1(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(nprogress@0.2.0)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vue@3.5.13(typescript@5.6.2))': dependencies: '@unocss/reset': 0.61.0 '@vue/devtools-shared': 7.3.1 @@ -18783,7 +18747,7 @@ snapshots: '@vueuse/core': 10.11.0(vue@3.5.13(typescript@5.6.2)) '@vueuse/integrations': 10.11.0(axios@1.7.2)(change-case@4.1.2)(focus-trap@7.5.4)(nprogress@0.2.0)(vue@3.5.13(typescript@5.6.2)) colord: 2.9.3 - floating-vue: 5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)) + floating-vue: 5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)) focus-trap: 7.5.4 unocss: 0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)) vue: 3.5.13(typescript@5.6.2) @@ -18817,8 +18781,8 @@ snapshots: dependencies: '@volar/language-core': 1.11.1 '@volar/source-map': 1.11.1 - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 computeds: 0.0.1 minimatch: 9.0.4 muggle-string: 0.3.1 @@ -18830,8 +18794,8 @@ snapshots: '@vue/language-core@2.0.21(typescript@5.2.2)': dependencies: '@volar/language-core': 2.3.0 - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 computeds: 0.0.1 minimatch: 9.0.4 path-browserify: 1.0.1 @@ -18842,8 +18806,8 @@ snapshots: '@vue/language-core@2.0.21(typescript@5.6.2)': dependencies: '@volar/language-core': 2.3.0 - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.4.29 + '@vue/shared': 3.4.29 computeds: 0.0.1 minimatch: 9.0.4 path-browserify: 1.0.1 @@ -18851,31 +18815,15 @@ snapshots: optionalDependencies: typescript: 5.6.2 - '@vue/reactivity@3.5.0': - dependencies: - '@vue/shared': 3.5.0 - '@vue/reactivity@3.5.13': dependencies: '@vue/shared': 3.5.13 - '@vue/runtime-core@3.5.0': - dependencies: - '@vue/reactivity': 3.5.0 - '@vue/shared': 3.5.0 - '@vue/runtime-core@3.5.13': dependencies: '@vue/reactivity': 3.5.13 '@vue/shared': 3.5.13 - '@vue/runtime-dom@3.5.0': - dependencies: - '@vue/reactivity': 3.5.0 - '@vue/runtime-core': 3.5.0 - '@vue/shared': 3.5.0 - csstype: 3.1.3 - '@vue/runtime-dom@3.5.13': dependencies: '@vue/reactivity': 3.5.13 @@ -18883,12 +18831,6 @@ snapshots: '@vue/shared': 3.5.13 csstype: 3.1.3 - '@vue/server-renderer@3.5.0(vue@3.5.0(typescript@5.6.2))': - dependencies: - '@vue/compiler-ssr': 3.5.0 - '@vue/shared': 3.5.0 - vue: 3.5.0(typescript@5.6.2) - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.2.2))': dependencies: '@vue/compiler-ssr': 3.5.13 @@ -18909,8 +18851,6 @@ snapshots: '@vue/shared@3.4.29': {} - '@vue/shared@3.5.0': {} - '@vue/shared@3.5.13': {} '@vue/test-utils@2.4.6': @@ -19355,12 +19295,12 @@ snapshots: ast-kit@0.12.2: dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 pathe: 1.1.2 ast-kit@0.9.5(rollup@4.18.0): dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@rollup/pluginutils': 5.1.0(rollup@4.18.0) pathe: 1.1.2 transitivePeerDependencies: @@ -20179,7 +20119,7 @@ snapshots: constantinople@4.0.1: dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@babel/types': 7.24.7 content-disposition@0.5.2: {} @@ -21913,11 +21853,11 @@ snapshots: flatten@1.0.3: {} - floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)): + floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)): dependencies: '@floating-ui/dom': 1.1.1 - vue: 3.5.0(typescript@5.6.2) - vue-resize: 2.0.0-alpha.1(vue@3.5.0(typescript@5.6.2)) + vue: 3.5.13(typescript@5.6.2) + vue-resize: 2.0.0-alpha.1(vue@3.5.13(typescript@5.6.2)) optionalDependencies: '@nuxt/kit': 3.12.2(magicast@0.3.4)(rollup@4.18.0) @@ -23095,7 +23035,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.24.7 - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -23105,7 +23045,7 @@ snapshots: istanbul-lib-instrument@6.0.2: dependencies: '@babel/core': 7.24.7 - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.2 @@ -24298,13 +24238,13 @@ snapshots: magic-string-ast@0.6.1: dependencies: - magic-string: 0.30.14 + magic-string: 0.30.10 magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - magic-string@0.30.14: + magic-string@0.30.15: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -24928,7 +24868,7 @@ snapshots: node-source-walk@4.3.0: dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 nodemon@2.0.22: dependencies: @@ -25053,10 +24993,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - nuxt@3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.0(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)): + nuxt@3.12.2(@opentelemetry/api@1.9.0)(@parcel/watcher@2.4.1)(@types/node@20.14.5)(@unocss/reset@0.61.0)(axios@1.7.2)(change-case@4.1.2)(encoding@0.1.13)(eslint@8.57.0)(floating-vue@5.2.2(@nuxt/kit@3.12.2(magicast@0.3.4)(rollup@4.18.0))(vue@3.5.13(typescript@5.6.2)))(ioredis@5.4.1)(magicast@0.3.4)(nprogress@0.2.0)(optionator@0.9.4)(rollup@4.18.0)(sass@1.77.6)(stylelint@16.10.0(typescript@5.6.2))(terser@5.31.1)(typescript@5.6.2)(unocss@0.61.0(postcss@8.4.49)(rollup@4.18.0)(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1)))(vite@5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1))(vue-tsc@2.0.21(typescript@5.6.2)): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.3.3(kp24w7dirm5sk46yjklo4malpi) + '@nuxt/devtools': 1.3.3(u6sbqw2rjfgzaaghhojmlr5bqq) '@nuxt/kit': 3.12.2(magicast@0.3.4)(rollup@4.18.0) '@nuxt/schema': 3.12.2(rollup@4.18.0) '@nuxt/telemetry': 2.5.4(magicast@0.3.4)(rollup@4.18.0) @@ -28897,7 +28837,7 @@ snapshots: '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7) '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.7) '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.7) - '@vue/compiler-dom': 3.5.13 + '@vue/compiler-dom': 3.4.29 kolorist: 1.8.0 magic-string: 0.30.10 vite: 5.3.1(@types/node@20.14.5)(sass@1.77.6)(terser@5.31.1) @@ -29083,8 +29023,8 @@ snapshots: dependencies: '@babel/parser': 7.24.7 '@babel/types': 7.24.7 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 + '@vue/compiler-dom': 3.4.29 + '@vue/compiler-sfc': 3.4.29 ast-types: 0.16.1 esm-resolve: 1.0.11 hash-sum: 2.0.0 @@ -29130,23 +29070,14 @@ snapshots: dependencies: vue: 3.5.13(typescript@5.6.2) - vue-resize@2.0.0-alpha.1(vue@3.5.0(typescript@5.6.2)): - dependencies: - vue: 3.5.0(typescript@5.6.2) - vue-resize@2.0.0-alpha.1(vue@3.5.13(typescript@5.6.2)): dependencies: vue: 3.5.13(typescript@5.6.2) - vue-router@4.3.3(vue@3.5.0(typescript@5.6.2)): + vue-router@4.3.3(vue@3.5.13(typescript@5.6.2)): dependencies: '@vue/devtools-api': 6.6.3 - vue: 3.5.0(typescript@5.6.2) - - vue-router@4.4.5(vue@3.5.0(typescript@5.6.2)): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.0(typescript@5.6.2) + vue: 3.5.13(typescript@5.6.2) vue-router@4.4.5(vue@3.5.13(typescript@5.6.2)): dependencies: @@ -29196,16 +29127,6 @@ snapshots: '@vue/compiler-sfc': 2.7.16 csstype: 3.1.3 - vue@3.5.0(typescript@5.6.2): - dependencies: - '@vue/compiler-dom': 3.5.0 - '@vue/compiler-sfc': 3.5.0 - '@vue/runtime-dom': 3.5.0 - '@vue/server-renderer': 3.5.0(vue@3.5.0(typescript@5.6.2)) - '@vue/shared': 3.5.0 - optionalDependencies: - typescript: 5.6.2 - vue@3.5.13(typescript@5.2.2): dependencies: '@vue/compiler-dom': 3.5.13 @@ -29528,7 +29449,7 @@ snapshots: with@7.0.2: dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.24.7 '@babel/types': 7.24.7 assert-never: 1.2.1 babel-walk: 3.0.0-canary-5 From 8037aa2ac513f6ed12accd1f6312a59bd6e85653 Mon Sep 17 00:00:00 2001 From: Nils Date: Fri, 15 Nov 2024 09:36:01 +0100 Subject: [PATCH 03/53] trap focus in popover --- .../mt-bare-popover/mt-bare-popover.spec.ts | 32 +++++++++++++++++++ .../mt-bare-popover/mt-bare-popover.vue | 21 ++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts index d9175af3c..36ae5daaa 100644 --- a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.spec.ts @@ -159,4 +159,36 @@ describe("mt-bare-popover", () => { screen.getByRole("button").getAttribute("id"), ); }); + + it("locks the focus inside the popover when it is open", async () => { + // ARRANGE + render({ + components: { MtBarePopover }, + template: ` + + + + + + `, + }); + + await userEvent.click(screen.getByRole("button")); + + // ACT + await userEvent.keyboard("{Tab}"); + + // focuses the body element + await userEvent.keyboard("{Tab}"); + + // focuses the button + // await userEvent.keyboard("{Tab}"); + + // ASSERT + expect(screen.getByRole("textbox")).toHaveFocus(); + }); }); diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue index 5046964d3..a7f75ef9f 100644 --- a/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue +++ b/packages/component-library/src/components/overlay/mt-bare-popover/mt-bare-popover.vue @@ -25,11 +25,12 @@ - + From 8ebb08820995824647294d2bc94cb01045f2804a Mon Sep 17 00:00:00 2001 From: Nils Date: Sat, 16 Nov 2024 15:46:38 +0100 Subject: [PATCH 06/53] allow changing role of mt-bare-popover-item --- .../mt-bare-popover/sub-components/mt-bare-popover-item.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue b/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue index b3c4c3bc6..e19151477 100644 --- a/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue +++ b/packages/component-library/src/components/overlay/mt-bare-popover/sub-components/mt-bare-popover-item.vue @@ -1,6 +1,6 @@ @@ -362,6 +64,7 @@ export default defineComponent({ display: flex; position: relative; box-shadow: inset 0 -1px 0 var(--color-border-primary-default); + list-style: none; } .mt-tabs--small { @@ -447,31 +150,13 @@ export default defineComponent({ height: 2px; background-color: var(--color-border-brand-selected); z-index: 1; + transition: 0.2s all ease-in-out; } .mt-tabs__slider--error { background-color: var(--color-border-critical-default); } -.mt-tabs__slider--animated { - transition: 0.2s all ease-in-out; -} - -.mt-context-button { - display: flex; - align-items: center; - border-bottom: 1px solid var(--color-border-primary-default); - - & button { - display: flex; - align-items: center; - gap: 4px; - font-size: var(--font-size-s); - line-height: var(--font-line-height-s); - font-family: var(--font-family-body); - } -} - .mt-tabs__error-badge { margin-left: 2px; width: 12px; diff --git a/packages/component-library/src/components/navigation/mt-tabs/sw.tabs.spec.ts b/packages/component-library/src/components/navigation/mt-tabs/sw.tabs.spec.ts deleted file mode 100644 index 5c1ec5726..000000000 --- a/packages/component-library/src/components/navigation/mt-tabs/sw.tabs.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { mount } from "@vue/test-utils"; -import MtTabs from "./mt-tabs.vue"; - -async function createWrapper(customOptions = {}, props = {}) { - return mount(MtTabs, { - props: { - items: [ - { - name: "foo", - label: "Foo", - }, - { - name: "bar", - label: "Bar", - }, - ], - ...props, - }, - global: { - stubs: { - "mt-icon": true, - }, - mocks: { - $device: { - onResize: () => {}, - removeResizeListener: () => {}, - }, - }, - }, - ...customOptions, - }); -} - -describe("src/app/component/navigation/mt-tabs", () => { - let wrapper: undefined | Awaited>; - - afterEach(() => { - if (wrapper) { - wrapper.unmount(); - } - }); - - it("should be a Vue.JS component", async () => { - wrapper = await createWrapper(); - expect(wrapper.vm).toBeTruthy(); - }); - - it("should emit on clicked tab", async () => { - wrapper = await createWrapper(); - - await wrapper.find(".mt-tabs__item[data-item-name=bar]").trigger("click"); - - expect(wrapper.emitted("new-item-active")?.[0]).toStrictEqual(["bar"]); - }); - - it("should emit on clicked vertical tab", async () => { - wrapper = await createWrapper(undefined, { - vertical: true, - }); - - await wrapper.find(".mt-tabs__item[data-item-name=bar]").trigger("click"); - - expect(wrapper.emitted("new-item-active")?.[0]).toStrictEqual(["bar"]); - }); -}); From 6c758196da99d41e6dbde8ab2f5a1cd6ed21558f Mon Sep 17 00:00:00 2001 From: Nils Date: Sat, 16 Nov 2024 20:38:01 +0100 Subject: [PATCH 09/53] allow changing the tab --- .../navigation/mt-tabs/mt-tabs.spec.ts | 30 +++++++++++++++++++ .../components/navigation/mt-tabs/mt-tabs.vue | 9 +++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.spec.ts b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.spec.ts index 2fe1b5f94..d5eed1033 100644 --- a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.spec.ts +++ b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.spec.ts @@ -2,6 +2,7 @@ import { flushPromises } from "@vue/test-utils"; import type { TabItem } from "./mt-tabs.vue"; import MtTabs from "./mt-tabs.vue"; import { render, screen } from "@testing-library/vue"; +import { userEvent } from "@storybook/test"; describe("mt-tabs", () => { it("selects the first tab by default", async () => { @@ -41,4 +42,33 @@ describe("mt-tabs", () => { expect(screen.getByRole("tab", { name: "Tab 1" })).toHaveAttribute("aria-selected", "false"); expect(screen.getByRole("tab", { name: "Tab 2" })).toHaveAttribute("aria-selected", "true"); }); + + it("selects the tab when clicked", async () => { + // ARRANGE + const items: TabItem[] = [ + { label: "Tab 1", name: "tab1" }, + { label: "Tab 2", name: "tab2" }, + ]; + + const handler = vi.fn(); + + render(MtTabs, { + props: { + items, + "onNew-item-active": handler, + }, + }); + + await flushPromises(); + + // ACT + await userEvent.click(screen.getByRole("tab", { name: "Tab 2" })); + + // ASSERT + expect(screen.getByRole("tab", { name: "Tab 1" })).toHaveAttribute("aria-selected", "false"); + expect(screen.getByRole("tab", { name: "Tab 2" })).toHaveAttribute("aria-selected", "true"); + + expect(handler).toHaveBeenCalledOnce(); + expect(handler).toHaveBeenLastCalledWith("tab2"); + }); }); diff --git a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue index 251b8d363..c987c7e99 100644 --- a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue +++ b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue @@ -9,6 +9,8 @@ }, ]" role="tab" + @click="() => changeActiveTab(item.name)" + :data-text="item.label" :aria-selected="item.name === nameOfActiveItem" > {{ item.label }} @@ -38,7 +40,7 @@ export interface TabItem { } // TODO: IMO it makes more sense to use v-model for the component -defineEmits(["new-item-active"]); +const emit = defineEmits(["new-item-active"]); const props = defineProps<{ items: TabItem[]; @@ -47,6 +49,11 @@ const props = defineProps<{ defaultItem?: string; }>(); +function changeActiveTab(tabName: string) { + nameOfActiveItem.value = tabName; + emit("new-item-active", tabName); +} + const nameOfActiveItem = ref("unknown"); onMounted(() => { const firstItem = props.items.at(0); From 7ccba7b4e81559bec312f5918c558b596fe465db Mon Sep 17 00:00:00 2001 From: Nils Date: Sat, 16 Nov 2024 21:08:32 +0100 Subject: [PATCH 10/53] add slider --- .../components/navigation/mt-tabs/mt-tabs.vue | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue index c987c7e99..9d698e378 100644 --- a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue +++ b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue @@ -1,7 +1,8 @@ @@ -49,6 +52,27 @@ const props = defineProps<{ defaultItem?: string; }>(); +const tabListRef = ref(null); + +const sliderStyles = computed(() => { + if (!tabListRef.value || nameOfActiveItem.value === "unknown") return undefined; + + const activeTab = tabListRef.value.querySelector( + `#mt-tabs__item--${nameOfActiveItem.value}`, + ) as HTMLElement | null; + + if (!activeTab) + throw new Error( + "Failed to render mt-tabs; Tab not found, please make sure the tab exists. Searched for tab with id: mt-tabs__item--" + + nameOfActiveItem.value, + ); + + return { + width: `${activeTab.offsetWidth}px`, + left: `${activeTab.offsetLeft}px`, + }; +}); + function changeActiveTab(tabName: string) { nameOfActiveItem.value = tabName; emit("new-item-active", tabName); @@ -157,7 +181,7 @@ onMounted(() => { height: 2px; background-color: var(--color-border-brand-selected); z-index: 1; - transition: 0.2s all ease-in-out; + transition: 0.25s all cubic-bezier(0.77, 0, 0.175, 1); } .mt-tabs__slider--error { From 6fa27fd5532cd4fe721a3bb67155a98d483da1f9 Mon Sep 17 00:00:00 2001 From: Nils Date: Sat, 16 Nov 2024 21:09:37 +0100 Subject: [PATCH 11/53] add tablist role --- .../src/components/navigation/mt-tabs/mt-tabs.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue index 9d698e378..099d60487 100644 --- a/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue +++ b/packages/component-library/src/components/navigation/mt-tabs/mt-tabs.vue @@ -1,5 +1,5 @@ +