srcdev-nuxt-components 9.4.4 → 9.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/.claude/commands/migrate-component.md +68 -0
  2. package/.claude/component-ledger/artifact-url.txt +1 -0
  3. package/.claude/component-ledger/audit.json +1 -0
  4. package/.claude/component-ledger/build.mjs +111 -0
  5. package/.claude/component-ledger/output.html +559 -0
  6. package/.claude/component-ledger/template.html +559 -0
  7. package/.claude/hooks/refresh-component-ledger.sh +32 -0
  8. package/.claude/settings.json +10 -0
  9. package/.claude/skills/components/animated-svg-text.md +78 -0
  10. package/.claude/skills/components/canvas-switcher.md +61 -0
  11. package/.claude/skills/components/clip-element.md +67 -0
  12. package/.claude/skills/components/clipped-panel.md +64 -0
  13. package/.claude/skills/components/deep-expanding-menu-classic.md +94 -0
  14. package/.claude/skills/components/deep-expanding-menu.md +92 -0
  15. package/.claude/skills/components/display-banner.md +60 -0
  16. package/.claude/skills/components/display-tooltip-defined.md +136 -0
  17. package/.claude/skills/components/display-tooltip.md +84 -0
  18. package/.claude/skills/composable-tooltips-guide.md +10 -0
  19. package/.claude/skills/index.md +7 -1
  20. package/.claude/skills/storybook-add-story.md +30 -0
  21. package/.vscode/srcdev-component-animated-svg-text.code-snippets +15 -0
  22. package/.vscode/srcdev-component-canvas-switcher.code-snippets +9 -0
  23. package/.vscode/srcdev-component-clip-element.code-snippets +20 -0
  24. package/.vscode/srcdev-component-clipped-panel.code-snippets +23 -0
  25. package/.vscode/srcdev-component-deep-expanding-menu-classic.code-snippets +9 -0
  26. package/.vscode/srcdev-component-deep-expanding-menu.code-snippets +9 -0
  27. package/.vscode/srcdev-component-display-banner.code-snippets +30 -0
  28. package/.vscode/srcdev-component-display-tooltip-defined.code-snippets +14 -0
  29. package/.vscode/srcdev-component-display-tooltip.code-snippets +27 -0
  30. package/app/components/01.atoms/animations/animated-svg-text/AnimatedSvgText.vue +58 -0
  31. package/app/components/01.atoms/animations/animated-svg-text/CONSUMER-STYLING.md +34 -0
  32. package/app/components/01.atoms/animations/animated-svg-text/stories/AnimatedSvgText.stories.ts +69 -0
  33. package/app/components/01.atoms/animations/animated-svg-text/tests/AnimatedSvgText.spec.ts +63 -0
  34. package/app/components/01.atoms/animations/animated-svg-text/tests/__snapshots__/AnimatedSvgText.spec.ts.snap +7 -0
  35. package/app/components/01.atoms/animations/clip-element/CONSUMER-STYLING.md +27 -0
  36. package/app/components/{clip-element → 01.atoms/animations/clip-element}/ClipElement.vue +16 -11
  37. package/app/components/01.atoms/animations/clip-element/stories/ClipElement.stories.ts +133 -0
  38. package/app/components/01.atoms/animations/clip-element/tests/ClipElement.spec.ts +70 -0
  39. package/app/components/01.atoms/animations/clip-element/tests/__snapshots__/ClipElement.spec.ts.snap +7 -0
  40. package/app/components/01.atoms/canvas-switcher/CONSUMER-STYLING.md +27 -0
  41. package/app/components/01.atoms/canvas-switcher/CanvasSwitcher.vue +111 -0
  42. package/app/components/01.atoms/canvas-switcher/stories/CanvasSwitcher.stories.ts +75 -0
  43. package/app/components/01.atoms/canvas-switcher/tests/CanvasSwitcher.spec.ts +67 -0
  44. package/app/components/01.atoms/clipped-panel/CONSUMER-STYLING.md +39 -0
  45. package/app/components/01.atoms/clipped-panel/ClippedPanel.vue +68 -0
  46. package/app/components/01.atoms/clipped-panel/stories/ClippedPanel.stories.ts +105 -0
  47. package/app/components/01.atoms/clipped-panel/tests/ClippedPanel.spec.ts +67 -0
  48. package/app/components/01.atoms/clipped-panel/tests/__snapshots__/ClippedPanel.spec.ts.snap +3 -0
  49. package/app/components/01.atoms/display-banner/CONSUMER-STYLING.md +35 -0
  50. package/app/components/{display-banner → 01.atoms/display-banner}/DisplayBanner.vue +13 -35
  51. package/app/components/01.atoms/display-banner/stories/DisplayBanner.stories.ts +100 -0
  52. package/app/components/01.atoms/display-banner/tests/DisplayBanner.spec.ts +78 -0
  53. package/app/components/01.atoms/display-banner/tests/__snapshots__/DisplayBanner.spec.ts.snap +8 -0
  54. package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +62 -0
  55. package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +185 -0
  56. package/app/components/01.atoms/display-tooltip/stories/DisplayTooltip.stories.ts +94 -0
  57. package/app/components/01.atoms/display-tooltip/tests/DisplayTooltip.spec.ts +75 -0
  58. package/app/components/01.atoms/display-tooltip/tests/__snapshots__/DisplayTooltip.spec.ts.snap +12 -0
  59. package/app/components/02.molecules/display-tooltip-defined/CONSUMER-STYLING.md +42 -0
  60. package/app/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue +103 -0
  61. package/app/components/02.molecules/display-tooltip-defined/stories/DisplayTooltipDefined.stories.ts +126 -0
  62. package/app/components/02.molecules/display-tooltip-defined/tests/DisplayTooltipDefined.spec.ts +66 -0
  63. package/app/components/02.molecules/display-tooltip-defined/tests/__snapshots__/DisplayTooltipDefined.spec.ts.snap +17 -0
  64. package/app/components/02.molecules/navigation/deep-expanding-menu/CONSUMER-STYLING.md +44 -0
  65. package/app/components/{deep-expanding-menu → 02.molecules/navigation/deep-expanding-menu}/DeepExpandingMenu.vue +53 -64
  66. package/app/components/02.molecules/navigation/deep-expanding-menu/stories/DeepExpandingMenu.stories.ts +79 -0
  67. package/app/components/02.molecules/navigation/deep-expanding-menu/tests/DeepExpandingMenu.spec.ts +92 -0
  68. package/app/components/02.molecules/navigation/deep-expanding-menu/tests/__snapshots__/DeepExpandingMenu.spec.ts.snap +17 -0
  69. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/CONSUMER-STYLING.md +40 -0
  70. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/DeepExpandingMenuClassic.vue +200 -0
  71. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/stories/DeepExpandingMenuClassic.stories.ts +79 -0
  72. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/tests/DeepExpandingMenuClassic.spec.ts +82 -0
  73. package/app/components/02.molecules/navigation/deep-expanding-menu-classic/tests/__snapshots__/DeepExpandingMenuClassic.spec.ts.snap +18 -0
  74. package/app/types/components/display-tooltip-defined.d.ts +10 -0
  75. package/app/types/components/index.ts +1 -0
  76. package/package.json +1 -1
  77. package/app/components/animated-svg-text/AnimatedSvgText.vue +0 -89
  78. package/app/components/canvas-switcher/CanvasSwitcher.vue +0 -104
  79. package/app/components/clipped-panels/ClippedPanel.vue +0 -87
  80. package/app/components/deep-expanding-menu/DeepExpandingMenuOld.vue +0 -218
  81. package/app/components/display-details/DisplayDetailsCore.vue +0 -122
  82. package/app/components/display-tooltip/DisplayTooltip.vue +0 -170
  83. package/app/components/display-tooltip/DisplayTooltipDefined.vue +0 -103
  84. package/app/components/magnetic-navigation/MagneticNavigation.vue +0 -162
