srcdev-nuxt-components 9.4.6 → 9.4.8

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 (109) hide show
  1. package/.claude/commands/migrate-component.md +34 -3
  2. package/.claude/component-ledger/audit.json +1 -1
  3. package/.claude/component-ledger/build.mjs +27 -0
  4. package/.claude/component-ledger/output.html +8 -3
  5. package/.claude/component-ledger/template.html +7 -2
  6. package/.claude/skills/component-dynamic-slots.md +1 -1
  7. package/.claude/skills/components/column-flow-grid.md +93 -0
  8. package/.claude/skills/components/entry-animation.md +88 -0
  9. package/.claude/skills/components/header-block.md +92 -0
  10. package/.claude/skills/components/input-copy.md +2 -0
  11. package/.claude/skills/components/input-text-core.md +186 -0
  12. package/.claude/skills/components/masonry-grid.md +153 -0
  13. package/.claude/skills/components/pop-over.md +100 -0
  14. package/.claude/skills/components/rotating-carousel-image.md +101 -0
  15. package/.claude/skills/components/skip-links.md +82 -0
  16. package/.claude/skills/components/tabs-core.md +187 -0
  17. package/.claude/skills/index.md +10 -1
  18. package/.vscode/srcdev-component-column-flow-grid.code-snippets +39 -0
  19. package/.vscode/srcdev-component-entry-animation.code-snippets +29 -0
  20. package/.vscode/srcdev-component-header-block.code-snippets +41 -0
  21. package/.vscode/srcdev-component-input-text.code-snippets +107 -0
  22. package/.vscode/srcdev-component-masonry-grid.code-snippets +51 -0
  23. package/.vscode/srcdev-component-pop-over.code-snippets +44 -0
  24. package/.vscode/srcdev-component-rotating-carousel-image.code-snippets +74 -0
  25. package/.vscode/srcdev-component-skip-links.code-snippets +55 -0
  26. package/.vscode/srcdev-component-tabs-core.code-snippets +78 -0
  27. package/app/assets/styles/setup/05.typography/02.utility-classes/_font-classes-page-heading.css +2 -1
  28. package/app/components/01.atoms/animations/entry/EntryAnimation.vue +7 -1
  29. package/app/components/01.atoms/animations/entry/stories/EntryAnimation.stories.ts +47 -0
  30. package/app/components/01.atoms/animations/entry/tests/EntryAnimation.spec.ts +57 -0
  31. package/app/components/01.atoms/animations/rotating-carousel-image/CONSUMER-STYLING.md +54 -0
  32. package/app/components/01.atoms/animations/rotating-carousel-image/RotatingCarouselImage.vue +315 -0
  33. package/app/components/01.atoms/animations/rotating-carousel-image/stories/RotatingCarouselImage.stories.ts +156 -0
  34. package/app/components/01.atoms/animations/rotating-carousel-image/tests/RotatingCarouselImage.spec.ts +230 -0
  35. package/app/components/01.atoms/animations/rotating-carousel-image/tests/__snapshots__/RotatingCarouselImage.spec.ts.snap +19 -0
  36. package/app/components/01.atoms/canvas-switcher/stories/CanvasSwitcher.stories.ts +9 -10
  37. package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +12 -13
  38. package/app/components/01.atoms/grids/column-flow-grid/CONSUMER-STYLING.md +33 -0
  39. package/app/components/01.atoms/grids/column-flow-grid/ColumnFlowGrid.vue +55 -0
  40. package/app/components/01.atoms/grids/column-flow-grid/stories/ColumnFlowGrid.stories.ts +178 -0
  41. package/app/components/01.atoms/grids/column-flow-grid/tests/ColumnFlowGrid.spec.ts +75 -0
  42. package/app/components/01.atoms/grids/masonry-grid/CONSUMER-STYLING.md +35 -0
  43. package/app/components/01.atoms/grids/masonry-grid/MasonryGrid.vue +178 -0
  44. package/app/components/01.atoms/grids/masonry-grid/stories/MasonryGrid.stories.ts +199 -0
  45. package/app/components/01.atoms/grids/masonry-grid/tests/MasonryGrid.spec.ts +158 -0
  46. package/app/components/01.atoms/navigation/skip-links/CONSUMER-STYLING.md +31 -0
  47. package/app/components/01.atoms/navigation/skip-links/SkipLinks.vue +92 -0
  48. package/app/components/01.atoms/navigation/skip-links/stories/SkipLinks.stories.ts +113 -0
  49. package/app/components/01.atoms/navigation/skip-links/tests/SkipLinks.spec.ts +71 -0
  50. package/app/components/01.atoms/navigation/skip-links/tests/__snapshots__/SkipLinks.spec.ts.snap +15 -0
  51. package/app/components/01.atoms/navigation/tabs/CONSUMER-STYLING.md +99 -0
  52. package/app/components/01.atoms/navigation/tabs/TabsCore.vue +272 -0
  53. package/app/components/01.atoms/navigation/tabs/stories/TabsCore.stories.ts +199 -0
  54. package/app/components/01.atoms/navigation/tabs/tests/TabsCore.spec.ts +274 -0
  55. package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +54 -0
  56. package/app/components/01.atoms/pop-over/PopOver.vue +201 -0
  57. package/app/components/01.atoms/pop-over/stories/PopOver.stories.ts +141 -0
  58. package/app/components/01.atoms/pop-over/tests/PopOver.spec.ts +195 -0
  59. package/app/components/01.atoms/pop-over/tests/__snapshots__/PopOver.spec.ts.snap +11 -0
  60. package/app/components/01.atoms/text-blocks/header-block/CONSUMER-STYLING.md +43 -0
  61. package/app/components/01.atoms/text-blocks/header-block/HeaderBlock.vue +50 -0
  62. package/app/components/01.atoms/text-blocks/header-block/stories/HeaderBlock.stories.ts +111 -0
  63. package/app/components/01.atoms/text-blocks/header-block/tests/HeaderBlock.spec.ts +119 -0
  64. package/app/components/01.atoms/text-blocks/header-block/tests/__snapshots__/HeaderBlock.spec.ts.snap +5 -0
  65. package/app/components/02.molecules/action-menu/stories/ActionMenu.stories.ts +8 -2
  66. package/app/components/02.molecules/input-copy/InputCopy.vue +14 -0
  67. package/app/components/02.molecules/input-copy/stories/InputCopy.stories.ts +15 -0
  68. package/app/components/02.molecules/input-copy/tests/InputCopy.spec.ts +41 -0
  69. package/app/components/03.organisms/site-header/SiteHeader.vue +1 -1
  70. package/app/components/03.organisms/site-header/tests/SiteHeader.spec.ts +1 -1
  71. package/app/components/03.organisms/site-header/tests/__snapshots__/SiteHeader.spec.ts.snap +3 -3
  72. package/app/components/05.forms/input-select/InputSelectCore.vue +1 -1
  73. package/app/components/05.forms/input-text/InputTextCore.vue +6 -0
  74. package/app/components/05.forms/input-text/stories/InputPasswordWithLabel.stories.ts +49 -20
  75. package/app/components/05.forms/input-text/stories/InputTextAsNumberWithLabel.stories.ts +41 -22
  76. package/app/components/05.forms/input-text/stories/InputTextCore.stories.ts +48 -22
  77. package/app/components/05.forms/input-text/stories/InputTextWithLabel.stories.ts +43 -17
  78. package/app/components/05.forms/input-text/tests/InputPasswordWithLabel.spec.ts +56 -0
  79. package/app/components/05.forms/input-text/tests/InputTextAsNumberWithLabel.spec.ts +61 -0
  80. package/app/components/05.forms/input-text/tests/InputTextCore.spec.ts +60 -0
  81. package/app/components/05.forms/input-text/tests/InputTextWithLabel.spec.ts +46 -0
  82. package/app/components/05.forms/input-text/variants/InputPasswordWithLabel.vue +7 -1
  83. package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +8 -2
  84. package/app/components/05.forms/input-text/variants/InputTextWithLabel.vue +6 -0
  85. package/app/components/05.forms/input-textarea/stories/InputTextareaCore.stories.ts +20 -20
  86. package/app/components/05.forms/input-textarea/stories/InputTextareaWithLabel.stories.ts +32 -26
  87. package/app/composables/useTabs.ts +225 -207
  88. package/app/types/components/index.ts +2 -0
  89. package/app/types/components/rotating-carousel-image.d.ts +4 -0
  90. package/app/types/components/skip-links.d.ts +4 -0
  91. package/app/types/forms/types.forms.d.ts +1 -1
  92. package/package.json +1 -1
  93. package/app/components/01.atoms/grids/data-grid/tests/__snapshots__/DataGrid.spec.ts.snap +0 -11
  94. package/app/components/masonry-grid/MasonryGrid.vue +0 -68
  95. package/app/components/masonry-grid-ordered/MasonryGridOrdered.vue +0 -163
  96. package/app/components/masonry-grid-ordered/MasonryGridOrderedGridExperiment.vue +0 -259
  97. package/app/components/masonry-grid-ordered/stories/MasonryGridOrdered.stories.ts +0 -354
  98. package/app/components/masonry-grid-sorted/MasonryGridSorted.vue +0 -120
  99. package/app/components/pop-over/PopOver.vue +0 -90
  100. package/app/components/rotating-carousel/RotatingCarouselImage.vue +0 -216
  101. package/app/components/skip-links/SkipLinks.vue +0 -60
  102. package/app/components/tabs/TabsCore.vue +0 -306
  103. package/app/components/typography/HeaderBlock.vue +0 -35
  104. package/app/layouts/default.vue +0 -308
  105. package/app/layouts/site-navigation-demo.vue +0 -188
  106. /package/app/components/01.atoms/grids/{data-grid → auto-grid}/AutoGrid.vue +0 -0
  107. /package/app/components/01.atoms/grids/{data-grid → auto-grid}/stories/AutoGrid.stories.ts +0 -0
  108. /package/app/components/01.atoms/grids/{data-grid → auto-grid}/tests/AutoGrid.spec.ts +0 -0
  109. /package/app/components/01.atoms/grids/{data-grid → auto-grid}/tests/__snapshots__/AutoGrid.spec.ts.snap +0 -0
