@alphacifer/slidev-addon-theme 0.0.9 → 0.0.10
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/components/defense-in-depth/arc-did/ArcDiD.vue +732 -0
- package/components/defense-in-depth/arc-did/ArcDiDLayer.vue +321 -0
- package/components/defense-in-depth/arc-did/ArcDiDLayerPart.vue +449 -0
- package/components/defense-in-depth/arc-did/ArcDiDLayerParts.vue +11 -0
- package/components/defense-in-depth/arc-did/ArcDiDLayerSector.vue +148 -0
- package/components/defense-in-depth/arc-did/ArcDiDLayerTitle.vue +98 -0
- package/components/pyramid/circular-pyramid/CircularPyramid.vue +10 -23
- package/components/pyramid/circular-pyramid/CircularPyramidStack.vue +17 -50
- package/components/pyramid/circular-pyramid/CircularPyramidStackContent.vue +98 -1
- package/components/pyramid/circular-pyramid/CircularPyramidStackTitle.vue +70 -0
- package/components/pyramid/square-pyramid/SquarePyramid.vue +10 -23
- package/components/pyramid/square-pyramid/SquarePyramidStack.vue +17 -50
- package/components/pyramid/square-pyramid/SquarePyramidStackContent.vue +98 -1
- package/components/pyramid/square-pyramid/SquarePyramidStackTitle.vue +70 -0
- package/package.json +1 -1
- package/utils/defenseInDepth/arcDid/context.ts +110 -0
- package/utils/defenseInDepth/arcDid/createArcDiDGeometry.ts +570 -0
- package/utils/defenseInDepth/arcDid/index.ts +3 -0
- package/utils/defenseInDepth/arcDid/types.ts +140 -0
- package/utils/defenseInDepth/index.ts +2 -0
- package/utils/defenseInDepth/shared/colors.ts +121 -0
- package/utils/defenseInDepth/shared/constants.ts +14 -0
- package/utils/defenseInDepth/shared/index.ts +3 -0
- package/utils/defenseInDepth/shared/types.ts +12 -0
- package/utils/pyramid/shared/constants.ts +1 -0
- package/utils/useDiagramAutoScale.ts +61 -15
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
type ComputedRef,
|
|
4
|
+
computed,
|
|
5
|
+
Fragment,
|
|
6
|
+
inject,
|
|
7
|
+
onUnmounted,
|
|
8
|
+
provide,
|
|
9
|
+
ref,
|
|
10
|
+
useSlots,
|
|
11
|
+
type VNode,
|
|
12
|
+
watch,
|
|
13
|
+
} from 'vue';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
ARC_DID_LAYER_KEY,
|
|
17
|
+
ARC_DID_ROOT_KEY,
|
|
18
|
+
type IArcDiDLayerContext,
|
|
19
|
+
type IArcDiDRegisteredLayerData,
|
|
20
|
+
type IArcDiDRegisteredSectorData,
|
|
21
|
+
} from '../../../utils/defenseInDepth/arcDid/context';
|
|
22
|
+
import type {
|
|
23
|
+
IArcDiDPartGeometry,
|
|
24
|
+
IArcDiDPartItem,
|
|
25
|
+
IArcDiDSectorItem,
|
|
26
|
+
} from '../../../utils/defenseInDepth/arcDid/types';
|
|
27
|
+
import ArcDiDLayerPart from './ArcDiDLayerPart.vue';
|
|
28
|
+
import ArcDiDLayerParts from './ArcDiDLayerParts.vue';
|
|
29
|
+
import ArcDiDLayerSector from './ArcDiDLayerSector.vue';
|
|
30
|
+
import ArcDiDLayerTitle from './ArcDiDLayerTitle.vue';
|
|
31
|
+
|
|
32
|
+
defineOptions({
|
|
33
|
+
name: 'ArcDiDLayer',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export interface IArcDiDLayerProps {
|
|
37
|
+
readonly title?: string;
|
|
38
|
+
readonly color?: string;
|
|
39
|
+
readonly textColor?: string;
|
|
40
|
+
readonly index?: number;
|
|
41
|
+
readonly active?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const props = withDefaults(defineProps<IArcDiDLayerProps>(), {
|
|
45
|
+
title: undefined,
|
|
46
|
+
color: undefined,
|
|
47
|
+
textColor: undefined,
|
|
48
|
+
index: undefined,
|
|
49
|
+
active: undefined,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const slots = useSlots();
|
|
53
|
+
const rootContext = inject(ARC_DID_ROOT_KEY, undefined);
|
|
54
|
+
|
|
55
|
+
interface INamedComponent {
|
|
56
|
+
readonly type?: {
|
|
57
|
+
readonly name?: string;
|
|
58
|
+
readonly displayName?: string;
|
|
59
|
+
readonly __name?: string;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function hasComponentName(type: unknown, targetName: string): boolean {
|
|
64
|
+
if (typeof type === 'object' && type !== null) {
|
|
65
|
+
const comp = type as INamedComponent['type'];
|
|
66
|
+
return (
|
|
67
|
+
comp?.name === targetName ||
|
|
68
|
+
comp?.displayName === targetName ||
|
|
69
|
+
comp?.__name === targetName
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function flattenVNodes(nodes: VNode[]): VNode[] {
|
|
76
|
+
const result: VNode[] = [];
|
|
77
|
+
for (const node of nodes) {
|
|
78
|
+
if (node.type === Fragment && Array.isArray(node.children)) {
|
|
79
|
+
result.push(...flattenVNodes(node.children as VNode[]));
|
|
80
|
+
} else {
|
|
81
|
+
result.push(node);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const defaultNodes = computed(() => {
|
|
88
|
+
if (!slots.default) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return flattenVNodes(slots.default());
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const hasSlottedTitle = computed(() => {
|
|
95
|
+
return defaultNodes.value.some((node) =>
|
|
96
|
+
hasComponentName(node.type, 'ArcDiDLayerTitle'),
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const hasSlottedParts = computed(() => {
|
|
101
|
+
if (registeredSectorTokens.value.length > 0) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return defaultNodes.value.some(
|
|
105
|
+
(node) =>
|
|
106
|
+
hasComponentName(node.type, 'ArcDiDLayerParts') ||
|
|
107
|
+
hasComponentName(node.type, 'ArcDiDLayerPart') ||
|
|
108
|
+
hasComponentName(node.type, 'ArcDiDLayerSector'),
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const currentTitle = ref<string | undefined>(props.title);
|
|
113
|
+
watch(
|
|
114
|
+
() => props.title,
|
|
115
|
+
(val) => {
|
|
116
|
+
if (val !== undefined) {
|
|
117
|
+
currentTitle.value = val;
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// Manage sector and part registrations within this layer
|
|
123
|
+
const registeredSectorTokens = ref<symbol[]>([]);
|
|
124
|
+
const registeredSectorData = ref<Map<symbol, IArcDiDRegisteredSectorData>>(
|
|
125
|
+
new Map(),
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
function registerSector(
|
|
129
|
+
token?: symbol,
|
|
130
|
+
sectorDataRef?: ComputedRef<IArcDiDRegisteredSectorData | undefined>,
|
|
131
|
+
) {
|
|
132
|
+
const sToken = token ?? Symbol();
|
|
133
|
+
if (!registeredSectorTokens.value.includes(sToken)) {
|
|
134
|
+
registeredSectorTokens.value = [...registeredSectorTokens.value, sToken];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let stopWatch: (() => void) | undefined;
|
|
138
|
+
if (sectorDataRef) {
|
|
139
|
+
stopWatch = watch(
|
|
140
|
+
sectorDataRef,
|
|
141
|
+
(val) => {
|
|
142
|
+
const nextMap = new Map(registeredSectorData.value);
|
|
143
|
+
if (val) {
|
|
144
|
+
nextMap.set(sToken, val);
|
|
145
|
+
} else {
|
|
146
|
+
nextMap.delete(sToken);
|
|
147
|
+
}
|
|
148
|
+
registeredSectorData.value = nextMap;
|
|
149
|
+
},
|
|
150
|
+
{ immediate: true },
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const index = computed(() => registeredSectorTokens.value.indexOf(sToken));
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
index,
|
|
158
|
+
unregister: () => {
|
|
159
|
+
stopWatch?.();
|
|
160
|
+
registeredSectorTokens.value = registeredSectorTokens.value.filter(
|
|
161
|
+
(t) => t !== sToken,
|
|
162
|
+
);
|
|
163
|
+
const nextMap = new Map(registeredSectorData.value);
|
|
164
|
+
nextMap.delete(sToken);
|
|
165
|
+
registeredSectorData.value = nextMap;
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function registerPart(
|
|
171
|
+
token?: symbol,
|
|
172
|
+
partDataRef?: ComputedRef<IArcDiDPartItem | undefined>,
|
|
173
|
+
) {
|
|
174
|
+
const pToken = token ?? Symbol();
|
|
175
|
+
const sectorDataRef = computed<IArcDiDRegisteredSectorData | undefined>(
|
|
176
|
+
() => {
|
|
177
|
+
const pData = partDataRef?.value;
|
|
178
|
+
if (!pData) return undefined;
|
|
179
|
+
return {
|
|
180
|
+
parts: [pData],
|
|
181
|
+
split: false,
|
|
182
|
+
angle: pData.angle,
|
|
183
|
+
span: pData.span,
|
|
184
|
+
color: pData.color,
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
return registerSector(pToken, sectorDataRef);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const registeredSectorsList = computed<IArcDiDSectorItem[]>(() => {
|
|
192
|
+
return registeredSectorTokens.value
|
|
193
|
+
.map((token) => registeredSectorData.value.get(token))
|
|
194
|
+
.filter((item): item is IArcDiDRegisteredSectorData => item !== undefined)
|
|
195
|
+
.map((data) => ({
|
|
196
|
+
parts: data.parts ?? [],
|
|
197
|
+
split: data.split,
|
|
198
|
+
angle: data.angle,
|
|
199
|
+
span: data.span,
|
|
200
|
+
color: data.color,
|
|
201
|
+
}));
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const registeredPartsList = computed<IArcDiDPartItem[]>(() => {
|
|
205
|
+
return registeredSectorsList.value.flatMap(
|
|
206
|
+
(s) => s.parts as IArcDiDPartItem[],
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const layerToken = Symbol();
|
|
211
|
+
const layerRegistrationData = computed<IArcDiDRegisteredLayerData>(() => ({
|
|
212
|
+
title: currentTitle.value,
|
|
213
|
+
color: props.color,
|
|
214
|
+
sectors: registeredSectorsList.value,
|
|
215
|
+
parts: registeredPartsList.value,
|
|
216
|
+
index: props.index !== undefined ? Number(props.index) : undefined,
|
|
217
|
+
}));
|
|
218
|
+
|
|
219
|
+
const registration = rootContext?.registerLayer(
|
|
220
|
+
layerToken,
|
|
221
|
+
layerRegistrationData,
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
onUnmounted(() => {
|
|
225
|
+
registration?.unregister();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const resolvedIndex = computed<number>(() => {
|
|
229
|
+
if (props.index !== undefined) {
|
|
230
|
+
return Number(props.index);
|
|
231
|
+
}
|
|
232
|
+
return registration?.index.value ?? 0;
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const layerGeo = computed(() => {
|
|
236
|
+
if (!rootContext) {
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
return rootContext.geo.value.layers[resolvedIndex.value];
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const isActive = computed<boolean>(() => {
|
|
243
|
+
if (props.active !== undefined) {
|
|
244
|
+
return props.active;
|
|
245
|
+
}
|
|
246
|
+
if (!rootContext) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
return (
|
|
250
|
+
rootContext.activeIndex.value === -1 ||
|
|
251
|
+
rootContext.activeIndex.value === resolvedIndex.value
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const effectiveColor = computed<string>(() => {
|
|
256
|
+
if (props.color) {
|
|
257
|
+
return props.color;
|
|
258
|
+
}
|
|
259
|
+
if (rootContext) {
|
|
260
|
+
return rootContext.getLayerColor(resolvedIndex.value);
|
|
261
|
+
}
|
|
262
|
+
return '#0ea5e9';
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const layerContext: IArcDiDLayerContext = {
|
|
266
|
+
layerIndex: resolvedIndex,
|
|
267
|
+
layerGeo,
|
|
268
|
+
isActive,
|
|
269
|
+
color: effectiveColor,
|
|
270
|
+
textColor: computed(() => props.textColor),
|
|
271
|
+
title: computed(() => currentTitle.value),
|
|
272
|
+
setTitle: (title: string) => {
|
|
273
|
+
currentTitle.value = title;
|
|
274
|
+
},
|
|
275
|
+
partsCount: computed(() => registeredPartsList.value.length),
|
|
276
|
+
registerPart,
|
|
277
|
+
registerSector,
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
provide(ARC_DID_LAYER_KEY, layerContext);
|
|
281
|
+
</script>
|
|
282
|
+
|
|
283
|
+
<template>
|
|
284
|
+
<div
|
|
285
|
+
class="alpha-arc-did__layer contents"
|
|
286
|
+
:data-index="resolvedIndex"
|
|
287
|
+
:data-active="isActive"
|
|
288
|
+
>
|
|
289
|
+
<!-- Auto-render title if prop title provided but no slotted ArcDiDLayerTitle -->
|
|
290
|
+
<ArcDiDLayerTitle v-if="!hasSlottedTitle && currentTitle" :title="currentTitle" />
|
|
291
|
+
|
|
292
|
+
<!-- Default children slots -->
|
|
293
|
+
<slot />
|
|
294
|
+
|
|
295
|
+
<!-- Fallback parts from geometry if layer has no slotted parts and default geo parts/sectors exist -->
|
|
296
|
+
<ArcDiDLayerParts v-if="!hasSlottedParts && registeredSectorTokens.length === 0 && layerGeo && layerGeo.sectors.length > 0">
|
|
297
|
+
<template v-for="sector in layerGeo.sectors" :key="sector.index">
|
|
298
|
+
<ArcDiDLayerSector v-if="sector.parts.length > 1 || sector.split" :split="sector.split">
|
|
299
|
+
<ArcDiDLayerPart
|
|
300
|
+
v-for="part in sector.parts"
|
|
301
|
+
:key="part.index"
|
|
302
|
+
:label="part.label"
|
|
303
|
+
:index="part.index"
|
|
304
|
+
:position="part.position"
|
|
305
|
+
:angle="part.angle"
|
|
306
|
+
:radius="part.radius"
|
|
307
|
+
/>
|
|
308
|
+
</ArcDiDLayerSector>
|
|
309
|
+
<ArcDiDLayerPart
|
|
310
|
+
v-else-if="sector.parts[0]"
|
|
311
|
+
:key="sector.parts[0].index"
|
|
312
|
+
:label="sector.parts[0].label"
|
|
313
|
+
:index="sector.parts[0].index"
|
|
314
|
+
:position="sector.parts[0].position"
|
|
315
|
+
:angle="sector.parts[0].angle"
|
|
316
|
+
:radius="sector.parts[0].radius"
|
|
317
|
+
/>
|
|
318
|
+
</template>
|
|
319
|
+
</ArcDiDLayerParts>
|
|
320
|
+
</div>
|
|
321
|
+
</template>
|