@alphacifer/slidev-addon-theme 0.0.6 → 0.0.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 (105) hide show
  1. package/README.md +117 -51
  2. package/components/{chevron-card → card/chevron-card}/ChevronCard.vue +2 -2
  3. package/components/{chevron-card → card/chevron-card}/ChevronCardBadge.vue +1 -1
  4. package/components/{chevron-card → card/chevron-card}/ChevronCardContent.vue +1 -1
  5. package/components/{chevron-card → card/chevron-card}/ChevronCardHeading.vue +1 -1
  6. package/components/{horiz-card → card/horiz-card}/HorizCard.vue +2 -2
  7. package/components/{horiz-card → card/horiz-card}/HorizCardBadge.vue +2 -2
  8. package/components/{horiz-card → card/horiz-card}/HorizCardContent.vue +2 -2
  9. package/components/{horiz-card → card/horiz-card}/HorizCardHeading.vue +2 -2
  10. package/components/{horiz-card → card/horiz-card}/HorizCardIcon.vue +2 -2
  11. package/components/{vert-card → card/vert-card}/VertCard.vue +2 -2
  12. package/components/{vert-card → card/vert-card}/VertCardBadge.vue +5 -2
  13. package/components/{vert-card → card/vert-card}/VertCardContent.vue +2 -2
  14. package/components/{vert-card → card/vert-card}/VertCardHeading.vue +2 -2
  15. package/components/{vert-card → card/vert-card}/VertCardIcon.vue +2 -2
  16. package/components/{vert-card → card/vert-card}/VertCardTitle.vue +2 -2
  17. package/components/comparisons/arc-comparison/ArcComparison.vue +654 -0
  18. package/components/comparisons/arc-comparison/ArcComparisonBadge.vue +29 -0
  19. package/components/comparisons/arc-comparison/ArcComparisonContent.vue +29 -0
  20. package/components/comparisons/arc-comparison/ArcComparisonContents.vue +17 -0
  21. package/components/comparisons/arc-comparison/ArcComparisonHeading.vue +29 -0
  22. package/components/comparisons/arc-comparison/ArcComparisonLeft.vue +268 -0
  23. package/components/comparisons/arc-comparison/ArcComparisonOrbit.vue +47 -0
  24. package/components/comparisons/arc-comparison/ArcComparisonRight.vue +271 -0
  25. package/components/comparisons/arc-comparison/ArcComparisonTitle.vue +29 -0
  26. package/components/comparisons/table-comparison/TableComparison.vue +254 -0
  27. package/components/comparisons/table-comparison/TableComparisonCell.vue +88 -0
  28. package/components/comparisons/table-comparison/TableComparisonCol.vue +97 -0
  29. package/components/comparisons/table-comparison/TableComparisonCols.vue +74 -0
  30. package/components/comparisons/table-comparison/TableComparisonRow.vue +92 -0
  31. package/components/comparisons/table-comparison/TableComparisonRows.vue +21 -0
  32. package/components/core/ReflectedTitle.vue +2 -1
  33. package/components/core/arc-orbit/ArcOrbit.vue +468 -0
  34. package/components/{arc-compare/ArcCompareBadge.vue → core/arc-orbit/ArcOrbitBadge.vue} +11 -8
  35. package/components/core/arc-orbit/ArcOrbitCallout.vue +400 -0
  36. package/components/{arc-compare/ArcCompareContent.vue → core/arc-orbit/ArcOrbitContent.vue} +8 -8
  37. package/components/{arc-compare/ArcCompareContents.vue → core/arc-orbit/ArcOrbitContents.vue} +3 -3
  38. package/components/{arc-compare/ArcCompareHeading.vue → core/arc-orbit/ArcOrbitHeading.vue} +11 -8
  39. package/components/core/arc-orbit/ArcOrbitTitle.vue +50 -0
  40. package/components/{thanks → core/thanks}/ThanksOutlineSquare.vue +1 -1
  41. package/components/{thanks → core/thanks}/ThanksSquare.vue +1 -1
  42. package/components/{quad-hub/QuadHub.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetrad.vue} +71 -69
  43. package/components/{quad-hub/QuadHubCallout.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCallout.vue} +45 -43
  44. package/components/{quad-hub/QuadHubCenter.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradCenter.vue} +4 -4
  45. package/components/{quad-hub/QuadHubContent.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradContent.vue} +6 -6
  46. package/components/{quad-hub/QuadHubHeading.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradHeading.vue} +6 -6
  47. package/components/{quad-hub/QuadHubIcon.vue → facets/tetrad/rect-orbit-tetrad/RectOrbitTetradIcon.vue} +6 -6
  48. package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriad.vue +3 -3
  49. package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadCallout.vue +1 -1
  50. package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadContent.vue +1 -1
  51. package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadHeading.vue +1 -1
  52. package/components/facets/triad/gear-triad/GearTriad.vue +591 -0
  53. package/components/facets/triad/gear-triad/GearTriadCallout.vue +285 -0
  54. package/components/facets/triad/gear-triad/GearTriadCenter.vue +41 -0
  55. package/components/facets/triad/gear-triad/GearTriadContent.vue +58 -0
  56. package/components/facets/triad/gear-triad/GearTriadContents.vue +111 -0
  57. package/components/facets/triad/gear-triad/GearTriadDescription.vue +38 -0
  58. package/components/facets/triad/gear-triad/GearTriadHeading.vue +38 -0
  59. package/components/facets/triad/gear-triad/GearTriadIcon.vue +157 -0
  60. package/components/{hex-triad → facets/triad/hex-triad}/HexTriad.vue +2 -2
  61. package/components/{hex-triad → facets/triad/hex-triad}/HexTriadBadge.vue +1 -1
  62. package/components/{hex-triad → facets/triad/hex-triad}/HexTriadCallout.vue +1 -1
  63. package/components/{hex-triad → facets/triad/hex-triad}/HexTriadHeading.vue +1 -1
  64. package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcess.vue +2 -2
  65. package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessArrow.vue +1 -1
  66. package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessCallout.vue +1 -1
  67. package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessContent.vue +1 -1
  68. package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessHeading.vue +1 -1
  69. package/package.json +1 -1
  70. package/utils/arcComparison/context.ts +40 -0
  71. package/utils/arcComparison/createArcComparisonGeometry.ts +175 -0
  72. package/utils/arcComparison/index.ts +3 -0
  73. package/utils/{arcCompare/resolveArcCompareItems.ts → arcComparison/resolveArcComparisonItems.ts} +24 -45
  74. package/utils/arcOrbit/context.ts +38 -0
  75. package/utils/{arcCompare/createArcCompareGeometry.ts → arcOrbit/createArcOrbitGeometry.ts} +77 -108
  76. package/utils/arcOrbit/index.ts +3 -0
  77. package/utils/arcOrbit/resolveArcOrbitItems.ts +92 -0
  78. package/utils/gearTriad/context.ts +51 -0
  79. package/utils/gearTriad/createGearTriadGeometry.ts +210 -0
  80. package/utils/gearTriad/index.ts +3 -0
  81. package/utils/gearTriad/resolveGearTriadItems.ts +159 -0
  82. package/utils/rectOrbitTetrad/context.ts +31 -0
  83. package/utils/{quadHub/createQuadHubGeometry.ts → rectOrbitTetrad/createRectOrbitTetradGeometry.ts} +33 -28
  84. package/utils/rectOrbitTetrad/index.ts +3 -0
  85. package/utils/{quadHub/resolveQuadHubItems.ts → rectOrbitTetrad/resolveRectOrbitTetradItems.ts} +25 -25
  86. package/utils/tableComparison/constants.ts +72 -0
  87. package/utils/tableComparison/context.ts +24 -0
  88. package/utils/tableComparison/index.ts +2 -0
  89. package/utils/useDiagramAutoScale.ts +1 -1
  90. package/components/arc-compare/ArcCompare.vue +0 -443
  91. package/components/arc-compare/ArcCompareCallout.vue +0 -386
  92. package/components/arc-compare/ArcCompareLeft.vue +0 -183
  93. package/components/arc-compare/ArcCompareRight.vue +0 -183
  94. package/components/arc-compare/ArcCompareTitle.vue +0 -47
  95. package/utils/arcCompare/context.ts +0 -36
  96. package/utils/arcCompare/index.ts +0 -3
  97. package/utils/quadHub/context.ts +0 -26
  98. package/utils/quadHub/index.ts +0 -3
  99. /package/components/{shifting-heading → core}/TransitionHeading.vue +0 -0
  100. /package/components/{thanks → core/thanks}/ThanksContent.vue +0 -0
  101. /package/components/{arrow-triad → facets/triad/arrow-triad}/ArrowTriadIcon.vue +0 -0
  102. /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadCenterBadge.vue +0 -0
  103. /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadContent.vue +0 -0
  104. /package/components/{hex-triad → facets/triad/hex-triad}/HexTriadLayer.vue +0 -0
  105. /package/components/{arc-arrow-process → process/arc-arrow-process}/ArcArrowProcessIcon.vue +0 -0