@@ -1,216 +0,0 @@
1
- <template>
2
- <component
3
- :is="tag"
4
- class="rotating-carousel"
5
- :class="[elementClasses]"
6
- :style="`--_rotate-x: ${rotateXProp}deg; --_perspective: ${perspectiveProp}; --_translateZ: ${translateZProp}; --_animation-play-state: ${
7
- pauseOnHover ? 'paused' : 'running'
8
- }`"
9
- ref="carouselRef"
10
- >
11
- <div class="slider" :style="`--quantity: ${Object.keys(data).length}`">
12
- <div v-for="(item, key) in data" :key="key" class="item" :style="`--_position: ${key}`">
13
- <NuxtImg :src="item.src" :alt="item.alt" />
14
- </div>
15
- </div>
16
- </component>
17
- </template>
18
-
19
- <script setup lang="ts">
20
- interface CarouselImageData {
21
- src: string
22
- alt: string
23
- }
24
-
25
- const props = defineProps({
26
- data: {
27
- type: Array as PropType<CarouselImageData[]>,
28
- default: () => [],
29
- },
30
- tag: {
31
- type: String,
32
- default: "div",
33
- validator(value: string) {
34
- return [
35
- "div",
36
- "p",
37
- "span",
38
- "section",
39
- "article",
40
- "aside",
41
- "header",
42
- "footer",
43
- "main",
44
- "nav",
45
- "ul",
46
- "ol",
47
- ].includes(value)
48
- },
49
- },
50
- rotateX: {
51
- type: Number,
52
- default: 0,
53
- },
54
- perspective: {
55
- type: Number,
56
- default: 1000,
57
- },
58
- translateZ: {
59
- type: Number,
60
- default: 1000,
61
- },
62
- pauseOnHover: {
63
- type: Boolean,
64
- default: false,
65
- },
66
- useParallaxEffect: {
67
- type: Boolean,
68
- default: true,
69
- },
70
- styleClassPassthrough: {
71
- type: [String, Array] as PropType<string | string[]>,
72
- default: () => [],
73
- },
74
- })
75
-
76
- const perspectiveProp = computed(() => `${props.perspective.toString()}px`)
77
- const translateZProp = computed(() => `${props.translateZ.toString()}px`)
78
-
79
- const carouselRef = ref<HTMLElement | null>(null)
80
- const rotateXProp = ref(props.rotateX)
81
- const minRotateX = -32
82
- const maxRotateX = 32
83
-
84
- const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
85
-
86
- watch(
87
- () => props.styleClassPassthrough,
88
- () => {
89
- resetElementClasses(props.styleClassPassthrough)
90
- }
91
- )
92
-
93
- watch(
94
- () => props.rotateX,
95
- () => {
96
- if (!props.useParallaxEffect) {
97
- console.log("rotateXProp changed: ", rotateXProp.value)
98
-
99
- rotateXProp.value = props.rotateX
100
- }
101
- }
102
- )
103
-
104
- watch(
105
- () => props.useParallaxEffect,
106
- (currentValue) => {
107
- if (currentValue) {
108
- handleScroll()
109
- window.addEventListener("scroll", handleScroll)
110
- } else {
111
- window.removeEventListener("scroll", handleScroll)
112
- }
113
- }
114
- )
115
-
116
- const handleScroll = () => {
117
- if (!carouselRef.value) return
118
- if ("IntersectionObserver" in window) {
119
- const rect = carouselRef.value.getBoundingClientRect()
120
- const viewportHeight = window.innerHeight
121
-
122
- const elementCenter = rect.top + rect.height / 2
123
- const viewportCenter = viewportHeight / 2
124
- const distanceFromCenter = viewportCenter - elementCenter
125
- const maxDistance = viewportHeight / 2 + rect.height / 2
126
-
127
- const progress = (distanceFromCenter + maxDistance) / (maxDistance * 2)
128
- const clampedProgress = Math.max(0, Math.min(1, progress))
129
-
130
- rotateXProp.value = minRotateX + (maxRotateX - minRotateX) * clampedProgress
131
- }
132
- }
133
-
134
- onMounted(async () => {
135
- if (props.useParallaxEffect) {
136
- handleScroll()
137
- await nextTick()
138
- window.addEventListener("scroll", handleScroll)
139
- }
140
- })
141
-
142
- onUnmounted(() => {
143
- window.removeEventListener("scroll", handleScroll)
144
- })
145
- </script>
146
-
147
- <style lang="css">
148
- @layer components {
149
- /* @property --_rotate-x {
150
- syntax: '<angle>';
151
- inherits: false;
152
- initial-value: 0deg;
153
- }
154
-
155
- @keyframes autoRotateAnimation {
156
- from {
157
- --_rotate-x: -16deg;
158
- }
159
- to {
160
- --_rotate-x: 16deg;
161
- }
162
- } */
163
-
164
- @keyframes autoRun {
165
- from {
166
- transform: perspective(var(--_perspective)) rotateX(var(--_rotate-x)) rotateY(0deg);
167
- }
168
- to {
169
- transform: perspective(var(--_perspective)) rotateX(var(--_rotate-x)) rotateY(360deg);
170
- }
171
- }
172
-
173
- .rotating-carousel {
174
- width: 100%;
175
- height: 70svh;
176
- text-align: center;
177
- overflow: hidden;
178
- position: relative;
179
-
180
- /* padding-block: 800px; */
181
-
182
- /* &.scroll-effect {
183
- animation: autoRotateAnimation;
184
- animation-timeline: view();
185
- } */
186
-
187
- .slider {
188
- position: absolute;
189
- width: 200px;
190
- height: 250px;
191
- bottom: 35%;
192
- left: calc(50% - 100px);
193
- transform-style: preserve-3d;
194
- transform: perspective(var(--_perspective));
195
- animation: autoRun 30s linear infinite;
196
- z-index: 2;
197
-
198
- &:has(.item img:hover) {
199
- animation-play-state: var(--_animation-play-state);
200
- }
201
-
202
- .item {
203
- position: absolute;
204
- inset: 0 0 0 0;
205
- transform: rotateY(calc((var(--_position) - 1) * (360 / var(--quantity)) * 1deg)) translateZ(var(--_translateZ));
206
-
207
- img {
208
- width: 100%;
209
- height: 100%;
210
- object-fit: cover;
211
- }
212
- }
213
- }
214
- }
215
- }
216
- </style>
@@ -1,60 +0,0 @@
1
- <template>
2
- <div class="home-link-navigation">
3
- <div v-if="slots.homeLink" class="home-link">
4
- <slot name="homeLink"></slot>
5
- </div>
6
- <nav class="skip-links-nav" aria-label="Skip navigation">
7
- <a ref="skipLink" href="#main-content" class="skip-link">Skip to main content</a>
8
- <a href="#footer-content" class="skip-link">Skip to footer</a>
9
- </nav>
10
- </div>
11
- </template>
12
-
13
- <script lang="ts" setup>
14
- const slots = useSlots();
15
- </script>
16
-
17
- <style lang="css">
18
- @layer components {
19
- .home-link-navigation {
20
- position: relative;
21
-
22
- .skip-links-nav {
23
- position: absolute;
24
- top: 100%;
25
- left: 0;
26
- z-index: 1000;
27
-
28
- display: flex;
29
- flex-direction: column;
30
- gap: 0.2rem;
31
- background-color: black;
32
- border: 1px solid white;
33
- padding: 0.2rem;
34
- margin: 0;
35
-
36
- /* Hidden off-screen via transform — does NOT break keyboard focusability */
37
- opacity: 0;
38
- transform: translateY(-100%);
39
- transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;
40
-
41
- &:focus-within {
42
- opacity: 1;
43
- transform: translateY(0);
44
- }
45
-
46
- .skip-link {
47
- display: block;
48
- color: white;
49
- text-decoration: none;
50
- padding: 0.8rem 1.2rem;
51
- text-wrap: nowrap;
52
-
53
- &:focus-visible {
54
- outline: 2px solid white;
55
- }
56
- }
57
- }
58
- }
59
- }
60
- </style>
@@ -1,306 +0,0 @@
1
- <template>
2
- <div class="tabs-core" :class="`axis-${axis}`">
3
- <ul
4
- ref="tabsNavRef"
5
- role="tablist"
6
- aria-labelledby="channel-name"
7
- class="tabs-list"
8
- :class="[elementClasses]"
9
- @mouseleave="resetHoverToActivePosition()"
10
- >
11
- <li v-for="(index, key) in itemCount" :key="key">
12
- <button
13
- :id="`tab-${key}-trigger`"
14
- :data-tab-index="key"
15
- data-nav-item
16
- role="tab"
17
- aria-selected="false"
18
- class="tabs-list-item"
19
- @click.prevent="navItemClicked($event)"
20
- @mouseover="navItemHovered($event)"
21
- >
22
- <slot :name="`tab-${key}-trigger`"></slot>
23
- </button>
24
- </li>
25
- </ul>
26
- <div class="tab-content-wrapper">
27
- <div
28
- v-for="(item, key) in itemCount"
29
- :id="`tab-${key}-content`"
30
- :key="key"
31
- ref="tabsContentRefs"
32
- class="tab-content"
33
- :aria-labelledby="`tab-${key}-trigger`"
34
- role="region"
35
- aria-hidden="true"
36
- >
37
- <slot :name="`tab-${key}-content`"></slot>
38
- </div>
39
- </div>
40
- </div>
41
- </template>
42
-
43
- <script setup lang="ts">
44
- const props = defineProps({
45
- tag: {
46
- type: String as PropType<string>,
47
- default: "button",
48
- },
49
- axis: {
50
- type: String as PropType<"x" | "y">,
51
- default: "x",
52
- },
53
- transitionDuration: {
54
- type: Number as PropType<number>,
55
- default: 200,
56
- },
57
- itemCount: {
58
- type: Number as PropType<number>,
59
- default: 0,
60
- },
61
- trackHover: {
62
- type: Boolean as PropType<boolean>,
63
- default: true,
64
- },
65
- trackActive: {
66
- type: Boolean as PropType<boolean>,
67
- default: true,
68
- },
69
- trackIndicator: {
70
- type: Boolean as PropType<boolean>,
71
- default: true,
72
- },
73
- styleClassPassthrough: {
74
- type: [String, Array] as PropType<string | string[]>,
75
- default: () => [],
76
- },
77
- });
78
-
79
- const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
80
-
81
- const tabsNavRef = ref<HTMLElement | null>(null);
82
- const tabsContentRefs = ref<HTMLElement[] | null>(null);
83
-
84
- const { initNavDecorators, navItemClicked, navItemHovered, resetHoverToActivePosition } = useTabs(
85
- props.axis,
86
- tabsNavRef,
87
- tabsContentRefs,
88
- props.transitionDuration
89
- );
90
-
91
- onMounted(() => {
92
- initNavDecorators();
93
- });
94
- </script>
95
-
96
- <style lang="css">
97
- @layer components {
98
- .tabs-core {
99
- .tabs-list {
100
- position: relative;
101
- display: flex;
102
- width: fit-content;
103
- z-index: 1;
104
-
105
- list-style-type: none;
106
- margin: 0;
107
- padding: 0;
108
-
109
- .nav__hovered {
110
- content: "";
111
- position: absolute;
112
- left: 0;
113
- right: 0;
114
- bottom: 0;
115
- top: 0;
116
- scale: var(--_width-hovered, 0.125) 1;
117
- translate: var(--_x-hovered, 0) 0;
118
- transform-origin: left;
119
- transition:
120
- scale var(--_transition-duration),
121
- translate var(--_transition-duration);
122
- z-index: 1;
123
- }
124
-
125
- .nav__active {
126
- content: "";
127
- position: absolute;
128
- left: 0;
129
- right: 0;
130
- bottom: 0;
131
- top: 0;
132
- scale: var(--_width-active, 0.125) 1;
133
- translate: var(--_x-active, 0) 0;
134
- transform-origin: left;
135
- transition:
136
- scale var(--_transition-duration),
137
- translate var(--_transition-duration);
138
- z-index: 2;
139
- }
140
-
141
- .nav__active-indicator {
142
- content: "";
143
- position: absolute;
144
- left: 0;
145
- right: 0;
146
- bottom: 0;
147
- scale: var(--_width-active, 0.125) 1;
148
- translate: var(--_x-active, 0) 0;
149
- transform-origin: left;
150
- transition:
151
- scale var(--_transition-duration),
152
- translate var(--_transition-duration);
153
- z-index: 3;
154
- }
155
-
156
- .tabs-list-item {
157
- opacity: 0.7;
158
- position: relative;
159
- transition: color 100ms;
160
- z-index: 4;
161
-
162
- &:hover {
163
- opacity: 1;
164
- }
165
-
166
- &[aria-selected="true"] {
167
- opacity: 1;
168
- }
169
- }
170
-
171
- border-bottom: var(--_tabs-border-bottom);
172
-
173
- .nav__hovered {
174
- background: light-dark(var(--slate-07), var(--slate-03));
175
- color: light-dark(var(--slate-00), var(--slate-10));
176
- }
177
-
178
- .nav__active {
179
- background: light-dark(var(--slate-10), var(--slate-00));
180
- color: light-dark(var(--slate-00), var(--slate-10));
181
- }
182
-
183
- .nav__active-indicator {
184
- background: light-dark(var(--slate-10), var(--slate-00));
185
- height: 0.4rem;
186
- }
187
-
188
- .tabs-list-item {
189
- background: transparent;
190
- border: 0;
191
- color: light-dark(var(--slate-10), var(--slate-00));
192
- cursor: pointer;
193
- font: inherit;
194
- text-transform: uppercase;
195
- font-weight: 500;
196
- margin: 0;
197
- padding: 1em 2em;
198
-
199
- &:hover {
200
- color: light-dark(var(--slate-00), var(--slate-10));
201
- }
202
-
203
- &[aria-selected="true"] {
204
- color: light-dark(var(--slate-00), var(--slate-10));
205
- }
206
-
207
- &.transitioning {
208
- color: light-dark(var(--slate-00), var(--slate-10));
209
- }
210
- }
211
- }
212
-
213
- .tab-content-wrapper {
214
- display: grid;
215
- grid-template-areas: "element-stack";
216
-
217
- background-color: light-dark(var(--slate-09), var(--slate-10));
218
- border: 0.1rem solid var(--slate-06);
219
- border-start-start-radius: 0;
220
- border-start-end-radius: 0;
221
- border-end-start-radius: 0;
222
- border-end-end-radius: 0;
223
- outline: 0.1rem solid var(--slate-06);
224
-
225
- .tab-content {
226
- grid-area: element-stack;
227
- display: none;
228
- }
229
- }
230
- }
231
-
232
- /*
233
- * Deal with axis-y
234
- **/
235
-
236
- .tabs-core {
237
- &.axis-y {
238
- display: flex;
239
- flex-direction: row;
240
- gap: 2em;
241
-
242
- .tabs-list {
243
- flex-direction: column;
244
-
245
- border-bottom: initial;
246
- border-left: var(--_tabs-border-bottom);
247
- position: relative;
248
-
249
- .tabs-list-item {
250
- text-align: left;
251
- width: 100%;
252
-
253
- &:hover {
254
- /* color: light-dark(var(--slate-00), var(--slate-10)); */
255
- }
256
-
257
- &[aria-selected="true"] {
258
- /* color: var(--_tabs-active-text); */
259
- }
260
-
261
- &.transitioning {
262
- /* color: light-dark(var(--slate-00), var(--slate-10)); */
263
- }
264
- }
265
-
266
- .nav__hovered {
267
- left: 0;
268
- right: initial;
269
- bottom: initial;
270
- top: 0;
271
- height: var(--_y-height);
272
- translate: 0 var(--_y-hovered, 0);
273
- transform-origin: top;
274
- width: var(--_y-width);
275
- }
276
-
277
- .nav__active {
278
- left: 0;
279
- right: initial;
280
- bottom: initial;
281
- top: 0;
282
- height: var(--_y-height);
283
- translate: 0 var(--_y-active, 0);
284
- transform-origin: top;
285
- width: var(--_y-width);
286
- }
287
-
288
- .nav__active-indicator {
289
- left: 0;
290
- right: initial;
291
- bottom: initial;
292
- top: 0;
293
- height: var(--_y-height);
294
- scale: var(--_width-active, 0.125) 1;
295
- translate: 0 var(--_y-active, 0);
296
- transform-origin: top;
297
- width: 0.4em;
298
- }
299
- }
300
- .tab-content-wrapper {
301
- flex-grow: 1;
302
- }
303
- }
304
- }
305
- }
306
- </style>
@@ -1,35 +0,0 @@
1
- <template>
2
- <component :is="tag" :class="[classLevelClass, elementClasses]">
3
- <slot></slot>
4
- </component>
5
- </template>
6
-
7
- <script setup lang="ts">
8
- const props = defineProps<{
9
- tagLevel?: number | string
10
- classLevel?: number | string
11
- styleClassPassthrough?: string | string[]
12
- }>()
13
-
14
- const tagLevel = computed(() => {
15
- const n = Number(props.tagLevel ?? 1)
16
- return [1, 2, 3, 4, 5, 6].includes(n) ? n : 1
17
- })
18
-
19
- const classLevel = computed(() => {
20
- const n = Number(props.classLevel ?? 1)
21
- return [1, 2, 3, 4, 5, 6].includes(n) ? n : 1
22
- })
23
-
24
- const tag = computed(() => `h${tagLevel.value}`)
25
- const classLevelClass = computed(() => `page-heading-${classLevel.value}`)
26
-
27
- const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough ?? [])
28
-
29
- watch(
30
- () => props.styleClassPassthrough,
31
- (newVal) => {
32
- resetElementClasses(newVal ?? [])
33
- }
34
- )
35
- </script>