@alphacifer/slidev-addon-theme 0.0.7 → 0.0.9
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.
- package/README.md +186 -76
- package/components/{chevron-card → card/chevron-card}/ChevronCard.vue +2 -2
- package/components/{chevron-card → card/chevron-card}/ChevronCardBadge.vue +1 -1
- package/components/{chevron-card → card/chevron-card}/ChevronCardContent.vue +1 -1
- package/components/{chevron-card → card/chevron-card}/ChevronCardHeading.vue +1 -1
- package/components/{horiz-card → card/horiz-card}/HorizCard.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardBadge.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardContent.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardHeading.vue +2 -2
- package/components/{horiz-card → card/horiz-card}/HorizCardIcon.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCard.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardBadge.vue +5 -2
- package/components/{vert-card → card/vert-card}/VertCardContent.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardHeading.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardIcon.vue +2 -2
- package/components/{vert-card → card/vert-card}/VertCardTitle.vue +2 -2
- package/components/comparisons/arc-comparison/ArcComparison.vue +654 -0
- package/components/comparisons/arc-comparison/ArcComparisonBadge.vue +29 -0
- package/components/comparisons/arc-comparison/ArcComparisonContent.vue +29 -0
- package/components/comparisons/arc-comparison/ArcComparisonContents.vue +17 -0
- package/components/comparisons/arc-comparison/ArcComparisonHeading.vue +29 -0
- package/components/comparisons/arc-comparison/ArcComparisonLeft.vue +268 -0
- package/components/comparisons/arc-comparison/ArcComparisonOrbit.vue +47 -0
- package/components/comparisons/arc-comparison/ArcComparisonRight.vue +271 -0
- package/components/comparisons/arc-comparison/ArcComparisonTitle.vue +29 -0
- package/components/{comparison-table/ComparisonTable.vue → comparisons/table-comparison/TableComparison.vue} +37 -27
- package/components/{comparison-table/ComparisonTableCell.vue → comparisons/table-comparison/TableComparisonCell.vue} +8 -8
- package/components/{comparison-table/ComparisonTableCol.vue → comparisons/table-comparison/TableComparisonCol.vue} +10 -10
- package/components/{comparison-table/ComparisonTableCols.vue → comparisons/table-comparison/TableComparisonCols.vue} +11 -11
- package/components/{comparison-table/ComparisonTableRow.vue → comparisons/table-comparison/TableComparisonRow.vue} +9 -9
- package/components/{comparison-table/ComparisonTableRows.vue → comparisons/table-comparison/TableComparisonRows.vue} +3 -3
- package/components/core/ReflectedTitle.vue +2 -1
- package/components/core/arc-orbit/ArcOrbit.vue +468 -0
- package/components/{arc-compare/ArcCompareBadge.vue → core/arc-orbit/ArcOrbitBadge.vue} +11 -8
- package/components/core/arc-orbit/ArcOrbitCallout.vue +400 -0
- package/components/{arc-compare/ArcCompareContent.vue → core/arc-orbit/ArcOrbitContent.vue} +8 -8
- package/components/{arc-compare/ArcCompareContents.vue → core/arc-orbit/ArcOrbitContents.vue} +3 -3
- package/components/{arc-compare/ArcCompareHeading.vue → core/arc-orbit/ArcOrbitHeading.vue} +11 -8
- package/components/core/arc-orbit/ArcOrbitTitle.vue +50 -0
- package/components/{thanks → core/thanks}/ThanksOutlineSquare.vue +1 -1
- package/components/{thanks → core/thanks}/ThanksSquare.vue +1 -1
- package/components/{quad-hub/QuadHub.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetrad.vue} +71 -69
- package/components/{quad-hub/QuadHubCallout.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCallout.vue} +45 -43
- package/components/{quad-hub/QuadHubCenter.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCenter.vue} +4 -4
- package/components/{quad-hub/QuadHubContent.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradContent.vue} +6 -6
- package/components/{quad-hub/QuadHubHeading.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradHeading.vue} +6 -6
- package/components/{quad-hub/QuadHubIcon.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradIcon.vue} +6 -6
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriad.vue +3 -3
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadCallout.vue +1 -1
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadContent.vue +1 -1
- package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadHeading.vue +1 -1
- package/components/facets/triad/gear-triad/GearTriad.vue +591 -0
- package/components/facets/triad/gear-triad/GearTriadCallout.vue +285 -0
- package/components/facets/triad/gear-triad/GearTriadCenter.vue +41 -0
- package/components/facets/triad/gear-triad/GearTriadContent.vue +58 -0
- package/components/facets/triad/gear-triad/GearTriadContents.vue +111 -0
- package/components/facets/triad/gear-triad/GearTriadDescription.vue +38 -0
- package/components/facets/triad/gear-triad/GearTriadHeading.vue +38 -0
- package/components/facets/triad/gear-triad/GearTriadIcon.vue +157 -0
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriad.vue +2 -2
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriadBadge.vue +1 -1
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriadCallout.vue +1 -1
- package/components/{hex-triad → facets/triad/hex-triad}/HexTriadHeading.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcess.vue +2 -2
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessArrow.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessCallout.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessContent.vue +1 -1
- package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessHeading.vue +1 -1
- package/components/pyramid/circular-pyramid/CircularPyramid.vue +871 -0
- package/components/pyramid/circular-pyramid/CircularPyramidStack.vue +375 -0
- package/components/pyramid/circular-pyramid/CircularPyramidStackContent.vue +208 -0
- package/components/pyramid/circular-pyramid/CircularPyramidStackTitle.vue +138 -0
- package/components/pyramid/square-pyramid/SquarePyramid.vue +876 -0
- package/components/pyramid/square-pyramid/SquarePyramidStack.vue +366 -0
- package/components/pyramid/square-pyramid/SquarePyramidStackContent.vue +204 -0
- package/components/pyramid/square-pyramid/SquarePyramidStackTitle.vue +134 -0
- package/package.json +2 -1
- package/utils/arcComparison/context.ts +40 -0
- package/utils/arcComparison/createArcComparisonGeometry.ts +175 -0
- package/utils/arcComparison/index.ts +3 -0
- package/utils/{arcCompare/resolveArcCompareItems.ts → arcComparison/resolveArcComparisonItems.ts} +24 -45
- package/utils/arcOrbit/context.ts +38 -0
- package/utils/{arcCompare/createArcCompareGeometry.ts → arcOrbit/createArcOrbitGeometry.ts} +77 -108
- package/utils/arcOrbit/index.ts +3 -0
- package/utils/arcOrbit/resolveArcOrbitItems.ts +92 -0
- package/utils/gearTriad/context.ts +51 -0
- package/utils/gearTriad/createGearTriadGeometry.ts +210 -0
- package/utils/gearTriad/index.ts +3 -0
- package/utils/gearTriad/resolveGearTriadItems.ts +159 -0
- package/utils/pyramid/circular-pyramid/context.ts +46 -0
- package/utils/pyramid/circular-pyramid/createCircularPyramidGeometry.ts +143 -0
- package/utils/pyramid/circular-pyramid/index.ts +3 -0
- package/utils/pyramid/circular-pyramid/types.ts +34 -0
- package/utils/pyramid/index.ts +3 -0
- package/utils/pyramid/shared/colors.ts +92 -0
- package/utils/pyramid/shared/connector.ts +111 -0
- package/utils/pyramid/shared/constants.ts +8 -0
- package/utils/pyramid/shared/index.ts +5 -0
- package/utils/pyramid/shared/stacking.ts +76 -0
- package/utils/pyramid/shared/types.ts +36 -0
- package/utils/pyramid/square-pyramid/context.ts +46 -0
- package/utils/pyramid/square-pyramid/createSquarePyramidGeometry.ts +265 -0
- package/utils/pyramid/square-pyramid/index.ts +3 -0
- package/utils/pyramid/square-pyramid/types.ts +39 -0
- package/utils/rectOrbitTetrad/context.ts +31 -0
- package/utils/{quadHub/createQuadHubGeometry.ts → rectOrbitTetrad/createRectOrbitTetradGeometry.ts} +33 -28
- package/utils/rectOrbitTetrad/index.ts +3 -0
- package/utils/{quadHub/resolveQuadHubItems.ts → rectOrbitTetrad/resolveRectOrbitTetradItems.ts} +25 -25
- package/utils/{comparisonTable → tableComparison}/context.ts +6 -6
- package/utils/useDiagramAutoScale.ts +7 -9
- package/components/arc-compare/ArcCompare.vue +0 -443
- package/components/arc-compare/ArcCompareCallout.vue +0 -386
- package/components/arc-compare/ArcCompareLeft.vue +0 -183
- package/components/arc-compare/ArcCompareRight.vue +0 -183
- package/components/arc-compare/ArcCompareTitle.vue +0 -47
- package/utils/arcCompare/context.ts +0 -36
- package/utils/arcCompare/index.ts +0 -3
- package/utils/quadHub/context.ts +0 -26
- package/utils/quadHub/index.ts +0 -3
- /package/components/{shifting-heading → core}/TransitionHeading.vue +0 -0
- /package/components/{thanks → core/thanks}/ThanksContent.vue +0 -0
- /package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadIcon.vue +0 -0
- /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadCenterBadge.vue +0 -0
- /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadContent.vue +0 -0
- /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadLayer.vue +0 -0
- /package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessIcon.vue +0 -0
- /package/utils/{comparisonTable → tableComparison}/constants.ts +0 -0
- /package/utils/{comparisonTable → tableComparison}/index.ts +0 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
computed,
|
|
4
|
+
Fragment,
|
|
5
|
+
inject,
|
|
6
|
+
onUnmounted,
|
|
7
|
+
provide,
|
|
8
|
+
useSlots,
|
|
9
|
+
type VNode,
|
|
10
|
+
} from 'vue';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
DEFAULT_SQUARE_PYRAMID_COLOR,
|
|
14
|
+
DEFAULT_SQUARE_PYRAMID_STACK_COLORS,
|
|
15
|
+
SQUARE_PYRAMID_ROOT_KEY,
|
|
16
|
+
SQUARE_PYRAMID_STACK_KEY,
|
|
17
|
+
} from '../../../utils/pyramid/square-pyramid';
|
|
18
|
+
import SquarePyramidStackContent from './SquarePyramidStackContent.vue';
|
|
19
|
+
import SquarePyramidStackTitle from './SquarePyramidStackTitle.vue';
|
|
20
|
+
|
|
21
|
+
defineOptions({
|
|
22
|
+
name: 'SquarePyramidStack',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export interface ISquarePyramidStackProps {
|
|
26
|
+
readonly index?: number;
|
|
27
|
+
readonly step?: string | number;
|
|
28
|
+
readonly title?: string;
|
|
29
|
+
readonly content?: string;
|
|
30
|
+
readonly color?: string;
|
|
31
|
+
readonly active?: boolean;
|
|
32
|
+
readonly connectorWidth?: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const props = withDefaults(defineProps<ISquarePyramidStackProps>(), {
|
|
36
|
+
index: undefined,
|
|
37
|
+
step: undefined,
|
|
38
|
+
title: undefined,
|
|
39
|
+
content: undefined,
|
|
40
|
+
color: undefined,
|
|
41
|
+
active: undefined,
|
|
42
|
+
connectorWidth: undefined,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const slots = useSlots();
|
|
46
|
+
const rootContext = inject(SQUARE_PYRAMID_ROOT_KEY, undefined);
|
|
47
|
+
|
|
48
|
+
interface INamedComponent {
|
|
49
|
+
readonly type?: {
|
|
50
|
+
readonly name?: string;
|
|
51
|
+
readonly displayName?: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function hasComponentName(type: unknown, targetName: string): boolean {
|
|
56
|
+
if (typeof type === 'object' && type !== null) {
|
|
57
|
+
const comp = type as INamedComponent['type'];
|
|
58
|
+
return comp?.name === targetName || comp?.displayName === targetName;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function flattenVNodes(nodes: VNode[]): VNode[] {
|
|
64
|
+
const result: VNode[] = [];
|
|
65
|
+
for (const node of nodes) {
|
|
66
|
+
if (node.type === Fragment && Array.isArray(node.children)) {
|
|
67
|
+
result.push(...flattenVNodes(node.children as VNode[]));
|
|
68
|
+
} else {
|
|
69
|
+
result.push(node);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const defaultNodes = computed(() => {
|
|
76
|
+
if (!slots.default) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
return flattenVNodes(slots.default());
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const slottedTitle = computed(() => {
|
|
83
|
+
return defaultNodes.value.find((node) =>
|
|
84
|
+
hasComponentName(node.type, 'SquarePyramidStackTitle'),
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const slottedContent = computed(() => {
|
|
89
|
+
return defaultNodes.value.find((node) =>
|
|
90
|
+
hasComponentName(node.type, 'SquarePyramidStackContent'),
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const stackToken = Symbol();
|
|
95
|
+
const effectiveColor = computed(() => {
|
|
96
|
+
return (
|
|
97
|
+
props.color || (slottedTitle.value?.props?.color as string | undefined)
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
const registration = rootContext?.registerStack(stackToken, effectiveColor);
|
|
101
|
+
|
|
102
|
+
onUnmounted(() => {
|
|
103
|
+
registration?.unregister();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const resolvedIndex = computed<number>(() => {
|
|
107
|
+
if (props.index !== undefined) {
|
|
108
|
+
return Number(props.index);
|
|
109
|
+
}
|
|
110
|
+
return registration?.index.value ?? 0;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const isActive = computed<boolean>(() => {
|
|
114
|
+
if (props.active !== undefined) {
|
|
115
|
+
return props.active;
|
|
116
|
+
}
|
|
117
|
+
if (!rootContext) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return rootContext.activeIndex.value === resolvedIndex.value;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const resolvedStep = computed(() => {
|
|
124
|
+
if (props.step !== undefined) {
|
|
125
|
+
return props.step;
|
|
126
|
+
}
|
|
127
|
+
return String(resolvedIndex.value + 1).padStart(2, '0');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const layerGeometry = computed(() => {
|
|
131
|
+
if (!rootContext) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
return rootContext.geo.value.layers[resolvedIndex.value];
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const posY = computed(() => {
|
|
138
|
+
if (!layerGeometry.value) {
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
const geo = layerGeometry.value;
|
|
142
|
+
return (
|
|
143
|
+
geo.slabCenterY ?? Number((geo.cy + (geo.slabHeight ?? 0) / 2).toFixed(2))
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
const DOT_POSITION_X = 210;
|
|
148
|
+
|
|
149
|
+
const leftWidth = computed(() => {
|
|
150
|
+
if (layerGeometry.value) {
|
|
151
|
+
const rx = layerGeometry.value.rx;
|
|
152
|
+
const cx = 465;
|
|
153
|
+
return Math.max(180, Math.round(cx - rx - 40));
|
|
154
|
+
}
|
|
155
|
+
return DOT_POSITION_X;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const rightWidth = computed(() => rootContext?.contentWidthPx.value ?? 240);
|
|
159
|
+
|
|
160
|
+
const rightWingWidth = computed(() => {
|
|
161
|
+
if (layerGeometry.value) {
|
|
162
|
+
const rx = layerGeometry.value.rx;
|
|
163
|
+
const cx = 465;
|
|
164
|
+
const dotRightX = cx + rx + 40;
|
|
165
|
+
const containerW = 960;
|
|
166
|
+
return Math.max(rightWidth.value + 20, Math.round(containerW - dotRightX));
|
|
167
|
+
}
|
|
168
|
+
return rightWidth.value + 40;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const rightOffset = computed(
|
|
172
|
+
() => rootContext?.contentRightOffsetPx.value ?? 0,
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
const resolvedColor = computed<string>(() => {
|
|
176
|
+
if (effectiveColor.value) {
|
|
177
|
+
return effectiveColor.value;
|
|
178
|
+
}
|
|
179
|
+
return (
|
|
180
|
+
rootContext?.getLayerColor(resolvedIndex.value) ??
|
|
181
|
+
DEFAULT_SQUARE_PYRAMID_STACK_COLORS[
|
|
182
|
+
Math.abs(resolvedIndex.value) % DEFAULT_SQUARE_PYRAMID_STACK_COLORS.length
|
|
183
|
+
] ??
|
|
184
|
+
DEFAULT_SQUARE_PYRAMID_COLOR
|
|
185
|
+
);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const hasActiveStack = computed(() => {
|
|
189
|
+
return (rootContext?.activeIndex.value ?? -1) >= 0;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
function handleStackClick(): void {
|
|
193
|
+
if (rootContext?.interactive.value) {
|
|
194
|
+
if (rootContext.activeIndex.value === resolvedIndex.value) {
|
|
195
|
+
rootContext.setActiveIndex(-1);
|
|
196
|
+
} else {
|
|
197
|
+
rootContext.setActiveIndex(resolvedIndex.value);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const deltaY = computed(() => {
|
|
203
|
+
return rootContext?.getCardDeltaY?.(resolvedIndex.value) ?? 0;
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const connectorWidth = computed(() => {
|
|
207
|
+
return Math.max(20, rightWingWidth.value - rightWidth.value);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
provide(SQUARE_PYRAMID_STACK_KEY, {
|
|
211
|
+
index: resolvedIndex,
|
|
212
|
+
isActive,
|
|
213
|
+
step: resolvedStep,
|
|
214
|
+
layerGeo: layerGeometry,
|
|
215
|
+
color: resolvedColor,
|
|
216
|
+
deltaY,
|
|
217
|
+
connectorWidth,
|
|
218
|
+
setActive: handleStackClick,
|
|
219
|
+
});
|
|
220
|
+
</script>
|
|
221
|
+
|
|
222
|
+
<template>
|
|
223
|
+
<div
|
|
224
|
+
class="alpha-square-pyramid-stack absolute inset-x-0 pointer-events-none select-none flex items-center justify-between"
|
|
225
|
+
:class="[
|
|
226
|
+
isActive
|
|
227
|
+
? 'alpha-square-pyramid-stack--active'
|
|
228
|
+
: 'alpha-square-pyramid-stack--inactive',
|
|
229
|
+
`alpha-square-pyramid-stack--${resolvedIndex}`,
|
|
230
|
+
]"
|
|
231
|
+
:data-index="resolvedIndex"
|
|
232
|
+
:data-active="isActive"
|
|
233
|
+
:style="{
|
|
234
|
+
top: `${posY}px`,
|
|
235
|
+
transform: 'translateY(-50%)',
|
|
236
|
+
}"
|
|
237
|
+
>
|
|
238
|
+
<!-- Left Wing: Title Pill (150px) -->
|
|
239
|
+
<div
|
|
240
|
+
class="alpha-square-pyramid-stack__left flex-shrink-0 flex items-center justify-start pointer-events-auto cursor-pointer"
|
|
241
|
+
:class="[
|
|
242
|
+
`alpha-square-pyramid-stack__left--${resolvedIndex}`,
|
|
243
|
+
{ 'alpha-square-pyramid-stack--animated': rootContext?.animation.value },
|
|
244
|
+
]"
|
|
245
|
+
:style="{
|
|
246
|
+
width: `${leftWidth}px`,
|
|
247
|
+
minWidth: `${leftWidth}px`,
|
|
248
|
+
maxWidth: `${leftWidth}px`,
|
|
249
|
+
opacity: !hasActiveStack || isActive ? 1 : 0.65,
|
|
250
|
+
}"
|
|
251
|
+
@click="handleStackClick"
|
|
252
|
+
>
|
|
253
|
+
<component :is="slottedTitle" v-if="slottedTitle" />
|
|
254
|
+
<SquarePyramidStackTitle
|
|
255
|
+
v-else
|
|
256
|
+
:step="resolvedStep"
|
|
257
|
+
:title="props.title || `Stage ${resolvedStep}`"
|
|
258
|
+
:connector-width="props.connectorWidth"
|
|
259
|
+
/>
|
|
260
|
+
</div>
|
|
261
|
+
<!-- Right Wing: Dot + Connector + Content Card (40px from slab) -->
|
|
262
|
+
<div
|
|
263
|
+
class="alpha-square-pyramid-stack__right flex-shrink-0 flex items-center justify-end pointer-events-auto cursor-pointer"
|
|
264
|
+
:class="[
|
|
265
|
+
`alpha-square-pyramid-stack__right--${resolvedIndex}`,
|
|
266
|
+
{ 'alpha-square-pyramid-stack--animated': rootContext?.animation.value },
|
|
267
|
+
]"
|
|
268
|
+
:style="{
|
|
269
|
+
width: `${rightWingWidth}px`,
|
|
270
|
+
minWidth: `${rightWidth}px`,
|
|
271
|
+
maxWidth: `${rightWingWidth}px`,
|
|
272
|
+
marginRight: rightOffset ? `${rightOffset}px` : undefined,
|
|
273
|
+
opacity: !hasActiveStack || isActive ? 1 : 0.65,
|
|
274
|
+
}"
|
|
275
|
+
@click="handleStackClick"
|
|
276
|
+
>
|
|
277
|
+
<component :is="slottedContent" v-if="slottedContent" />
|
|
278
|
+
<SquarePyramidStackContent
|
|
279
|
+
v-else
|
|
280
|
+
:content="props.content || 'Layer details and operational description.'"
|
|
281
|
+
/>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</template>
|
|
285
|
+
|
|
286
|
+
<style scoped>
|
|
287
|
+
.alpha-square-pyramid-stack {
|
|
288
|
+
height: 0;
|
|
289
|
+
overflow: visible;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.alpha-square-pyramid-stack__left,
|
|
293
|
+
.alpha-square-pyramid-stack__right {
|
|
294
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__left--0 {
|
|
298
|
+
animation: alpha-pyramid-left-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 100ms) both;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__left--1 {
|
|
302
|
+
animation: alpha-pyramid-left-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 180ms) both;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__left--2 {
|
|
306
|
+
animation: alpha-pyramid-left-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 260ms) both;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__left--3 {
|
|
310
|
+
animation: alpha-pyramid-left-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 340ms) both;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__left--4 {
|
|
314
|
+
animation: alpha-pyramid-left-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 420ms) both;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__left--5 {
|
|
318
|
+
animation: alpha-pyramid-left-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 500ms) both;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@keyframes alpha-pyramid-left-in {
|
|
322
|
+
0% {
|
|
323
|
+
opacity: 0;
|
|
324
|
+
transform: translateX(-12px);
|
|
325
|
+
}
|
|
326
|
+
100% {
|
|
327
|
+
opacity: 1;
|
|
328
|
+
transform: translateX(0);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__right--0 {
|
|
333
|
+
animation: alpha-pyramid-right-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 120ms) both;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__right--1 {
|
|
337
|
+
animation: alpha-pyramid-right-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 200ms) both;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__right--2 {
|
|
341
|
+
animation: alpha-pyramid-right-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 280ms) both;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__right--3 {
|
|
345
|
+
animation: alpha-pyramid-right-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 360ms) both;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__right--4 {
|
|
349
|
+
animation: alpha-pyramid-right-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 440ms) both;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.alpha-square-pyramid-stack--animated.alpha-square-pyramid-stack__right--5 {
|
|
353
|
+
animation: alpha-pyramid-right-in 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--square-pyramid-start-delay, 0ms) + 520ms) both;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
@keyframes alpha-pyramid-right-in {
|
|
357
|
+
0% {
|
|
358
|
+
opacity: 0;
|
|
359
|
+
transform: translateX(12px);
|
|
360
|
+
}
|
|
361
|
+
100% {
|
|
362
|
+
opacity: 1;
|
|
363
|
+
transform: translateX(0);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
</style>
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, inject, onMounted, onUnmounted, ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
import { createPyramidConnectorPath } from '../../../utils/pyramid/shared';
|
|
5
|
+
import {
|
|
6
|
+
SQUARE_PYRAMID_ROOT_KEY,
|
|
7
|
+
SQUARE_PYRAMID_STACK_KEY,
|
|
8
|
+
} from '../../../utils/pyramid/square-pyramid';
|
|
9
|
+
|
|
10
|
+
defineOptions({
|
|
11
|
+
name: 'SquarePyramidStackContent',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export interface ISquarePyramidStackContentProps {
|
|
15
|
+
readonly content?: string;
|
|
16
|
+
readonly color?: string;
|
|
17
|
+
readonly connectorWidth?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(defineProps<ISquarePyramidStackContentProps>(), {
|
|
21
|
+
content: undefined,
|
|
22
|
+
color: undefined,
|
|
23
|
+
connectorWidth: undefined,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const rootContext = inject(SQUARE_PYRAMID_ROOT_KEY, undefined);
|
|
27
|
+
const stackContext = inject(SQUARE_PYRAMID_STACK_KEY, undefined);
|
|
28
|
+
|
|
29
|
+
const connectorRef = ref<HTMLElement | null>(null);
|
|
30
|
+
const measuredConnectorWidth = ref<number>(0);
|
|
31
|
+
|
|
32
|
+
let resizeObserver: ResizeObserver | null = null;
|
|
33
|
+
|
|
34
|
+
function updateWidth(): void {
|
|
35
|
+
if (connectorRef.value && connectorRef.value.clientWidth > 0) {
|
|
36
|
+
measuredConnectorWidth.value = connectorRef.value.clientWidth;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onMounted(() => {
|
|
41
|
+
updateWidth();
|
|
42
|
+
if (typeof ResizeObserver !== 'undefined' && connectorRef.value) {
|
|
43
|
+
resizeObserver = new ResizeObserver(updateWidth);
|
|
44
|
+
resizeObserver.observe(connectorRef.value);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
onUnmounted(() => {
|
|
49
|
+
resizeObserver?.disconnect();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const isActive = computed(() => {
|
|
53
|
+
return stackContext?.isActive.value ?? false;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const contentWidth = computed(() => rootContext?.contentWidthPx.value ?? 240);
|
|
57
|
+
|
|
58
|
+
const deltaY = computed(() => {
|
|
59
|
+
if (stackContext?.deltaY?.value !== undefined) {
|
|
60
|
+
return stackContext.deltaY.value;
|
|
61
|
+
}
|
|
62
|
+
const idx = stackContext?.index.value ?? 0;
|
|
63
|
+
return rootContext?.getCardDeltaY?.(idx) ?? 0;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const effectiveDeltaY = computed(() => deltaY.value ?? 0);
|
|
67
|
+
|
|
68
|
+
const connectorWidth = computed(() => {
|
|
69
|
+
if (props.connectorWidth !== undefined) {
|
|
70
|
+
return props.connectorWidth;
|
|
71
|
+
}
|
|
72
|
+
if (stackContext?.connectorWidth?.value !== undefined) {
|
|
73
|
+
return stackContext.connectorWidth.value;
|
|
74
|
+
}
|
|
75
|
+
return measuredConnectorWidth.value || 40;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const svgMargin = 4;
|
|
79
|
+
const svgHeight = computed(() => {
|
|
80
|
+
return Math.max(8, Math.abs(effectiveDeltaY.value) + svgMargin * 2);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const svgMinY = computed(() => {
|
|
84
|
+
return Math.min(0, effectiveDeltaY.value) - svgMargin;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const svgTop = computed(() => {
|
|
88
|
+
return Math.min(0, effectiveDeltaY.value) - svgMargin;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const connectorPath = computed(() => {
|
|
92
|
+
const w = connectorWidth.value;
|
|
93
|
+
return createPyramidConnectorPath(
|
|
94
|
+
{ x: 0, y: 0 },
|
|
95
|
+
{ x: w, y: effectiveDeltaY.value },
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const stackColor = computed(() => {
|
|
100
|
+
return (
|
|
101
|
+
props.color ??
|
|
102
|
+
stackContext?.color?.value ??
|
|
103
|
+
rootContext?.color.value ??
|
|
104
|
+
'#3b82f6'
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<template>
|
|
110
|
+
<div class="alpha-square-pyramid-stack-content-wrapper relative w-full flex items-center select-none overflow-visible">
|
|
111
|
+
<!-- Scalable Line between Dot and Content Card (always at least 20px) -->
|
|
112
|
+
<div
|
|
113
|
+
ref="connectorRef"
|
|
114
|
+
class="alpha-square-pyramid-stack-content__connector flex-1 flex items-center min-w-[20px] pointer-events-none relative overflow-visible h-0"
|
|
115
|
+
>
|
|
116
|
+
<div
|
|
117
|
+
class="alpha-square-pyramid-stack-content__dot absolute left-0 top-0 -translate-x-1/2 -translate-y-1/2 w-1.5 h-1.5 rounded-full flex-shrink-0 transition-all duration-300 pointer-events-auto"
|
|
118
|
+
:style="{
|
|
119
|
+
backgroundColor: stackColor,
|
|
120
|
+
boxShadow: isActive
|
|
121
|
+
? `0 0 6px ${stackColor}`
|
|
122
|
+
: `0 0 2px ${stackColor}80`,
|
|
123
|
+
}"
|
|
124
|
+
/>
|
|
125
|
+
<!-- Straight horizontal line when deltaY is 0 -->
|
|
126
|
+
<div
|
|
127
|
+
v-if="!effectiveDeltaY"
|
|
128
|
+
class="alpha-square-pyramid-stack-content__line absolute left-0 top-0 w-full h-[1px] -translate-y-1/2 pointer-events-none transition-colors duration-300"
|
|
129
|
+
:style="{
|
|
130
|
+
backgroundColor: stackColor,
|
|
131
|
+
opacity: isActive ? 1 : 0.65,
|
|
132
|
+
}"
|
|
133
|
+
/>
|
|
134
|
+
<!-- Zigzag SVG connector when deltaY !== 0 -->
|
|
135
|
+
<svg
|
|
136
|
+
v-else
|
|
137
|
+
class="alpha-square-pyramid-stack-content__line-svg absolute left-0 pointer-events-none overflow-visible"
|
|
138
|
+
:width="connectorWidth"
|
|
139
|
+
:height="svgHeight"
|
|
140
|
+
:viewBox="`0 ${svgMinY} ${connectorWidth} ${svgHeight}`"
|
|
141
|
+
:style="{
|
|
142
|
+
top: `${svgTop}px`,
|
|
143
|
+
width: `${connectorWidth}px`,
|
|
144
|
+
height: `${svgHeight}px`,
|
|
145
|
+
}"
|
|
146
|
+
>
|
|
147
|
+
<path
|
|
148
|
+
class="alpha-square-pyramid-stack-content__line transition-all duration-300"
|
|
149
|
+
:d="connectorPath"
|
|
150
|
+
fill="none"
|
|
151
|
+
:stroke="stackColor"
|
|
152
|
+
stroke-width="1.25"
|
|
153
|
+
stroke-linecap="round"
|
|
154
|
+
stroke-linejoin="round"
|
|
155
|
+
:style="{
|
|
156
|
+
opacity: isActive ? 1 : 0.65,
|
|
157
|
+
}"
|
|
158
|
+
/>
|
|
159
|
+
</svg>
|
|
160
|
+
</div>
|
|
161
|
+
<!-- Content Card -->
|
|
162
|
+
<div
|
|
163
|
+
class="alpha-square-pyramid-stack-content rounded-xl p-2 px-2.5 transition-all duration-300 border select-none box-border flex-shrink-0"
|
|
164
|
+
:class="[
|
|
165
|
+
isActive
|
|
166
|
+
? 'alpha-square-pyramid-stack-content--active'
|
|
167
|
+
: 'alpha-square-pyramid-stack-content--default',
|
|
168
|
+
]"
|
|
169
|
+
:style="{
|
|
170
|
+
width: `${contentWidth}px`,
|
|
171
|
+
minWidth: `${contentWidth}px`,
|
|
172
|
+
maxWidth: `${contentWidth}px`,
|
|
173
|
+
boxSizing: 'border-box',
|
|
174
|
+
borderColor: stackColor,
|
|
175
|
+
backgroundColor: isActive
|
|
176
|
+
? 'rgba(255, 255, 255, 0.95)'
|
|
177
|
+
: 'rgba(255, 255, 255, 0.85)',
|
|
178
|
+
boxShadow: isActive
|
|
179
|
+
? `0 4px 14px ${stackColor}26`
|
|
180
|
+
: 'none',
|
|
181
|
+
transform: deltaY ? `translateY(${deltaY}px)` : undefined,
|
|
182
|
+
}"
|
|
183
|
+
>
|
|
184
|
+
<div
|
|
185
|
+
class="text-[10px] leading-snug transition-colors duration-300 break-words line-clamp-3"
|
|
186
|
+
:style="{
|
|
187
|
+
color: isActive ? '#0f172a' : '#475569',
|
|
188
|
+
}"
|
|
189
|
+
>
|
|
190
|
+
<slot>{{ props.content }}</slot>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</template>
|
|
195
|
+
|
|
196
|
+
<style scoped>
|
|
197
|
+
.alpha-square-pyramid-stack-content {
|
|
198
|
+
box-sizing: border-box;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.alpha-square-pyramid-stack-content--active {
|
|
202
|
+
backdrop-filter: blur(8px);
|
|
203
|
+
}
|
|
204
|
+
</style>
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, inject } from 'vue';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
SQUARE_PYRAMID_ROOT_KEY,
|
|
6
|
+
SQUARE_PYRAMID_STACK_KEY,
|
|
7
|
+
} from '../../../utils/pyramid/square-pyramid';
|
|
8
|
+
|
|
9
|
+
defineOptions({
|
|
10
|
+
name: 'SquarePyramidStackTitle',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export interface ISquarePyramidStackTitleProps {
|
|
14
|
+
readonly step?: string | number;
|
|
15
|
+
readonly title?: string;
|
|
16
|
+
readonly color?: string;
|
|
17
|
+
readonly minWidth?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const props = withDefaults(defineProps<ISquarePyramidStackTitleProps>(), {
|
|
21
|
+
step: undefined,
|
|
22
|
+
title: undefined,
|
|
23
|
+
color: undefined,
|
|
24
|
+
minWidth: 150,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const rootContext = inject(SQUARE_PYRAMID_ROOT_KEY, undefined);
|
|
28
|
+
const stackContext = inject(SQUARE_PYRAMID_STACK_KEY, undefined);
|
|
29
|
+
|
|
30
|
+
const isActive = computed(() => {
|
|
31
|
+
return stackContext?.isActive.value ?? false;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const resolvedStep = computed(() => {
|
|
35
|
+
if (props.step !== undefined) {
|
|
36
|
+
return props.step;
|
|
37
|
+
}
|
|
38
|
+
if (stackContext?.step.value !== undefined) {
|
|
39
|
+
return stackContext.step.value;
|
|
40
|
+
}
|
|
41
|
+
return '01';
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const minPillWidth = computed(() => props.minWidth ?? 150);
|
|
45
|
+
|
|
46
|
+
const stackColor = computed(() => {
|
|
47
|
+
return (
|
|
48
|
+
props.color ??
|
|
49
|
+
stackContext?.color?.value ??
|
|
50
|
+
rootContext?.color.value ??
|
|
51
|
+
'#3b82f6'
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<div
|
|
58
|
+
class="alpha-square-pyramid-stack-title relative w-full flex items-center select-none"
|
|
59
|
+
:class="[
|
|
60
|
+
isActive
|
|
61
|
+
? 'alpha-square-pyramid-stack-title--active'
|
|
62
|
+
: 'alpha-square-pyramid-stack-title--default',
|
|
63
|
+
]"
|
|
64
|
+
>
|
|
65
|
+
<!-- Pill Badge Container -->
|
|
66
|
+
<div
|
|
67
|
+
class="alpha-square-pyramid-stack-title__pill flex items-center gap-2 px-2.5 py-1 rounded-full transition-all duration-300 border flex-shrink-0"
|
|
68
|
+
:style="{
|
|
69
|
+
minWidth: `${minPillWidth}px`,
|
|
70
|
+
maxWidth: 'calc(100% - 30px)',
|
|
71
|
+
width: 'fit-content',
|
|
72
|
+
boxSizing: 'border-box',
|
|
73
|
+
borderColor: stackColor,
|
|
74
|
+
backgroundColor: isActive
|
|
75
|
+
? 'rgba(255, 255, 255, 0.95)'
|
|
76
|
+
: 'rgba(255, 255, 255, 0.85)',
|
|
77
|
+
boxShadow: isActive
|
|
78
|
+
? `0 4px 14px ${stackColor}26`
|
|
79
|
+
: 'none',
|
|
80
|
+
}"
|
|
81
|
+
>
|
|
82
|
+
<!-- Circular Step Indicator -->
|
|
83
|
+
<div
|
|
84
|
+
class="w-5.5 h-5.5 rounded-full flex items-center justify-center text-[10px] font-bold tracking-tight transition-all duration-300 flex-shrink-0"
|
|
85
|
+
:style="{
|
|
86
|
+
backgroundColor: stackColor,
|
|
87
|
+
color: '#ffffff',
|
|
88
|
+
}"
|
|
89
|
+
>
|
|
90
|
+
<slot name="step">{{ resolvedStep }}</slot>
|
|
91
|
+
</div>
|
|
92
|
+
<!-- Title Text -->
|
|
93
|
+
<span
|
|
94
|
+
class="text-xs font-semibold tracking-tight transition-colors duration-300 pr-1 truncate flex-1 leading-tight"
|
|
95
|
+
:style="{
|
|
96
|
+
color: isActive ? '#0f172a' : '#334155',
|
|
97
|
+
}"
|
|
98
|
+
>
|
|
99
|
+
<slot>{{ props.title }}</slot>
|
|
100
|
+
</span>
|
|
101
|
+
</div>
|
|
102
|
+
<!-- Scalable Line between Title and Dot -->
|
|
103
|
+
<div
|
|
104
|
+
class="alpha-square-pyramid-stack-title__connector flex-1 flex items-center min-w-[30px] pointer-events-none"
|
|
105
|
+
>
|
|
106
|
+
<div
|
|
107
|
+
class="alpha-square-pyramid-stack-title__line flex-1 h-[1px] transition-colors duration-300"
|
|
108
|
+
:style="{
|
|
109
|
+
backgroundColor: stackColor,
|
|
110
|
+
opacity: isActive ? 1 : 0.65,
|
|
111
|
+
}"
|
|
112
|
+
/>
|
|
113
|
+
<div
|
|
114
|
+
class="alpha-square-pyramid-stack-title__dot w-1.5 h-1.5 rounded-full flex-shrink-0 -ml-1 transition-all duration-300"
|
|
115
|
+
:style="{
|
|
116
|
+
backgroundColor: stackColor,
|
|
117
|
+
boxShadow: isActive
|
|
118
|
+
? `0 0 6px ${stackColor}`
|
|
119
|
+
: `0 0 2px ${stackColor}80`,
|
|
120
|
+
}"
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
</template>
|
|
125
|
+
|
|
126
|
+
<style scoped>
|
|
127
|
+
.alpha-square-pyramid-stack-title {
|
|
128
|
+
box-sizing: border-box;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.alpha-square-pyramid-stack-title--active .alpha-square-pyramid-stack-title__pill {
|
|
132
|
+
backdrop-filter: blur(8px);
|
|
133
|
+
}
|
|
134
|
+
</style>
|