@@ -0,0 +1,200 @@
1
+ <template>
2
+ <component :is="tag" class="deep-expanding-menu-classic" :class="[elementClasses]">
3
+ <div class="inner">
4
+ <template v-for="(link, key) in navLinks" :key="key">
5
+ <NuxtLink v-if="link.path" :to="link.path" class="navigation-link">{{ link.name }}</NuxtLink>
6
+ <details v-else ref="navigationGroupRef" class="navigation-group" name="navigation-group">
7
+ <summary class="navigation-group-toggle">
8
+ <span>{{ link.name }}</span>
9
+ <Icon name="bi:caret-down-fill" class="icon" />
10
+ </summary>
11
+ <div class="navigation-group-panel">
12
+ <h4 class="page-heading-4 mb-6">{{ link.childLinksTitle }}</h4>
13
+ <ul class="navigation-group-list">
14
+ <li v-for="childLink in link.childLinks" :key="childLink.name" class="navigation-group-item">
15
+ <NuxtLink :to="childLink.path" class="navigation-group-link">{{ childLink.name }}</NuxtLink>
16
+ </li>
17
+ </ul>
18
+ </div>
19
+ </details>
20
+ </template>
21
+ </div>
22
+ </component>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { onClickOutside } from "@vueuse/core";
27
+ import type { ResponsiveHeaderNavItem } from "~/types/components";
28
+
29
+ interface Props {
30
+ tag?: "div" | "section" | "nav" | "ul" | "ol";
31
+ navLinks?: ResponsiveHeaderNavItem[];
32
+ styleClassPassthrough?: string | string[];
33
+ }
34
+
35
+ const props = withDefaults(defineProps<Props>(), {
36
+ tag: "nav",
37
+ navLinks: () => [],
38
+ styleClassPassthrough: () => [],
39
+ });
40
+
41
+ const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
42
+
43
+ const navigationGroupRef = useTemplateRef<HTMLElement[]>("navigationGroupRef");
44
+
45
+ watch(
46
+ () => props.styleClassPassthrough,
47
+ () => {
48
+ resetElementClasses(props.styleClassPassthrough);
49
+ }
50
+ );
51
+
52
+ onMounted(() => {
53
+ navigationGroupRef.value?.forEach((element, index) => {
54
+ onClickOutside(element, () => {
55
+ navigationGroupRef.value?.[index]?.removeAttribute("open");
56
+ });
57
+ });
58
+ });
59
+ </script>
60
+
61
+ <style lang="css">
62
+ @layer components {
63
+ @layer popover-setup {
64
+ .deep-expanding-menu-classic {
65
+ container-type: inline-size;
66
+ display: grid;
67
+ grid-template-areas: "element-stack";
68
+ align-items: center;
69
+ gap: var(--deep-expanding-menu-classic-gap, 1.2rem);
70
+
71
+ .inner {
72
+ grid-area: element-stack;
73
+ display: flex;
74
+ gap: var(--deep-expanding-menu-classic-item-gap, 2.4rem);
75
+ align-items: center;
76
+ z-index: 1;
77
+
78
+ .navigation-link,
79
+ .navigation-group-toggle {
80
+ all: unset;
81
+ border-bottom: var(--deep-expanding-menu-classic-link-border-width, 0.2rem) solid transparent;
82
+ padding-block: var(--deep-expanding-menu-classic-link-padding-block, 0.8rem);
83
+
84
+ transition: border-color 200ms;
85
+
86
+ &:hover,
87
+ &:focus,
88
+ &:focus-visible {
89
+ cursor: pointer;
90
+ border-color: var(
91
+ --deep-expanding-menu-classic-link-border-colour-hover,
92
+ light-dark(var(--blue-10), var(--slate-00))
93
+ );
94
+ }
95
+ }
96
+
97
+ .navigation-group {
98
+ --_icon-transform: scaleY(1);
99
+
100
+ display: grid;
101
+ grid-template-areas: "details-stack";
102
+ z-index: 1;
103
+ position: relative;
104
+
105
+ summary::-webkit-details-marker,
106
+ summary::marker {
107
+ display: none;
108
+ }
109
+
110
+ &[open] {
111
+ --_icon-transform: scaleY(-1);
112
+ }
113
+
114
+ .navigation-group-toggle {
115
+ grid-area: details-stack;
116
+
117
+ display: flex !important;
118
+ align-items: center;
119
+ gap: 1.2rem;
120
+ list-style: none;
121
+
122
+ .icon {
123
+ display: block;
124
+ font-size: var(--deep-expanding-menu-classic-icon-size, 1.2rem);
125
+
126
+ transform: var(--_icon-transform);
127
+ transition: transform 200ms;
128
+ }
129
+ }
130
+
131
+ .navigation-group-panel {
132
+ display: grid;
133
+ grid-area: details-stack;
134
+ z-index: 2;
135
+ position: absolute;
136
+ inset: auto;
137
+ top: var(--deep-expanding-menu-classic-panel-offset-top, 4rem);
138
+ left: 0rem;
139
+ gap: var(--deep-expanding-menu-classic-panel-list-gap, 1.2rem);
140
+
141
+ width: var(--deep-expanding-menu-classic-panel-width, 20rem);
142
+
143
+ @media screen and (min-width: 768px) {
144
+ width: var(--deep-expanding-menu-classic-panel-width-tablet, 40rem);
145
+ }
146
+
147
+ @media screen and (min-width: 1024px) {
148
+ width: var(--deep-expanding-menu-classic-panel-width-desktop, 60rem);
149
+ }
150
+
151
+ background-color: var(--deep-expanding-menu-classic-panel-background-colour, white);
152
+ border: var(--deep-expanding-menu-classic-panel-border-width, 0.1rem) solid
153
+ var(--deep-expanding-menu-classic-panel-border-colour, black);
154
+ border-radius: var(--deep-expanding-menu-classic-panel-border-radius, 1.2rem);
155
+ box-shadow: var(--deep-expanding-menu-classic-panel-shadow, 0 0 1rem rgba(0, 0, 0, 0.1));
156
+ padding: var(--deep-expanding-menu-classic-panel-padding, 1.2rem);
157
+ overflow: clip;
158
+
159
+ h4 {
160
+ color: var(--deep-expanding-menu-classic-panel-heading-colour, var(--slate-10));
161
+ }
162
+
163
+ .navigation-group-list {
164
+ display: grid;
165
+ grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
166
+ gap: var(--deep-expanding-menu-classic-panel-list-gap, 1.2rem);
167
+ padding-inline-start: 0;
168
+ margin-block-end: 0.8rem;
169
+
170
+ .navigation-group-item {
171
+ display: block;
172
+
173
+ a.navigation-group-link {
174
+ display: inline-block;
175
+ color: var(--deep-expanding-menu-classic-group-link-colour, var(--slate-10));
176
+ text-decoration: none;
177
+ padding-block: 0.8rem;
178
+
179
+ border-bottom: var(--deep-expanding-menu-classic-link-border-width, 0.2rem) solid transparent;
180
+
181
+ transition: border-color 200ms;
182
+
183
+ &:hover,
184
+ &:focus-visible {
185
+ cursor: pointer;
186
+ border-color: var(
187
+ --deep-expanding-menu-classic-group-link-border-colour-hover,
188
+ var(--slate-10)
189
+ );
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ }
200
+ </style>
@@ -0,0 +1,79 @@
1
+ import DeepExpandingMenuClassic from "../DeepExpandingMenuClassic.vue";
2
+ import type { Meta, StoryObj } from "@nuxtjs/storybook";
3
+ import type { ResponsiveHeaderNavItem } from "~/types/components";
4
+
5
+ const navLinks: ResponsiveHeaderNavItem[] = [
6
+ { name: "Home", path: "/" },
7
+ {
8
+ name: "Services",
9
+ childLinksTitle: "Our services",
10
+ childLinks: [
11
+ { name: "Haircuts", path: "/services/haircuts" },
12
+ { name: "Colouring", path: "/services/colouring" },
13
+ { name: "Styling", path: "/services/styling" },
14
+ ],
15
+ },
16
+ { name: "Contact", path: "/contact" },
17
+ ];
18
+
19
+ const meta: Meta<typeof DeepExpandingMenuClassic> = {
20
+ title: "Molecules/DeepExpandingMenuClassic",
21
+ component: DeepExpandingMenuClassic,
22
+ argTypes: {
23
+ tag: {
24
+ control: { type: "select" },
25
+ options: ["div", "section", "nav", "ul", "ol"],
26
+ description: "Root element tag",
27
+ table: { category: "Basic" },
28
+ },
29
+ navLinks: { table: { disable: true } },
30
+ styleClassPassthrough: { table: { disable: true } },
31
+ },
32
+ args: {
33
+ tag: "nav",
34
+ navLinks,
35
+ },
36
+ parameters: {
37
+ docs: {
38
+ description: {
39
+ component:
40
+ "`<details>`/`<summary>`-based fallback implementation of `DeepExpandingMenu`, using `onClickOutside` to close an open group instead of CSS anchor-positioning/Popover API — use this when the modern implementation's browser support (see its own docs) isn't acceptable.",
41
+ },
42
+ },
43
+ },
44
+ };
45
+
46
+ export default meta;
47
+ type Story = StoryObj<typeof DeepExpandingMenuClassic>;
48
+
49
+ export const Default: Story = {
50
+ render: (args) => ({
51
+ components: { DeepExpandingMenuClassic },
52
+ setup() {
53
+ return { args };
54
+ },
55
+ template: `<DeepExpandingMenuClassic v-bind="args" style="padding: 4rem;" />`,
56
+ }),
57
+ };
58
+
59
+ export const CustomColours: Story = {
60
+ render: (args) => ({
61
+ components: { DeepExpandingMenuClassic },
62
+ setup() {
63
+ return { args };
64
+ },
65
+ template: `
66
+ <DeepExpandingMenuClassic
67
+ v-bind="args"
68
+ style="padding: 4rem; --deep-expanding-menu-classic-panel-background-colour: #1a1a1a; --deep-expanding-menu-classic-panel-border-colour: transparent; --deep-expanding-menu-classic-group-link-colour: white; --deep-expanding-menu-classic-panel-heading-colour: #aaaaaa;"
69
+ />
70
+ `,
71
+ }),
72
+ parameters: {
73
+ docs: {
74
+ description: {
75
+ story: "Overriding the public tokens via inline `--deep-expanding-menu-classic-*` custom properties.",
76
+ },
77
+ },
78
+ },
79
+ };
@@ -0,0 +1,82 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { mountSuspended } from "@nuxt/test-utils/runtime";
3
+ import DeepExpandingMenuClassic from "../DeepExpandingMenuClassic.vue";
4
+ import type { ResponsiveHeaderNavItem } from "~/types/components";
5
+
6
+ const defaultNavLinks: ResponsiveHeaderNavItem[] = [
7
+ { name: "Home", path: "/" },
8
+ {
9
+ name: "Services",
10
+ childLinksTitle: "Our services",
11
+ childLinks: [
12
+ { name: "Haircuts", path: "/services/haircuts" },
13
+ { name: "Colouring", path: "/services/colouring" },
14
+ ],
15
+ },
16
+ { name: "Contact", path: "/contact" },
17
+ ];
18
+
19
+ describe("DeepExpandingMenuClassic", () => {
20
+ it("mounts without error", async () => {
21
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
22
+ expect(wrapper.vm).toBeTruthy();
23
+ });
24
+
25
+ it("renders correct HTML structure", async () => {
26
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
27
+ expect(wrapper.html()).toMatchSnapshot();
28
+ });
29
+
30
+ it("renders a <nav> by default", async () => {
31
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
32
+ expect(wrapper.element.tagName.toLowerCase()).toBe("nav");
33
+ });
34
+
35
+ it("renders the given tag", async () => {
36
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, {
37
+ props: { navLinks: defaultNavLinks, tag: "div" },
38
+ });
39
+ expect(wrapper.element.tagName.toLowerCase()).toBe("div");
40
+ });
41
+
42
+ it("renders a direct link for items with a path", async () => {
43
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
44
+ const links = wrapper.findAll(".navigation-link");
45
+ expect(links.map((l) => l.text())).toEqual(["Home", "Contact"]);
46
+ });
47
+
48
+ it("renders a <details> group for items with childLinks", async () => {
49
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
50
+ expect(wrapper.find("details.navigation-group").exists()).toBe(true);
51
+ expect(wrapper.find(".navigation-group-toggle").text()).toContain("Services");
52
+ });
53
+
54
+ it("renders each child link inside the group panel", async () => {
55
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
56
+ const childLinks = wrapper.findAll(".navigation-group-link");
57
+ expect(childLinks.map((l) => l.text())).toEqual(["Haircuts", "Colouring"]);
58
+ });
59
+
60
+ it("renders the childLinksTitle heading", async () => {
61
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, { props: { navLinks: defaultNavLinks } });
62
+ expect(wrapper.find(".navigation-group-panel h4").text()).toBe("Our services");
63
+ });
64
+
65
+ it("applies styleClassPassthrough classes", async () => {
66
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, {
67
+ props: { navLinks: defaultNavLinks, styleClassPassthrough: ["custom-class"] },
68
+ });
69
+ expect(wrapper.classes()).toContain("custom-class");
70
+ });
71
+
72
+ it("resets classes when styleClassPassthrough prop changes", async () => {
73
+ const wrapper = await mountSuspended(DeepExpandingMenuClassic, {
74
+ props: { navLinks: defaultNavLinks, styleClassPassthrough: ["initial-class"] },
75
+ });
76
+ expect(wrapper.classes()).toContain("initial-class");
77
+
78
+ await wrapper.setProps({ styleClassPassthrough: ["updated-class"] });
79
+ expect(wrapper.classes()).not.toContain("initial-class");
80
+ expect(wrapper.classes()).toContain("updated-class");
81
+ });
82
+ });
@@ -0,0 +1,18 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`DeepExpandingMenuClassic > renders correct HTML structure 1`] = `
4
+ "<nav class="deep-expanding-menu-classic">
5
+ <div class="inner"><a href="/" class="navigation-link">Home</a>
6
+ <details class="navigation-group" name="navigation-group">
7
+ <summary class="navigation-group-toggle"><span>Services</span><span class="iconify i-bi:caret-down-fill icon" aria-hidden="true"></span></summary>
8
+ <div class="navigation-group-panel">
9
+ <h4 class="page-heading-4 mb-6">Our services</h4>
10
+ <ul class="navigation-group-list">
11
+ <li class="navigation-group-item"><a href="/services/haircuts" class="navigation-group-link">Haircuts</a></li>
12
+ <li class="navigation-group-item"><a href="/services/colouring" class="navigation-group-link">Colouring</a></li>
13
+ </ul>
14
+ </div>
15
+ </details><a href="/contact" class="navigation-link">Contact</a>
16
+ </div>
17
+ </nav>"
18
+ `;
@@ -0,0 +1,10 @@
1
+ export interface TooltipContentTextItem {
2
+ tag: string
3
+ text: string
4
+ }
5
+
6
+ export interface TooltipContentText {
7
+ tooltipTitle?: TooltipContentTextItem
8
+ tooltipContent?: TooltipContentTextItem
9
+ tooltipAction?: TooltipContentTextItem
10
+ }
@@ -16,3 +16,4 @@ export * from "./social-icons-list.d"
16
16
  export * from "./content-docs.d"
17
17
  export * from "./breadcrumb"
18
18
  export * from "./cookie-consent-banner.d"
19
+ export * from "./display-tooltip-defined.d"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "9.4.4",
4
+ "version": "9.4.5",
5
5
  "main": "nuxt.config.ts",
6
6
  "types": "types.d.ts",
7
7
  "license": "MIT",
@@ -1,89 +0,0 @@
1
- <template>
2
- <div class="animated-svg-text" :class="[elementClasses]">
3
- <slot name="text"></slot>
4
- </div>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- const props = defineProps({
9
- styleClassPassthrough: {
10
- type: [String, Array] as PropType<string | string[]>,
11
- default: () => [],
12
- },
13
- })
14
-
15
- const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
16
-
17
- watch(
18
- () => props.styleClassPassthrough,
19
- () => {
20
- resetElementClasses(props.styleClassPassthrough)
21
- }
22
- )
23
- </script>
24
-
25
- <style lang="css">
26
- @layer components {
27
-
28
- @keyframes animatedSvgText {
29
- 0% {
30
- fill: transparent;
31
- stroke-dashoffset: var(--_animated-svg-text-stroke-dasharray);
32
- stroke-width: 0.3;
33
- }
34
- 70% {
35
- fill: transparent;
36
- stroke-width: 0.3;
37
- }
38
- 100% {
39
- fill: var(--_animated-svg-fill-color);
40
- stroke-dashoffset: 0;
41
- stroke-width: 0;
42
- }
43
- }
44
-
45
- html {
46
-
47
- &[data-color-scheme='light'] {
48
- .animated-svg-text {
49
- --_animated-svg-text-color: var(--_animated-svg-text-stroke-light);
50
- --_animated-svg-fill-color: var(--_animated-svg-text-fill-light);
51
- }
52
- }
53
- &[data-color-scheme='dark'] {
54
- .animated-svg-text {
55
- --_animated-svg-text-color: var(--_animated-svg-text-stroke-dark);
56
- --_animated-svg-fill-color: var(--_animated-svg-text-fill-dark);
57
- }
58
- }
59
- &[data-color-scheme='auto'] {
60
- .animated-svg-text {
61
- @media (prefers-color-scheme: light) {
62
- --_animated-svg-text-color: var(--_animated-svg-text-stroke-light);
63
- --_animated-svg-fill-color: var(--_animated-svg-text-fill-light);
64
- }
65
-
66
- @media (prefers-color-scheme: dark) {
67
- --_animated-svg-text-color: var(--_animated-svg-text-stroke-dark);
68
- --_animated-svg-fill-color: var(--_animated-svg-text-fill-dark);
69
- }
70
- }
71
- }
72
-
73
- .animated-svg-text {
74
-
75
- --_animated-svg-text-color: var(--_animated-svg-text-stroke-light):
76
- --_animated-svg-fill-color: var(--_animated-svg-text-fill-light);
77
-
78
- svg path {
79
- stroke: var(--_animated-svg-text-color);
80
- stroke-width: 0.3;
81
- stroke-dasharray: var(--_animated-svg-text-stroke-dasharray);
82
- stroke-dashoffset: var(--_animated-svg-text-stroke-dasharray);
83
- animation: animatedSvgText var(--_animated-svg-animation-duration) linear 1 forwards;
84
- }
85
- }
86
-
87
- }
88
- }
89
- </style>
@@ -1,104 +0,0 @@
1
- <template>
2
- <div class="canvas-switcher">
3
- <p>Canvas switcher</p>
4
- <ul class="canvas-switcher mbe-20">
5
- <li>
6
- <button type="button" @click.stop.prevent="updateCanvas('mobileCanvas')">
7
- <Icon name="ic:baseline-phone-iphone" class="icon" :class="[{ current: canvasName === 'mobileCanvas' }]" />
8
- </button>
9
- </li>
10
- <li>
11
- <button type="button" @click.stop.prevent="updateCanvas('tabletCanvas')">
12
- <Icon name="ic:baseline-tablet-mac" class="icon" :class="[{ current: canvasName === 'tabletCanvas' }]" />
13
- </button>
14
- </li>
15
- <li>
16
- <button type="button" @click.stop.prevent="updateCanvas('laptopCanvas')">
17
- <Icon name="ic:baseline-laptop-mac" class="icon" :class="[{ current: canvasName === 'laptopCanvas' }]" />
18
- </button>
19
- </li>
20
- <li>
21
- <button type="button" @click.stop.prevent="updateCanvas('desktopCanvas')">
22
- <Icon name="ic:outline-desktop-mac" class="icon" :class="[{ current: canvasName === 'desktopCanvas' }]" />
23
- </button>
24
- </li>
25
- <li>
26
- <button type="button" @click.stop.prevent="updateCanvas('fullWidthCanvas')">
27
- <Icon
28
- name="pixelarticons:viewport-wide"
29
- class="icon"
30
- :class="[{ current: canvasName === 'fullWidthCanvas' }]"
31
- />
32
- </button>
33
- </li>
34
- </ul>
35
- </div>
36
- </template>
37
-
38
- <script setup lang="ts">
39
- import type { MediaCanvas } from "../../types/components";
40
-
41
- const canvasName = defineModel<MediaCanvas>("canvasName");
42
-
43
- const updateCanvas = (setCanvas: MediaCanvas) => {
44
- canvasName.value = setCanvas;
45
- };
46
- </script>
47
-
48
- <style lang="css">
49
- @layer components {
50
- .canvas-switcher {
51
- display: flex;
52
- align-items: center;
53
- gap: 20px;
54
-
55
- ul {
56
- display: flex;
57
- gap: 10px;
58
- list-style-type: none;
59
- margin: 0;
60
- padding: 0;
61
-
62
- li {
63
- button {
64
- all: unset;
65
- display: flex;
66
- align-items: center;
67
- justify-content: center;
68
- padding: 5px;
69
- border: 0px solid light-dark(var(--slate-10), var(--slate-02));
70
- border-radius: 4px;
71
- cursor: pointer;
72
-
73
- .icon {
74
- color: light-dark(var(--slate-10), var(--slate-02));
75
-
76
- width: 24px;
77
- height: 24px;
78
-
79
- &.current {
80
- color: light-dark(var(--green-10), var(--green-04));
81
- }
82
- }
83
- }
84
- }
85
- }
86
- }
87
-
88
- .mobileCanvas {
89
- max-width: 412px;
90
- }
91
- .tabletCanvas {
92
- max-width: 768px;
93
- }
94
- .laptopCanvas {
95
- max-width: 1064px;
96
- }
97
- .desktopCanvas {
98
- max-width: 1280px;
99
- }
100
- .fullWidthCanvas {
101
- max-width: unset;
102
- }
103
- }
104
- </style>
@@ -1,87 +0,0 @@
1
- <template>
2
- <component :is="tag" class="clipped-panel" :class="[variant, elementClasses]">
3
- <slot name="default"></slot>
4
- </component>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- const props = defineProps({
9
- tag: {
10
- type: String,
11
- default: "div",
12
- validator(value: string) {
13
- return [
14
- "div",
15
- "p",
16
- "span",
17
- "section",
18
- "article",
19
- "aside",
20
- "header",
21
- "footer",
22
- "main",
23
- "nav",
24
- "ul",
25
- "ol",
26
- ].includes(value)
27
- },
28
- },
29
- variant: {
30
- type: String,
31
- default: "square",
32
- validator(value: string) {
33
- return ["circle-cutout", "rectangle", "square"].includes(value)
34
- },
35
- },
36
- styleClassPassthrough: {
37
- type: [String, Array] as PropType<string | string[]>,
38
- default: () => [],
39
- },
40
- })
41
-
42
- const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
43
-
44
- watch(
45
- () => props.styleClassPassthrough,
46
- () => {
47
- resetElementClasses(props.styleClassPassthrough)
48
- }
49
- )
50
- </script>
51
-
52
- <style lang="css">
53
- @layer components {
54
- .clipped-panel {
55
- --_foreground-color: light-dark(hsl(0, 29%, 3%), hsl(0, 0%, 92%));
56
-
57
- /* Component styles */
58
-
59
- background-color: red;
60
- /* color: var(--_foreground-color); */
61
- outline: 1px solid var(--_foreground-color);
62
- /* box-shadow: 5px 5px 5px 5px white; */
63
-
64
- aspect-ratio: 1;
65
-
66
- &.rectangle {
67
- --_max-x-position: 300px;
68
- --_curve-radius: 10px;
69
-
70
- clip-path: path(
71
- "M 10, 50 L 140, 50 A 10, 10, 0, 0, 0 150, 40 L 150, 10 A 10, 10, 0, 0, 1 160, 0 L 290, 0 A 10, 10, 0, 0, 1 300, 10 L 300, 190 A 10, 10, 0, 0, 1 290, 200 L 10, 200 A 10, 10, 0, 0, 1 0, 190 L 0, 60 A 10, 10, 0, 0, 1 10, 50 Z"
72
- );
73
- width: 300px;
74
- }
75
- &.square {
76
- /* clip-path: path('M 10, 50 L 90, 50 A 10, 10, 0, 0, 0 100, 40 L 100, 10 L 110, 0 L 190, 0 L 200, 10 L 200, 190 L 190, 200 L 10, 200 L 0, 190 L 0, 60 L 10, 50 Z'); */
77
- clip-path: path(
78
- "M 10, 50 L 90, 50 A 10, 10, 0, 0, 0 100, 40 L 100, 10 A 10, 10, 0, 0, 1 110, 0 L 190, 0 A 10, 10, 0, 0, 1 200, 10 L 200, 190 A 10, 10, 0, 0, 1 190, 200 L 10, 200 A 10, 10, 0, 0, 1 0, 190 L 0, 60 A 10, 10, 0, 0, 1 10, 50 Z"
79
- );
80
- width: 200px;
81
- }
82
- &.circle-cutout {
83
- clip-path: path("M Z");
84
- }
85
- }
86
- }
87
- </style>