@alphacifer/slidev-addon-theme 0.0.9 → 0.0.11

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 (220) hide show
  1. package/README.md +133 -75
  2. package/components/card/chevron-card/ChevronCard.vue +44 -32
  3. package/components/card/chevron-card/ChevronCardBadge.vue +14 -8
  4. package/components/card/chevron-card/ChevronCardContent.vue +15 -13
  5. package/components/card/chevron-card/style.css +12 -0
  6. package/components/card/{horiz-card/HorizCard.vue → horizontal-card/HorizontalCard.vue} +78 -85
  7. package/components/card/{horiz-card/HorizCardBadge.vue → horizontal-card/HorizontalCardBadge.vue} +15 -10
  8. package/components/card/{horiz-card/HorizCardContent.vue → horizontal-card/HorizontalCardContent.vue} +11 -11
  9. package/components/card/{horiz-card/HorizCardIcon.vue → horizontal-card/HorizontalCardIcon.vue} +24 -38
  10. package/components/card/horizontal-card/style.css +17 -0
  11. package/components/card/{vert-card/VertCard.vue → vertical-card/VerticalCard.vue} +80 -103
  12. package/components/card/{vert-card/VertCardBadge.vue → vertical-card/VerticalCardBadge.vue} +15 -10
  13. package/components/card/{vert-card/VertCardContent.vue → vertical-card/VerticalCardContent.vue} +13 -12
  14. package/components/card/{vert-card/VertCardIcon.vue → vertical-card/VerticalCardIcon.vue} +15 -33
  15. package/components/card/vertical-card/style.css +19 -0
  16. package/components/comparisons/arc-comparison/ArcComparison.vue +376 -80
  17. package/components/comparisons/arc-comparison/ArcComparisonBadge.vue +9 -4
  18. package/components/comparisons/arc-comparison/ArcComparisonContent.vue +9 -4
  19. package/components/comparisons/arc-comparison/ArcComparisonHeading.vue +9 -4
  20. package/components/comparisons/arc-comparison/ArcComparisonLeft.vue +39 -63
  21. package/components/comparisons/arc-comparison/ArcComparisonOrbit.vue +9 -8
  22. package/components/comparisons/arc-comparison/ArcComparisonRight.vue +39 -63
  23. package/components/comparisons/arc-comparison/style.css +27 -0
  24. package/components/comparisons/table-comparison/TableComparison.vue +17 -97
  25. package/components/comparisons/table-comparison/TableComparisonCell.vue +22 -20
  26. package/components/comparisons/table-comparison/{TableComparisonCol.vue → TableComparisonColumn.vue} +16 -14
  27. package/components/comparisons/table-comparison/{TableComparisonCols.vue → TableComparisonColumns.vue} +5 -8
  28. package/components/comparisons/table-comparison/TableComparisonRow.vue +10 -14
  29. package/components/comparisons/table-comparison/TableComparisonRows.vue +1 -4
  30. package/components/comparisons/table-comparison/style.css +15 -0
  31. package/components/core/Date.vue +2 -5
  32. package/components/core/QnA.vue +1 -1
  33. package/components/core/Quote.vue +3 -6
  34. package/components/core/ReflectedTitle.vue +2 -6
  35. package/components/core/Speaker.vue +5 -10
  36. package/components/core/TransitionHeading.vue +2 -5
  37. package/components/core/arc-orbit/ArcOrbit.vue +65 -84
  38. package/components/core/arc-orbit/ArcOrbitBadge.vue +9 -11
  39. package/components/core/arc-orbit/ArcOrbitCallout.vue +30 -32
  40. package/components/core/arc-orbit/ArcOrbitContent.vue +6 -12
  41. package/components/core/arc-orbit/ArcOrbitHeading.vue +13 -11
  42. package/components/core/arc-orbit/style.css +20 -0
  43. package/components/core/style.css +9 -0
  44. package/components/core/thanks/{ThanksContent.vue → SquareThanks.vue} +36 -31
  45. package/components/core/thanks/SquareThanksContent.vue +89 -0
  46. package/components/core/thanks/ThanksOutlineSquare.vue +2 -5
  47. package/components/core/thanks/ThanksSquare.vue +2 -5
  48. package/components/core/thanks/style.css +30 -0
  49. package/components/defense-in-depth/arc-defense-in-depth/ArcDefenseInDepth.vue +802 -0
  50. package/components/defense-in-depth/arc-defense-in-depth/ArcDefenseInDepthLayer.vue +240 -0
  51. package/components/defense-in-depth/arc-defense-in-depth/ArcDefenseInDepthLayerHeading.vue +96 -0
  52. package/components/defense-in-depth/arc-defense-in-depth/ArcDefenseInDepthLayerPart.vue +501 -0
  53. package/components/defense-in-depth/arc-defense-in-depth/ArcDefenseInDepthLayerSector.vue +162 -0
  54. package/components/defense-in-depth/arc-defense-in-depth/style.css +38 -0
  55. package/components/facets/tetrad/{rect-orbit-tetrad/RectOrbitTetrad.vue → rectangle-orbit-tetrad/RectangleOrbitTetrad.vue} +66 -63
  56. package/components/facets/tetrad/{rect-orbit-tetrad/RectOrbitTetradCallout.vue → rectangle-orbit-tetrad/RectangleOrbitTetradCallout.vue} +62 -48
  57. package/components/facets/tetrad/rectangle-orbit-tetrad/RectangleOrbitTetradCenter.vue +54 -0
  58. package/components/facets/tetrad/rectangle-orbit-tetrad/RectangleOrbitTetradContent.vue +44 -0
  59. package/components/facets/tetrad/rectangle-orbit-tetrad/RectangleOrbitTetradHeading.vue +27 -0
  60. package/components/facets/tetrad/{rect-orbit-tetrad/RectOrbitTetradIcon.vue → rectangle-orbit-tetrad/RectangleOrbitTetradIcon.vue} +23 -13
  61. package/components/facets/tetrad/rectangle-orbit-tetrad/style.css +22 -0
  62. package/components/facets/triad/arrow-triad/ArrowTriad.vue +99 -109
  63. package/components/facets/triad/arrow-triad/ArrowTriadCallout.vue +31 -59
  64. package/components/facets/triad/arrow-triad/ArrowTriadContent.vue +18 -13
  65. package/components/facets/triad/arrow-triad/ArrowTriadHeading.vue +20 -13
  66. package/components/facets/triad/arrow-triad/ArrowTriadIcon.vue +14 -9
  67. package/components/facets/triad/arrow-triad/style.css +15 -0
  68. package/components/facets/triad/gear-triad/GearTriad.vue +73 -64
  69. package/components/facets/triad/gear-triad/GearTriadCallout.vue +58 -53
  70. package/components/facets/triad/gear-triad/GearTriadCenter.vue +9 -4
  71. package/components/facets/triad/gear-triad/GearTriadContent.vue +21 -36
  72. package/components/facets/triad/gear-triad/GearTriadDetail.vue +92 -0
  73. package/components/facets/triad/gear-triad/GearTriadDetails.vue +169 -0
  74. package/components/facets/triad/gear-triad/GearTriadDetailsContent.vue +18 -0
  75. package/components/facets/triad/gear-triad/GearTriadDetailsHeading.vue +60 -0
  76. package/components/facets/triad/gear-triad/GearTriadHeading.vue +19 -13
  77. package/components/facets/triad/gear-triad/GearTriadIcon.vue +22 -9
  78. package/components/facets/triad/gear-triad/style.css +26 -0
  79. package/components/facets/triad/{hex-triad/HexTriad.vue → hexagon-triad/HexagonTriad.vue} +81 -63
  80. package/components/facets/triad/{hex-triad/HexTriadBadge.vue → hexagon-triad/HexagonTriadBadge.vue} +38 -12
  81. package/components/facets/triad/{hex-triad/HexTriadCallout.vue → hexagon-triad/HexagonTriadCallout.vue} +35 -31
  82. package/components/facets/triad/hexagon-triad/HexagonTriadCenterBadge.vue +74 -0
  83. package/components/facets/triad/hexagon-triad/HexagonTriadContent.vue +34 -0
  84. package/components/facets/triad/hexagon-triad/HexagonTriadHeading.vue +44 -0
  85. package/components/facets/triad/{hex-triad/HexTriadLayer.vue → hexagon-triad/HexagonTriadLayer.vue} +12 -4
  86. package/components/facets/triad/hexagon-triad/style.css +22 -0
  87. package/components/process/arc-arrow-process/ArcArrowProcess.vue +13 -35
  88. package/components/process/arc-arrow-process/ArcArrowProcessArrow.vue +20 -21
  89. package/components/process/arc-arrow-process/ArcArrowProcessCallout.vue +30 -71
  90. package/components/process/arc-arrow-process/ArcArrowProcessContent.vue +18 -13
  91. package/components/process/arc-arrow-process/ArcArrowProcessHeading.vue +18 -18
  92. package/components/process/arc-arrow-process/ArcArrowProcessIcon.vue +23 -11
  93. package/components/process/arc-arrow-process/style.css +20 -0
  94. package/components/pyramid/circular-pyramid/CircularPyramid.vue +276 -190
  95. package/components/pyramid/circular-pyramid/CircularPyramidStack.vue +83 -98
  96. package/components/pyramid/circular-pyramid/CircularPyramidStackContent.vue +136 -29
  97. package/components/pyramid/circular-pyramid/CircularPyramidStackHeading.vue +212 -0
  98. package/components/pyramid/circular-pyramid/style.css +26 -0
  99. package/components/pyramid/square-pyramid/SquarePyramid.vue +199 -83
  100. package/components/pyramid/square-pyramid/SquarePyramidStack.vue +87 -95
  101. package/components/pyramid/square-pyramid/SquarePyramidStackContent.vue +138 -27
  102. package/components/pyramid/square-pyramid/SquarePyramidStackHeading.vue +212 -0
  103. package/components/pyramid/square-pyramid/style.css +48 -0
  104. package/components/style.css +35 -0
  105. package/layouts/core/arc-toc.vue +40 -45
  106. package/layouts/core/bg-center.vue +7 -6
  107. package/layouts/core/style.css +17 -0
  108. package/layouts/shifting-heading/shifting-intro.vue +4 -13
  109. package/layouts/thanks/thanks.vue +5 -5
  110. package/package.json +8 -6
  111. package/style.css +17 -0
  112. package/uno.config.ts +1 -0
  113. package/utils/activateOnKeyboard.ts +14 -0
  114. package/utils/{chevronCard → card/chevron-card}/context.ts +1 -1
  115. package/utils/card/chevron-card/index.ts +1 -0
  116. package/utils/card/horizontal-card/context.ts +12 -0
  117. package/utils/{horizCard/createHorizCardGeometry.ts → card/horizontal-card/createHorizontalCardGeometry.ts} +10 -45
  118. package/utils/card/horizontal-card/index.ts +2 -0
  119. package/utils/card/vertical-card/context.ts +19 -0
  120. package/utils/{vertCard/createVertCardGeometry.ts → card/vertical-card/createVerticalCardGeometry.ts} +9 -130
  121. package/utils/card/vertical-card/index.ts +2 -0
  122. package/utils/colors.ts +93 -0
  123. package/utils/{arcComparison → comparisons/arc-comparison}/context.ts +0 -11
  124. package/utils/{arcComparison → comparisons/arc-comparison}/createArcComparisonGeometry.ts +1 -1
  125. package/utils/comparisons/arc-comparison/resolveArcComparisonItems.ts +33 -0
  126. package/utils/comparisons/table-comparison/constants.ts +47 -0
  127. package/utils/{tableComparison → comparisons/table-comparison}/context.ts +2 -2
  128. package/utils/{arcOrbit → core/arc-orbit}/resolveArcOrbitItems.ts +11 -15
  129. package/utils/defense-in-depth/arc-defense-in-depth/context.ts +113 -0
  130. package/utils/defense-in-depth/arc-defense-in-depth/createArcDefenseInDepthGeometry.ts +600 -0
  131. package/utils/defense-in-depth/arc-defense-in-depth/types.ts +144 -0
  132. package/utils/defense-in-depth/shared/colors.ts +51 -0
  133. package/utils/defense-in-depth/shared/constants.ts +22 -0
  134. package/utils/defense-in-depth/shared/types.ts +7 -0
  135. package/utils/facets/tetrad/rectangle-orbit-tetrad/context.ts +31 -0
  136. package/utils/{rectOrbitTetrad/createRectOrbitTetradGeometry.ts → facets/tetrad/rectangle-orbit-tetrad/createRectangleOrbitTetradGeometry.ts} +5 -104
  137. package/utils/facets/tetrad/rectangle-orbit-tetrad/index.ts +3 -0
  138. package/utils/{rectOrbitTetrad/resolveRectOrbitTetradItems.ts → facets/tetrad/rectangle-orbit-tetrad/resolveRectangleOrbitTetradItems.ts} +41 -49
  139. package/utils/{arrowTriad → facets/triad/arrow-triad}/resolveArrowTriadItems.ts +27 -28
  140. package/utils/{gearTriad → facets/triad/gear-triad}/context.ts +5 -5
  141. package/utils/{gearTriad → facets/triad/gear-triad}/createGearTriadGeometry.ts +2 -0
  142. package/utils/{gearTriad → facets/triad/gear-triad}/resolveGearTriadItems.ts +23 -24
  143. package/utils/facets/triad/hexagon-triad/context.ts +25 -0
  144. package/utils/{hexTriad/createHexTriadGeometry.ts → facets/triad/hexagon-triad/createHexagonTriadGeometry.ts} +11 -27
  145. package/utils/facets/triad/hexagon-triad/index.ts +3 -0
  146. package/utils/facets/triad/hexagon-triad/resolveHexagonTriadItems.ts +60 -0
  147. package/utils/{shiftingHeading → layouts/shifting-heading}/collectShiftingIntroNodes.ts +1 -0
  148. package/utils/layouts/table-of-contents/calculateTocCenterAlignmentOffset.ts +17 -0
  149. package/utils/{tableOfContents → layouts/table-of-contents}/calculateTocMarkerPositions.ts +0 -12
  150. package/utils/{tableOfContents → layouts/table-of-contents}/createTocConnectorPath.ts +11 -5
  151. package/utils/{mergeUno → merge-uno}/classifyVisual.ts +1 -1
  152. package/utils/{mergeUno → merge-uno}/collectClassNames.ts +9 -3
  153. package/utils/process/arc-arrow-process/resolveArcArrowProcessItems.ts +180 -0
  154. package/utils/pyramid/circular-pyramid/context.ts +1 -4
  155. package/utils/pyramid/circular-pyramid/createCircularPyramidGeometry.ts +6 -10
  156. package/utils/pyramid/shared/colors.ts +33 -83
  157. package/utils/pyramid/shared/constants.ts +3 -2
  158. package/utils/pyramid/shared/types.ts +0 -5
  159. package/utils/pyramid/square-pyramid/context.ts +1 -4
  160. package/utils/pyramid/square-pyramid/createSquarePyramidGeometry.ts +6 -10
  161. package/utils/useDiagramAutoScale.ts +64 -16
  162. package/utils/useMergedUnoAttrs.ts +9 -5
  163. package/components/card/chevron-card/ChevronCardHeading.vue +0 -39
  164. package/components/card/horiz-card/HorizCardHeading.vue +0 -47
  165. package/components/card/vert-card/VertCardHeading.vue +0 -68
  166. package/components/card/vert-card/VertCardTitle.vue +0 -76
  167. package/components/comparisons/arc-comparison/ArcComparisonContents.vue +0 -17
  168. package/components/comparisons/arc-comparison/ArcComparisonTitle.vue +0 -29
  169. package/components/core/arc-orbit/ArcOrbitContents.vue +0 -18
  170. package/components/core/arc-orbit/ArcOrbitTitle.vue +0 -50
  171. package/components/facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCenter.vue +0 -53
  172. package/components/facets/tetrad/rect-orbit-tetrad/RectOrbitTetradContent.vue +0 -39
  173. package/components/facets/tetrad/rect-orbit-tetrad/RectOrbitTetradHeading.vue +0 -44
  174. package/components/facets/triad/gear-triad/GearTriadContents.vue +0 -111
  175. package/components/facets/triad/gear-triad/GearTriadDescription.vue +0 -38
  176. package/components/facets/triad/hex-triad/HexTriadCenterBadge.vue +0 -51
  177. package/components/facets/triad/hex-triad/HexTriadContent.vue +0 -20
  178. package/components/facets/triad/hex-triad/HexTriadHeading.vue +0 -28
  179. package/components/pyramid/circular-pyramid/CircularPyramidStackTitle.vue +0 -138
  180. package/components/pyramid/square-pyramid/SquarePyramidStackTitle.vue +0 -134
  181. package/layouts/core/table-of-contents.vue +0 -30
  182. package/utils/arcArrowProcess/resolveArcArrowProcessItems.ts +0 -189
  183. package/utils/arcComparison/resolveArcComparisonItems.ts +0 -102
  184. package/utils/chevronCard/createChevronCardGeometry.ts +0 -48
  185. package/utils/chevronCard/index.ts +0 -2
  186. package/utils/hexTriad/context.ts +0 -25
  187. package/utils/hexTriad/index.ts +0 -3
  188. package/utils/hexTriad/resolveHexTriadItems.ts +0 -63
  189. package/utils/horizCard/context.ts +0 -13
  190. package/utils/horizCard/index.ts +0 -2
  191. package/utils/pyramid/index.ts +0 -3
  192. package/utils/rectOrbitTetrad/context.ts +0 -31
  193. package/utils/rectOrbitTetrad/index.ts +0 -3
  194. package/utils/tableComparison/constants.ts +0 -72
  195. package/utils/tableOfContents/calculateTocCenterAlignmentOffset.ts +0 -11
  196. package/utils/vertCard/context.ts +0 -18
  197. package/utils/vertCard/index.ts +0 -2
  198. package/utils/{arcComparison → comparisons/arc-comparison}/index.ts +0 -0
  199. package/utils/{tableComparison → comparisons/table-comparison}/index.ts +0 -0
  200. package/utils/{arcOrbit → core/arc-orbit}/context.ts +0 -0
  201. package/utils/{arcOrbit → core/arc-orbit}/createArcOrbitGeometry.ts +0 -0
  202. package/utils/{arcOrbit → core/arc-orbit}/index.ts +0 -0
  203. package/utils/{arrowTriad → facets/triad/arrow-triad}/context.ts +0 -0
  204. package/utils/{arrowTriad → facets/triad/arrow-triad}/createArrowTriadGeometry.ts +0 -0
  205. package/utils/{arrowTriad → facets/triad/arrow-triad}/index.ts +0 -0
  206. package/utils/{gearTriad → facets/triad/gear-triad}/index.ts +0 -0
  207. package/utils/{tableOfContents → layouts/table-of-contents}/calculateUniformTocArticleWidth.ts +0 -0
  208. package/utils/{tableOfContents → layouts/table-of-contents}/createTocArcPath.ts +0 -0
  209. package/utils/{tableOfContents → layouts/table-of-contents}/index.ts +0 -0
  210. package/utils/{mergeUno → merge-uno}/classifyLayout.ts +0 -0
  211. package/utils/{mergeUno → merge-uno}/classifySimple.ts +0 -0
  212. package/utils/{mergeUno → merge-uno}/classifyTypography.ts +0 -0
  213. package/utils/{mergeUno → merge-uno}/classifyUtility.ts +0 -0
  214. package/utils/{mergeUno → merge-uno}/index.ts +0 -0
  215. package/utils/{mergeUno → merge-uno}/mergeClassValues.ts +0 -0
  216. package/utils/{mergeUno → merge-uno}/splitVariantScope.ts +1 -1
  217. package/utils/{mergeUno → merge-uno}/types.ts +0 -0
  218. package/utils/{arcArrowProcess → process/arc-arrow-process}/context.ts +1 -1
  219. /package/utils/{arcArrowProcess → process/arc-arrow-process}/createArcArrowProcessGeometry.ts +0 -0
  220. /package/utils/{arcArrowProcess → process/arc-arrow-process}/index.ts +0 -0