@@ -1,386 +0,0 @@
1
- <script setup lang="ts">
2
- import { computed, Fragment, inject, provide, useSlots, type VNode } from 'vue';
3
-
4
- import {
5
- ARC_COMPARE_CALLOUT_KEY,
6
- ARC_COMPARE_ROOT_KEY,
7
- ARC_COMPARE_SIDE_KEY,
8
- DEFAULT_LEFT_ITEMS,
9
- DEFAULT_RIGHT_ITEMS,
10
- type IArcCompareItem,
11
- type IResolvedArcCompareItem,
12
- } from '../../utils/arcCompare';
13
- import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
14
- import ArcCompareBadge from './ArcCompareBadge.vue';
15
- import ArcCompareContent from './ArcCompareContent.vue';
16
- import ArcCompareHeading from './ArcCompareHeading.vue';
17
-
18
- defineOptions({
19
- inheritAttrs: false,
20
- name: 'ArcCompareCallout',
21
- });
22
-
23
- export interface IArcCompareCalloutProps {
24
- readonly side?: 'left' | 'right';
25
- readonly index?: number;
26
- readonly id?: string | number;
27
- readonly title?: string;
28
- readonly description?: string;
29
- readonly color?: string;
30
- readonly textColor?: string;
31
- readonly textGap?: number;
32
- }
33
-
34
- const props = withDefaults(defineProps<IArcCompareCalloutProps>(), {
35
- side: undefined,
36
- index: undefined,
37
- id: undefined,
38
- title: undefined,
39
- description: undefined,
40
- color: undefined,
41
- textColor: undefined,
42
- textGap: undefined,
43
- });
44
-
45
- interface INamedComponent {
46
- readonly name?: string;
47
- readonly __name?: string;
48
- }
49
-
50
- function hasComponentName(type: unknown, name: string): boolean {
51
- if (typeof type === 'object' && type !== null) {
52
- const comp = type as INamedComponent;
53
-
54
- return comp.name === name || comp.__name === name;
55
- }
56
-
57
- if (typeof type === 'function') {
58
- return (type as { name?: string }).name === name;
59
- }
60
-
61
- return false;
62
- }
63
-
64
- const rootContext = inject(ARC_COMPARE_ROOT_KEY, undefined);
65
- const sideContext = inject(ARC_COMPARE_SIDE_KEY, undefined);
66
-
67
- const resolvedSide = computed<'left' | 'right'>(() => {
68
- return props.side ?? sideContext?.side ?? 'left';
69
- });
70
-
71
- const autoIndex = sideContext?.registerCallout();
72
-
73
- const resolvedIndex = computed<number>(() => {
74
- return props.index ?? autoIndex ?? 0;
75
- });
76
-
77
- const activeItem = computed<IResolvedArcCompareItem>(() => {
78
- const isRight = resolvedSide.value === 'right';
79
- const defaultList = isRight ? DEFAULT_RIGHT_ITEMS : DEFAULT_LEFT_ITEMS;
80
- const fallback =
81
- defaultList[resolvedIndex.value] ??
82
- defaultList[defaultList.length - 1] ??
83
- defaultList[0];
84
-
85
- const override: IArcCompareItem = {
86
- id: props.id,
87
- title: props.title,
88
- description: props.description,
89
- color: props.color ?? sideContext?.color.value,
90
- textColor: props.textColor,
91
- };
92
-
93
- return {
94
- id: override.id ?? fallback.id,
95
- title: override.title ?? fallback.title,
96
- description: override.description ?? fallback.description,
97
- color: override.color ?? fallback.color,
98
- textColor: override.textColor ?? fallback.textColor,
99
- };
100
- });
101
-
102
- const sideColor = computed(() => {
103
- return props.color ?? sideContext?.color.value ?? activeItem.value.color;
104
- });
105
-
106
- provide(ARC_COMPARE_CALLOUT_KEY, {
107
- item: activeItem,
108
- side: resolvedSide.value,
109
- index: resolvedIndex.value,
110
- color: sideColor,
111
- });
112
-
113
- const slots = useSlots();
114
-
115
- function isSignificantNode(node: VNode): boolean {
116
- if (typeof node.type === 'symbol') {
117
- if (typeof node.children === 'string' && !node.children.trim()) {
118
- return false;
119
- }
120
- }
121
-
122
- if (typeof node.children === 'string' && !node.children.trim()) {
123
- return false;
124
- }
125
-
126
- return true;
127
- }
128
-
129
- function flattenVNodes(nodes: VNode[]): VNode[] {
130
- const result: VNode[] = [];
131
-
132
- for (const node of nodes) {
133
- if (node.type === Fragment && Array.isArray(node.children)) {
134
- result.push(...flattenVNodes(node.children as VNode[]));
135
- } else if (isSignificantNode(node)) {
136
- result.push(node);
137
- }
138
- }
139
-
140
- return result;
141
- }
142
-
143
- function isBadgeNode(node: VNode): boolean {
144
- return (
145
- hasComponentName(node.type, 'ArcCompareBadge') ||
146
- node.type === ArcCompareBadge
147
- );
148
- }
149
-
150
- function isHeadingNode(node: VNode): boolean {
151
- return (
152
- hasComponentName(node.type, 'ArcCompareHeading') ||
153
- node.type === ArcCompareHeading
154
- );
155
- }
156
-
157
- function isContentNode(node: VNode): boolean {
158
- return (
159
- hasComponentName(node.type, 'ArcCompareContent') ||
160
- node.type === ArcCompareContent
161
- );
162
- }
163
-
164
- const defaultNodes = computed(() => {
165
- if (!slots.default) {
166
- return [];
167
- }
168
-
169
- return flattenVNodes(slots.default());
170
- });
171
-
172
- const badgeNode = computed(() => {
173
- return defaultNodes.value.find(isBadgeNode);
174
- });
175
-
176
- const headingNode = computed(() => {
177
- return defaultNodes.value.find(isHeadingNode);
178
- });
179
-
180
- const contentNode = computed(() => {
181
- return defaultNodes.value.find(isContentNode);
182
- });
183
-
184
- const otherNodes = computed(() => {
185
- return defaultNodes.value.filter((node) => {
186
- return !isBadgeNode(node) && !isHeadingNode(node) && !isContentNode(node);
187
- });
188
- });
189
-
190
- const animation = computed(() => {
191
- return rootContext?.animation?.value ?? true;
192
- });
193
-
194
- const isRight = computed(() => {
195
- return resolvedSide.value === 'right';
196
- });
197
-
198
- // Dynamic coordinate positioning aligned with parametric SVG geometry
199
- const positionStyle = computed(() => {
200
- const right = isRight.value;
201
- const sideGeo = right
202
- ? rootContext?.geo.value.right
203
- : rootContext?.geo.value.left;
204
-
205
- const calloutGeo = sideGeo?.callouts[resolvedIndex.value];
206
-
207
- if (calloutGeo) {
208
- if (right) {
209
- return {
210
- position: 'absolute' as const,
211
- right: `${calloutGeo.badgeOffset}px`,
212
- top: `${calloutGeo.top}px`,
213
- width: `${calloutGeo.width}px`,
214
- zIndex: 10,
215
- };
216
- }
217
-
218
- return {
219
- position: 'absolute' as const,
220
- left: `${calloutGeo.badgeOffset}px`,
221
- top: `${calloutGeo.top}px`,
222
- width: `${calloutGeo.width}px`,
223
- zIndex: 10,
224
- };
225
- }
226
-
227
- const idx = Math.min(Math.max(resolvedIndex.value, 0), 2);
228
- const offset = idx === 1 ? 184 : 134;
229
- const topY = idx === 0 ? 66 : idx === 1 ? 214 : 362;
230
- const w = idx === 1 ? 260 : 310;
231
-
232
- if (right) {
233
- return {
234
- position: 'absolute' as const,
235
- right: `${offset}px`,
236
- top: `${topY}px`,
237
- width: `${w}px`,
238
- zIndex: 10,
239
- };
240
- }
241
-
242
- return {
243
- position: 'absolute' as const,
244
- left: `${offset}px`,
245
- top: `${topY}px`,
246
- width: `${w}px`,
247
- zIndex: 10,
248
- };
249
- });
250
-
251
- const textStyle = computed(() => {
252
- const sideGeo = isRight.value
253
- ? rootContext?.geo.value.right
254
- : rootContext?.geo.value.left;
255
- const calloutGeo = sideGeo?.callouts[resolvedIndex.value];
256
- const gap = props.textGap ?? calloutGeo?.textGap ?? 28;
257
- const width = calloutGeo?.textWidth ?? 215;
258
-
259
- if (isRight.value) {
260
- return {
261
- marginRight: `${gap}px`,
262
- width: `${width}px`,
263
- };
264
- }
265
-
266
- return {
267
- marginLeft: `${gap}px`,
268
- width: `${width}px`,
269
- };
270
- });
271
-
272
- const { className, forwardedAttrs } = useMergedUnoAttrs(
273
- 'alpha-arc-compare-callout absolute flex items-start select-none z-10 transition-all duration-300 pointer-events-auto',
274
- );
275
- </script>
276
-
277
- <template>
278
- <div
279
- v-bind="forwardedAttrs()"
280
- :class="[
281
- className(),
282
- isRight ? 'justify-end text-right' : 'justify-start text-left',
283
- `alpha-arc-compare-callout--${resolvedSide}-${resolvedIndex}`,
284
- { 'alpha-arc-compare-callout--animated': animation },
285
- ]"
286
- :style="positionStyle"
287
- >
288
- <!-- Left side: [Badge] [Heading + Content] -->
289
- <template v-if="!isRight">
290
- <component :is="badgeNode" v-if="badgeNode" />
291
- <ArcCompareBadge v-else />
292
- <div
293
- class="flex flex-col items-start text-left min-w-0 pt-0.5"
294
- :style="textStyle"
295
- >
296
- <component :is="headingNode" v-if="headingNode" />
297
- <ArcCompareHeading v-else />
298
- <component :is="contentNode" v-if="contentNode" />
299
- <ArcCompareContent v-else />
300
- <component :is="node" v-for="(node, i) in otherNodes" :key="i" />
301
- </div>
302
- </template>
303
- <!-- Right side: [Heading + Content] [Badge] -->
304
- <template v-else>
305
- <div
306
- class="flex flex-col items-end text-right min-w-0 pt-0.5"
307
- :style="textStyle"
308
- >
309
- <component :is="headingNode" v-if="headingNode" />
310
- <ArcCompareHeading v-else />
311
- <component :is="contentNode" v-if="contentNode" />
312
- <ArcCompareContent v-else />
313
- <component :is="node" v-for="(node, i) in otherNodes" :key="i" />
314
- </div>
315
- <component :is="badgeNode" v-if="badgeNode" />
316
- <ArcCompareBadge v-else />
317
- </template>
318
- </div>
319
- </template>
320
-
321
- <style scoped>
322
- .alpha-arc-compare-callout :deep(p),
323
- .alpha-arc-compare-callout :deep(h1),
324
- .alpha-arc-compare-callout :deep(h2),
325
- .alpha-arc-compare-callout :deep(h3),
326
- .alpha-arc-compare-callout :deep(h4),
327
- .alpha-arc-compare-callout :deep(h5),
328
- .alpha-arc-compare-callout :deep(h6) {
329
- margin: 0;
330
- padding: 0;
331
- }
332
-
333
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--left-0 {
334
- animation: arc-callout-fade-left 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 120ms) both;
335
- }
336
-
337
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--left-1 {
338
- animation: arc-callout-fade-left 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 200ms) both;
339
- }
340
-
341
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--left-2 {
342
- animation: arc-callout-fade-left 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 280ms) both;
343
- }
344
-
345
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--left-3 {
346
- animation: arc-callout-fade-left 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 360ms) both;
347
- }
348
-
349
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--right-0 {
350
- animation: arc-callout-fade-right 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 120ms) both;
351
- }
352
-
353
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--right-1 {
354
- animation: arc-callout-fade-right 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 200ms) both;
355
- }
356
-
357
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--right-2 {
358
- animation: arc-callout-fade-right 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 280ms) both;
359
- }
360
-
361
- .alpha-arc-compare-callout--animated.alpha-arc-compare-callout--right-3 {
362
- animation: arc-callout-fade-right 450ms cubic-bezier(0.16, 1, 0.3, 1) calc(var(--arc-compare-start-delay, 0ms) + 360ms) both;
363
- }
364
-
365
- @keyframes arc-callout-fade-left {
366
- 0% {
367
- opacity: 0;
368
- transform: translateX(-14px);
369
- }
370
- 100% {
371
- opacity: 1;
372
- transform: translateX(0);
373
- }
374
- }
375
-
376
- @keyframes arc-callout-fade-right {
377
- 0% {
378
- opacity: 0;
379
- transform: translateX(14px);
380
- }
381
- 100% {
382
- opacity: 1;
383
- transform: translateX(0);
384
- }
385
- }
386
- </style>
@@ -1,183 +0,0 @@
1
- <script setup lang="ts">
2
- import {
3
- computed,
4
- Fragment,
5
- inject,
6
- onBeforeUpdate,
7
- provide,
8
- ref,
9
- useSlots,
10
- type VNode,
11
- } from 'vue';
12
-
13
- import {
14
- ARC_COMPARE_ROOT_KEY,
15
- ARC_COMPARE_SIDE_KEY,
16
- DEFAULT_LEFT_COLOR,
17
- } from '../../utils/arcCompare';
18
- import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
19
- import ArcCompareCallout from './ArcCompareCallout.vue';
20
- import ArcCompareContents from './ArcCompareContents.vue';
21
- import ArcCompareTitle from './ArcCompareTitle.vue';
22
-
23
- defineOptions({
24
- inheritAttrs: false,
25
- name: 'ArcCompareLeft',
26
- });
27
-
28
- export interface IArcCompareLeftProps {
29
- readonly color?: string;
30
- readonly title?: string;
31
- readonly count?: number;
32
- }
33
-
34
- const props = withDefaults(defineProps<IArcCompareLeftProps>(), {
35
- color: DEFAULT_LEFT_COLOR,
36
- title: undefined,
37
- count: undefined,
38
- });
39
-
40
- const rootContext = inject(ARC_COMPARE_ROOT_KEY, undefined);
41
-
42
- const slots = useSlots();
43
-
44
- interface INamedComponent {
45
- readonly name?: string;
46
- readonly __name?: string;
47
- }
48
-
49
- function hasComponentName(type: unknown, name: string): boolean {
50
- if (typeof type === 'object' && type !== null) {
51
- const comp = type as INamedComponent;
52
-
53
- return comp.name === name || comp.__name === name;
54
- }
55
-
56
- if (typeof type === 'function') {
57
- return (type as { name?: string }).name === name;
58
- }
59
-
60
- return false;
61
- }
62
-
63
- let calloutCounter = 0;
64
- onBeforeUpdate(() => {
65
- calloutCounter = 0;
66
- });
67
-
68
- const sideColor = computed(() => {
69
- return props.color ?? DEFAULT_LEFT_COLOR;
70
- });
71
-
72
- const resolvedCount = computed(() => {
73
- return props.count ?? rootContext?.pointsCount.value ?? 3;
74
- });
75
-
76
- const currentTitle = ref<string>(props.title ?? 'Add Project\nName');
77
-
78
- provide(ARC_COMPARE_SIDE_KEY, {
79
- side: 'left',
80
- color: sideColor,
81
- title: computed(() => currentTitle.value),
82
- setTitle: (val: string) => {
83
- currentTitle.value = val;
84
- },
85
- registerCallout: () => {
86
- return calloutCounter++;
87
- },
88
- count: resolvedCount,
89
- });
90
-
91
- function isSignificantNode(node: VNode): boolean {
92
- if (typeof node.type === 'symbol') {
93
- if (typeof node.children === 'string' && !node.children.trim()) {
94
- return false;
95
- }
96
- }
97
-
98
- if (typeof node.children === 'string' && !node.children.trim()) {
99
- return false;
100
- }
101
-
102
- return true;
103
- }
104
-
105
- function flattenVNodes(nodes: VNode[]): VNode[] {
106
- const result: VNode[] = [];
107
-
108
- for (const node of nodes) {
109
- if (node.type === Fragment && Array.isArray(node.children)) {
110
- result.push(...flattenVNodes(node.children as VNode[]));
111
- } else if (isSignificantNode(node)) {
112
- result.push(node);
113
- }
114
- }
115
-
116
- return result;
117
- }
118
-
119
- function isTitleNode(node: VNode): boolean {
120
- return (
121
- hasComponentName(node.type, 'ArcCompareTitle') ||
122
- node.type === ArcCompareTitle
123
- );
124
- }
125
-
126
- const defaultNodes = computed(() => {
127
- if (!slots.default) {
128
- return [];
129
- }
130
-
131
- return flattenVNodes(slots.default());
132
- });
133
-
134
- const titleNode = computed(() => {
135
- return defaultNodes.value.find(isTitleNode);
136
- });
137
-
138
- const bodyNodes = computed(() => {
139
- return defaultNodes.value.filter((node) => !isTitleNode(node));
140
- });
141
-
142
- const hubStyle = computed(() => {
143
- const hubR = rootContext?.geo.value.left.hubRadius ?? 170;
144
- const centerY = rootContext?.geo.value.centerY ?? 240;
145
-
146
- return {
147
- top: `${centerY - hubR}px`,
148
- width: `${hubR}px`,
149
- height: `${hubR * 2}px`,
150
- };
151
- });
152
-
153
- const { className, forwardedAttrs } = useMergedUnoAttrs(
154
- 'alpha-arc-compare-left absolute inset-0 w-full h-full pointer-events-none',
155
- );
156
- </script>
157
-
158
- <template>
159
- <div v-bind="forwardedAttrs()" :class="className()">
160
- <!-- Left Hub Title Display -->
161
- <div
162
- class="alpha-arc-compare__hub-title alpha-arc-compare__hub-title--left absolute left-0 flex items-center justify-center z-10 pointer-events-auto"
163
- :style="hubStyle"
164
- >
165
- <component :is="titleNode" v-if="titleNode" />
166
- <ArcCompareTitle v-else-if="props.title">
167
- {{ props.title }}
168
- </ArcCompareTitle>
169
- <ArcCompareTitle v-else />
170
- </div>
171
- <!-- Contents & Callouts -->
172
- <template v-if="bodyNodes.length > 0">
173
- <component :is="node" v-for="(node, i) in bodyNodes" :key="i" />
174
- </template>
175
- <ArcCompareContents v-else>
176
- <ArcCompareCallout
177
- v-for="idx in resolvedCount"
178
- :key="idx"
179
- :index="idx - 1"
180
- />
181
- </ArcCompareContents>
182
- </div>
183
- </template>