@@ -0,0 +1,501 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject, onUnmounted, useSlots, type VNode } from 'vue';
3
+
4
+ import {
5
+ ARC_DID_LAYER_KEY,
6
+ ARC_DID_ROOT_KEY,
7
+ ARC_DID_SECTOR_KEY,
8
+ } from '../../../utils/defense-in-depth/arc-defense-in-depth/context';
9
+ import {
10
+ calculatePartAngles,
11
+ polarToCartesian,
12
+ } from '../../../utils/defense-in-depth/arc-defense-in-depth/createArcDefenseInDepthGeometry';
13
+ import type {
14
+ IArcDefenseInDepthPartItem,
15
+ TArcDefenseInDepthOrientation,
16
+ TArcDefenseInDepthPartPosition,
17
+ } from '../../../utils/defense-in-depth/arc-defense-in-depth/types';
18
+ import { DEFAULT_DID_DOT_COLOR } from '../../../utils/defense-in-depth/shared/constants';
19
+ import { useMergedUnoAttrs } from '../../../utils/useMergedUnoAttrs';
20
+
21
+ defineOptions({
22
+ inheritAttrs: false,
23
+ name: 'ArcDefenseInDepthLayerPart',
24
+ });
25
+
26
+ export interface IArcDefenseInDepthLayerPartProps {
27
+ readonly label?: string;
28
+ readonly index?: number;
29
+ readonly angle?: number;
30
+ readonly radius?: number;
31
+ readonly radialOffset?: number;
32
+ readonly color?: string;
33
+ readonly icon?: string;
34
+ readonly showDot?: boolean;
35
+ readonly span?: number;
36
+ readonly position?: TArcDefenseInDepthPartPosition;
37
+ readonly maxWidth?: number | string;
38
+ readonly rotate?: TArcDefenseInDepthOrientation;
39
+ readonly skew?: TArcDefenseInDepthOrientation;
40
+ readonly active?: boolean;
41
+ }
42
+
43
+ const props = withDefaults(defineProps<IArcDefenseInDepthLayerPartProps>(), {
44
+ label: undefined,
45
+ index: undefined,
46
+ angle: undefined,
47
+ radius: undefined,
48
+ radialOffset: undefined,
49
+ color: undefined,
50
+ icon: undefined,
51
+ showDot: false,
52
+ span: undefined,
53
+ position: undefined,
54
+ maxWidth: undefined,
55
+ rotate: undefined,
56
+ skew: undefined,
57
+ active: undefined,
58
+ });
59
+
60
+ const slots = useSlots();
61
+ const rootContext = inject(ARC_DID_ROOT_KEY, undefined);
62
+ const layerContext = inject(ARC_DID_LAYER_KEY, undefined);
63
+ const sectorContext = inject(ARC_DID_SECTOR_KEY, undefined);
64
+
65
+ function extractTextFromVNodes(nodes: VNode[]): string {
66
+ let text = '';
67
+ for (const node of nodes) {
68
+ if (typeof node.type === 'string' && node.type === 'br') {
69
+ text += '\n';
70
+ } else if (typeof node.children === 'string') {
71
+ text += node.children;
72
+ } else if (Array.isArray(node.children)) {
73
+ text += extractTextFromVNodes(node.children as VNode[]);
74
+ }
75
+ }
76
+
77
+ return text.trim();
78
+ }
79
+
80
+ const slottedLabel = computed<string>(() => {
81
+ if (props.label) {
82
+ return props.label;
83
+ }
84
+
85
+ if (slots.default) {
86
+ const vnodes = slots.default();
87
+ const textNode = vnodes[0]?.children;
88
+ if (typeof textNode === 'string') {
89
+ return textNode.trim();
90
+ }
91
+
92
+ return extractTextFromVNodes(slots.default());
93
+ }
94
+
95
+ return '';
96
+ });
97
+
98
+ const partToken = Symbol();
99
+ const registrationData = computed<IArcDefenseInDepthPartItem>(() => ({
100
+ label: slottedLabel.value,
101
+ angle: props.angle,
102
+ radius: props.radius,
103
+ radialOffset: props.radialOffset,
104
+ color: props.color,
105
+ icon: props.icon,
106
+ span: props.span,
107
+ position: props.position,
108
+ maxWidth: props.maxWidth,
109
+ rotate: props.rotate,
110
+ skew: props.skew,
111
+ active: props.active,
112
+ }));
113
+
114
+ const registration = sectorContext
115
+ ? sectorContext.registerPart(partToken, registrationData)
116
+ : layerContext?.registerPart(partToken, registrationData);
117
+
118
+ onUnmounted(() => {
119
+ registration?.unregister();
120
+ });
121
+
122
+ const resolvedIndex = computed<number>(() => {
123
+ if (props.index !== undefined) {
124
+ return Number(props.index);
125
+ }
126
+
127
+ return registration?.index.value ?? 0;
128
+ });
129
+
130
+ const calculatedPosition = computed(() => {
131
+ const geo = layerContext?.layerGeo.value;
132
+ const rootGeo = rootContext?.geo.value;
133
+
134
+ if (props.angle !== undefined && rootGeo && geo) {
135
+ const r = props.radius ?? geo.midRadius + (props.radialOffset ?? 0);
136
+ return polarToCartesian(rootGeo.cx, rootGeo.cy, r, props.angle);
137
+ }
138
+
139
+ if (sectorContext) {
140
+ const partGeo = sectorContext.sectorGeo.value?.parts[resolvedIndex.value];
141
+ if (partGeo) {
142
+ return { x: partGeo.x, y: partGeo.y };
143
+ }
144
+ } else {
145
+ const standalonePartGeo =
146
+ layerContext?.layerGeo.value?.sectors[resolvedIndex.value]?.parts[0];
147
+ if (standalonePartGeo) {
148
+ return { x: standalonePartGeo.x, y: standalonePartGeo.y };
149
+ }
150
+ }
151
+
152
+ const partGeo = geo?.parts[resolvedIndex.value];
153
+ if (partGeo) {
154
+ return { x: partGeo.x, y: partGeo.y };
155
+ }
156
+
157
+ if (rootGeo && geo) {
158
+ const totalParts = layerContext?.partsCount?.value ?? 1;
159
+ const angles = calculatePartAngles(totalParts);
160
+ const fallbackAngle = angles[resolvedIndex.value] ?? 90;
161
+ const r = props.radius ?? geo.midRadius + (props.radialOffset ?? 0);
162
+ return polarToCartesian(rootGeo.cx, rootGeo.cy, r, fallbackAngle);
163
+ }
164
+
165
+ return { x: 0, y: 0 };
166
+ });
167
+
168
+ const isAnimated = computed(() => rootContext?.animation.value ?? true);
169
+ const rootStartDelay = computed(() => rootContext?.startDelay.value ?? 0);
170
+
171
+ const effectiveDotColor = computed(() => {
172
+ return props.color ?? layerContext?.color.value ?? DEFAULT_DID_DOT_COLOR;
173
+ });
174
+
175
+ const animationDelay = computed(() => {
176
+ const layerIdx = layerContext?.layerIndex.value ?? 0;
177
+ const sectorIdx = sectorContext?.sectorIndex.value ?? 0;
178
+ return (
179
+ rootStartDelay.value +
180
+ layerIdx * 120 +
181
+ sectorIdx * 60 +
182
+ resolvedIndex.value * 40 +
183
+ 200
184
+ );
185
+ });
186
+
187
+ const maxContentWidth = computed(() => {
188
+ if (props.maxWidth !== undefined) {
189
+ return typeof props.maxWidth === 'number'
190
+ ? `${props.maxWidth}px`
191
+ : props.maxWidth;
192
+ }
193
+
194
+ if (sectorContext) {
195
+ const partGeo = sectorContext.sectorGeo.value?.parts[resolvedIndex.value];
196
+ if (partGeo?.maxContentWidth) {
197
+ return `${partGeo.maxContentWidth}px`;
198
+ }
199
+ } else {
200
+ const standalonePartGeo =
201
+ layerContext?.layerGeo.value?.sectors[resolvedIndex.value]?.parts[0];
202
+ if (standalonePartGeo?.maxContentWidth) {
203
+ return `${standalonePartGeo.maxContentWidth}px`;
204
+ }
205
+ }
206
+
207
+ const geo = layerContext?.layerGeo.value;
208
+ if (!geo) {
209
+ return '110px';
210
+ }
211
+
212
+ const partGeo = geo.parts[resolvedIndex.value];
213
+ if (partGeo?.maxContentWidth) {
214
+ return `${partGeo.maxContentWidth}px`;
215
+ }
216
+
217
+ const span =
218
+ partGeo?.startAngle !== undefined && partGeo?.endAngle !== undefined
219
+ ? Math.abs(partGeo.startAngle - partGeo.endAngle)
220
+ : 35;
221
+ const arcLength = geo.midRadius * (span * (Math.PI / 180));
222
+ return `${Math.max(100, Math.min(180, Math.round(arcLength * 0.92)))}px`;
223
+ });
224
+
225
+ const isSplitSector = computed(() => {
226
+ if (
227
+ props.position === 'top' ||
228
+ props.position === 'bottom' ||
229
+ props.position === 'middle'
230
+ ) {
231
+ return true;
232
+ }
233
+
234
+ if (sectorContext?.sectorGeo.value?.split) {
235
+ return true;
236
+ }
237
+
238
+ if ((sectorContext?.sectorGeo.value?.parts.length ?? 0) > 1) {
239
+ return true;
240
+ }
241
+
242
+ return false;
243
+ });
244
+
245
+ const resolvedAngle = computed<number>(() => {
246
+ if (props.angle !== undefined) {
247
+ return props.angle;
248
+ }
249
+
250
+ if (sectorContext) {
251
+ const partGeo = sectorContext.sectorGeo.value?.parts[resolvedIndex.value];
252
+ if (partGeo?.angle !== undefined) {
253
+ return partGeo.angle;
254
+ }
255
+
256
+ if (sectorContext.sectorGeo.value?.midAngle !== undefined) {
257
+ return sectorContext.sectorGeo.value.midAngle;
258
+ }
259
+ }
260
+
261
+ const geo = layerContext?.layerGeo.value;
262
+ const partGeo = geo?.parts[resolvedIndex.value];
263
+ if (partGeo?.angle !== undefined) {
264
+ return partGeo.angle;
265
+ }
266
+
267
+ return 90;
268
+ });
269
+
270
+ const effectiveRotate = computed(() => {
271
+ return props.rotate ?? sectorContext?.rotate?.value;
272
+ });
273
+
274
+ const effectiveSkew = computed(() => {
275
+ return props.skew ?? sectorContext?.skew?.value;
276
+ });
277
+
278
+ const resolvedRotation = computed<string | undefined>(() => {
279
+ const rot = effectiveRotate.value;
280
+ if (rot === undefined || rot === false) {
281
+ const sk = effectiveSkew.value;
282
+ if (sk === true || sk === 'tangent' || sk === 'auto') {
283
+ const tangent = Math.round(90 - resolvedAngle.value);
284
+ return `rotate(${tangent}deg)`;
285
+ }
286
+ return undefined;
287
+ }
288
+
289
+ if (typeof rot === 'number') {
290
+ return `rotate(${rot}deg)`;
291
+ }
292
+
293
+ if (rot === true || rot === 'tangent' || rot === 'auto') {
294
+ const tangent = Math.round(90 - resolvedAngle.value);
295
+ return `rotate(${tangent}deg)`;
296
+ }
297
+
298
+ if (typeof rot === 'string') {
299
+ return rot.includes('rotate')
300
+ ? rot
301
+ : rot.includes('deg')
302
+ ? `rotate(${rot})`
303
+ : `rotate(${rot}deg)`;
304
+ }
305
+
306
+ return undefined;
307
+ });
308
+
309
+ const resolvedSkew = computed<string | undefined>(() => {
310
+ const sk = effectiveSkew.value;
311
+ if (sk === undefined || sk === false) {
312
+ return undefined;
313
+ }
314
+
315
+ if (sk === true || sk === 'tangent' || sk === 'auto') {
316
+ return undefined;
317
+ }
318
+
319
+ if (typeof sk === 'number') {
320
+ return `skewX(${sk}deg)`;
321
+ }
322
+
323
+ if (typeof sk === 'string') {
324
+ return sk.includes('skew') || sk.includes('rotate')
325
+ ? sk
326
+ : sk.includes('deg')
327
+ ? `skewX(${sk})`
328
+ : `skewX(${sk}deg)`;
329
+ }
330
+
331
+ return undefined;
332
+ });
333
+
334
+ const partLabelTransform = computed<string | undefined>(() => {
335
+ const transforms: string[] = [];
336
+ if (resolvedRotation.value) {
337
+ transforms.push(resolvedRotation.value);
338
+ }
339
+
340
+ if (resolvedSkew.value) {
341
+ transforms.push(resolvedSkew.value);
342
+ }
343
+
344
+ return transforms.length > 0 ? transforms.join(' ') : undefined;
345
+ });
346
+
347
+ const isSelfActive = computed<boolean>(() => {
348
+ if (props.active !== undefined) {
349
+ return props.active;
350
+ }
351
+
352
+ if (rootContext?.isPartActive) {
353
+ return rootContext.isPartActive(
354
+ slottedLabel.value,
355
+ resolvedIndex.value,
356
+ props.active,
357
+ );
358
+ }
359
+
360
+ if (rootContext?.activePart?.value !== undefined) {
361
+ const ap = rootContext.activePart.value;
362
+ return ap === slottedLabel.value || ap === resolvedIndex.value;
363
+ }
364
+
365
+ return false;
366
+ });
367
+
368
+ const hasAnyActivePart = computed<boolean>(() => {
369
+ return rootContext?.hasAnyActivePart?.value ?? false;
370
+ });
371
+
372
+ function handlePartAreaClick(event: MouseEvent): void {
373
+ if (rootContext?.interactive?.value && rootContext.setActivePart) {
374
+ event.stopPropagation();
375
+ if (isSelfActive.value) {
376
+ rootContext.setActivePart(undefined);
377
+ } else {
378
+ rootContext.setActivePart(slottedLabel.value);
379
+ }
380
+ }
381
+ }
382
+
383
+ const { className, forwardedAttrs } = useMergedUnoAttrs(() => {
384
+ const colorClass = isSelfActive.value
385
+ ? 'text-(--alpha-arc-defense-in-depth-part-active)'
386
+ : 'text-(--alpha-arc-defense-in-depth-part)';
387
+ const opacityClass =
388
+ hasAnyActivePart.value && !isSelfActive.value
389
+ ? 'opacity-30'
390
+ : 'opacity-100';
391
+ const interactionClass = rootContext?.interactive?.value
392
+ ? 'cursor-pointer pointer-events-auto'
393
+ : 'pointer-events-none';
394
+
395
+ return `alpha-arc-defense-in-depth__part alpha-arc-defense-in-depth__part-area absolute flex flex-col items-center justify-center select-none text-center transition-all duration-300 ease-out bg-transparent border-0 p-0 m-0 appearance-none ${colorClass} ${opacityClass} ${interactionClass}`;
396
+ });
397
+ </script>
398
+
399
+ <template>
400
+ <button
401
+ type="button"
402
+ v-bind="forwardedAttrs()"
403
+ :disabled="!rootContext?.interactive?.value"
404
+ :aria-label="`Select ${slottedLabel}`"
405
+ :class="[
406
+ className(),
407
+ { 'alpha-arc-defense-in-depth__part--animated': isAnimated },
408
+ { 'alpha-arc-defense-in-depth__part--active': isSelfActive },
409
+ ]"
410
+ :data-active="isSelfActive"
411
+ :style="{
412
+ left: `${calculatedPosition.x}px`,
413
+ top: `${calculatedPosition.y}px`,
414
+ transform: 'translate(-50%, -50%)',
415
+ zIndex: isSelfActive ? 30 : 10,
416
+ '--part-delay': `${animationDelay}ms`,
417
+ ...(props.color
418
+ ? { '--alpha-arc-defense-in-depth-part': props.color }
419
+ : {}),
420
+ }"
421
+ @click="handlePartAreaClick"
422
+ >
423
+ <!-- Optional Dot Indicator or Icon -->
424
+ <div
425
+ v-if="props.showDot || props.icon"
426
+ class="relative flex items-center justify-center cursor-default group mb-1"
427
+ >
428
+ <span
429
+ v-if="props.icon"
430
+ class="text-xs text-current"
431
+ :class="props.icon"
432
+ />
433
+ <div
434
+ v-else-if="props.showDot"
435
+ class="w-4 h-4 rounded-full transition-all duration-200 flex items-center justify-center"
436
+ :class="[
437
+ isSelfActive ? 'scale-125 ring-2 ring-(--alpha-arc-defense-in-depth-part-ring) shadow-[0_0_12px_var(--alpha-arc-defense-in-depth-part-glow)]' : 'group-hover:scale-125',
438
+ ]"
439
+ :style="{
440
+ background: isSelfActive
441
+ ? 'radial-gradient(circle at 35% 32%, var(--alpha-arc-defense-in-depth-part-dot-highlight) 25%, var(--alpha-arc-defense-in-depth-part-dot-active) 70%, var(--alpha-arc-defense-in-depth-part-dot-active-edge) 100%)'
442
+ : props.color
443
+ ? `radial-gradient(circle at 35% 32%, var(--alpha-arc-defense-in-depth-part-dot-highlight) 15%, ${effectiveDotColor} 65%, var(--alpha-arc-defense-in-depth-part-dot-edge) 100%)`
444
+ : 'radial-gradient(circle at 35% 32%, var(--alpha-arc-defense-in-depth-part-dot-highlight) 15%, var(--alpha-arc-defense-in-depth-part-dot-idle) 55%, var(--alpha-arc-defense-in-depth-part-dot-idle-edge) 100%)',
445
+ boxShadow: isSelfActive
446
+ ? 'var(--alpha-arc-defense-in-depth-part-active-shadow)'
447
+ : 'var(--alpha-arc-defense-in-depth-part-shadow)',
448
+ }"
449
+ />
450
+ </div>
451
+
452
+ <!-- Part Area Content -->
453
+ <div
454
+ class="alpha-arc-defense-in-depth__part-label-wrapper"
455
+ :style="{
456
+ transform: partLabelTransform,
457
+ }"
458
+ >
459
+ <div
460
+ class="alpha-arc-defense-in-depth__part-label alpha-arc-defense-in-depth__part-content text-center font-medium leading-tight text-current drop-shadow-sm whitespace-pre-line transition-all duration-200"
461
+ :class="[
462
+ isSplitSector ? 'text-[11px] md:text-xs' : 'text-xs md:text-sm',
463
+ isSelfActive ? 'font-bold scale-110' : 'hover:scale-105',
464
+ ]"
465
+ :style="{
466
+ maxWidth: maxContentWidth,
467
+ textShadow: isSelfActive
468
+ ? 'var(--alpha-arc-defense-in-depth-part-active-text-shadow)'
469
+ : undefined,
470
+ }"
471
+ >
472
+ <slot>{{ slottedLabel }}</slot>
473
+ </div>
474
+ </div>
475
+ </button>
476
+ </template>
477
+
478
+ <style scoped>
479
+ .alpha-arc-defense-in-depth__part-label {
480
+ word-break: normal;
481
+ overflow-wrap: normal;
482
+ hyphens: none;
483
+ white-space: pre-line;
484
+ }
485
+
486
+ .alpha-arc-defense-in-depth__part--animated {
487
+ animation: arc-defense-in-depth-part-pop 450ms cubic-bezier(0.16, 1, 0.3, 1)
488
+ var(--part-delay, 0ms) both;
489
+ }
490
+
491
+ @keyframes arc-defense-in-depth-part-pop {
492
+ 0% {
493
+ opacity: 0;
494
+ transform: translate(-50%, -50%) scale(0.6);
495
+ }
496
+ 100% {
497
+ opacity: 1;
498
+ transform: translate(-50%, -50%) scale(1);
499
+ }
500
+ }
501
+ </style>
@@ -0,0 +1,162 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ type ComputedRef,
4
+ computed,
5
+ inject,
6
+ onUnmounted,
7
+ provide,
8
+ ref,
9
+ watch,
10
+ } from 'vue';
11
+
12
+ import {
13
+ ARC_DID_LAYER_KEY,
14
+ ARC_DID_SECTOR_KEY,
15
+ type IArcDefenseInDepthRegisteredSectorData,
16
+ type IArcDefenseInDepthSectorContext,
17
+ } from '../../../utils/defense-in-depth/arc-defense-in-depth/context';
18
+ import type { IArcDefenseInDepthPartItem } from '../../../utils/defense-in-depth/arc-defense-in-depth/types';
19
+
20
+ import { useMergedUnoAttrs } from '../../../utils/useMergedUnoAttrs';
21
+
22
+ defineOptions({
23
+ inheritAttrs: false,
24
+ name: 'ArcDefenseInDepthLayerSector',
25
+ });
26
+
27
+ export interface IArcDefenseInDepthLayerSectorProps {
28
+ readonly split?: boolean;
29
+ readonly angle?: number;
30
+ readonly span?: number;
31
+ readonly color?: string;
32
+ readonly index?: number;
33
+ readonly rotate?: boolean | number | 'tangent' | 'auto';
34
+ readonly skew?: boolean | number | string;
35
+ }
36
+
37
+ const props = withDefaults(defineProps<IArcDefenseInDepthLayerSectorProps>(), {
38
+ split: true,
39
+ angle: undefined,
40
+ span: undefined,
41
+ color: undefined,
42
+ index: undefined,
43
+ rotate: undefined,
44
+ skew: undefined,
45
+ });
46
+
47
+ const layerContext = inject(ARC_DID_LAYER_KEY, undefined);
48
+
49
+ const registeredPartTokens = ref<symbol[]>([]);
50
+ const registeredPartData = ref<Map<symbol, IArcDefenseInDepthPartItem>>(
51
+ new Map(),
52
+ );
53
+
54
+ function registerPart(
55
+ token?: symbol,
56
+ partDataRef?: ComputedRef<IArcDefenseInDepthPartItem | undefined>,
57
+ ) {
58
+ const pToken = token ?? Symbol();
59
+ if (!registeredPartTokens.value.includes(pToken)) {
60
+ registeredPartTokens.value = [...registeredPartTokens.value, pToken];
61
+ }
62
+
63
+ let stopWatch: (() => void) | undefined;
64
+ if (partDataRef) {
65
+ stopWatch = watch(
66
+ partDataRef,
67
+ (val) => {
68
+ const nextMap = new Map(registeredPartData.value);
69
+ if (val) {
70
+ nextMap.set(pToken, val);
71
+ } else {
72
+ nextMap.delete(pToken);
73
+ }
74
+
75
+ registeredPartData.value = nextMap;
76
+ },
77
+ { immediate: true },
78
+ );
79
+ }
80
+
81
+ const index = computed(() => registeredPartTokens.value.indexOf(pToken));
82
+
83
+ return {
84
+ index,
85
+ unregister: () => {
86
+ stopWatch?.();
87
+ registeredPartTokens.value = registeredPartTokens.value.filter(
88
+ (t) => t !== pToken,
89
+ );
90
+ const nextMap = new Map(registeredPartData.value);
91
+ nextMap.delete(pToken);
92
+ registeredPartData.value = nextMap;
93
+ },
94
+ };
95
+ }
96
+
97
+ const registeredPartsList = computed<IArcDefenseInDepthPartItem[]>(() => {
98
+ return registeredPartTokens.value
99
+ .map((token) => registeredPartData.value.get(token))
100
+ .filter((item): item is IArcDefenseInDepthPartItem => item !== undefined);
101
+ });
102
+
103
+ const sectorToken = Symbol();
104
+ const sectorRegistrationData = computed<IArcDefenseInDepthRegisteredSectorData>(
105
+ () => ({
106
+ parts: registeredPartsList.value,
107
+ split: props.split,
108
+ angle: props.angle,
109
+ span: props.span,
110
+ color: props.color,
111
+ index: props.index !== undefined ? Number(props.index) : undefined,
112
+ rotate: props.rotate,
113
+ skew: props.skew,
114
+ }),
115
+ );
116
+
117
+ const registration = layerContext?.registerSector(
118
+ sectorToken,
119
+ sectorRegistrationData,
120
+ );
121
+
122
+ onUnmounted(() => {
123
+ registration?.unregister();
124
+ });
125
+
126
+ const resolvedIndex = computed<number>(() => {
127
+ if (props.index !== undefined) {
128
+ return Number(props.index);
129
+ }
130
+
131
+ return registration?.index.value ?? 0;
132
+ });
133
+
134
+ const sectorGeo = computed(() => {
135
+ return layerContext?.layerGeo.value?.sectors[resolvedIndex.value];
136
+ });
137
+
138
+ const sectorContext: IArcDefenseInDepthSectorContext = {
139
+ sectorIndex: resolvedIndex,
140
+ sectorGeo,
141
+ rotate: computed(() => props.rotate),
142
+ skew: computed(() => props.skew),
143
+ registerPart,
144
+ };
145
+
146
+ provide(ARC_DID_SECTOR_KEY, sectorContext);
147
+
148
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
149
+ 'alpha-arc-defense-in-depth__layer-sector contents pointer-events-none',
150
+ );
151
+ </script>
152
+
153
+ <template>
154
+ <div
155
+ v-bind="forwardedAttrs()"
156
+ :class="className()"
157
+ :data-sector-index="resolvedIndex"
158
+ :data-split="props.split"
159
+ >
160
+ <slot />
161
+ </div>
162
+ </template>
@@ -0,0 +1,38 @@
1
+ /* Color defaults shared by this component family. */
2
+ @layer alpha-theme-tokens {
3
+ :root {
4
+ --alpha-arc-defense-in-depth-active-glow: drop-shadow(
5
+ 0 0 14px rgba(255, 255, 255, 0.85)
6
+ )
7
+ drop-shadow(0 0 6px rgba(56, 189, 248, 0.8)) brightness(1.2);
8
+ --alpha-arc-defense-in-depth-active-stroke: #ffffff;
9
+ --alpha-arc-defense-in-depth-center-fill: #ffffff;
10
+ --alpha-arc-defense-in-depth-layer-1-color: #38bdf8;
11
+ --alpha-arc-defense-in-depth-layer-2-color: #0ea5e9;
12
+ --alpha-arc-defense-in-depth-layer-3-color: #0284c7;
13
+ --alpha-arc-defense-in-depth-layer-accent: #0ea5e9;
14
+ --alpha-arc-defense-in-depth-layer-glow: drop-shadow(
15
+ 0 0 12px rgba(14, 165, 233, 0.45)
16
+ );
17
+ --alpha-arc-defense-in-depth-layer-heading: #ffffff;
18
+ --alpha-arc-defense-in-depth-part: #ffffff;
19
+ --alpha-arc-defense-in-depth-part-active: #ffffff;
20
+ --alpha-arc-defense-in-depth-part-active-shadow:
21
+ 0 0 12px rgba(56, 189, 248, 0.9), inset 0 1px 1px rgba(255, 255, 255, 0.9);
22
+ --alpha-arc-defense-in-depth-part-active-text-shadow:
23
+ 0 0 12px rgba(255, 255, 255, 0.95), 0 2px 6px rgba(0, 0, 0, 0.9);
24
+ --alpha-arc-defense-in-depth-part-dot: #0284c7;
25
+ --alpha-arc-defense-in-depth-part-dot-active: #38bdf8;
26
+ --alpha-arc-defense-in-depth-part-dot-active-edge: #0369a1;
27
+ --alpha-arc-defense-in-depth-part-dot-edge: #0f172a;
28
+ --alpha-arc-defense-in-depth-part-dot-glow: rgba(56, 189, 248, 0.35);
29
+ --alpha-arc-defense-in-depth-part-dot-highlight: #ffffff;
30
+ --alpha-arc-defense-in-depth-part-dot-idle: #cbd5e1;
31
+ --alpha-arc-defense-in-depth-part-dot-idle-edge: #94a3b8;
32
+ --alpha-arc-defense-in-depth-part-glow: #38bdf8;
33
+ --alpha-arc-defense-in-depth-part-ring: #ffffff;
34
+ --alpha-arc-defense-in-depth-part-shadow:
35
+ 0 2px 5px rgba(0, 0, 0, 0.28), inset 0 1px 1px rgba(255, 255, 255, 0.8);
36
+ --alpha-arc-defense-in-depth-stroke: #ffffff;
37
+ }
38
+ }