Skip to content

Commit 47976d1

Browse files
committed
ChartPatternSlotProps
2 parents b363f85 + e4dff84 commit 47976d1

File tree

7 files changed

+164
-186
lines changed

7 files changed

+164
-186
lines changed

app/components/Compare/FacetQuadrantChart.vue

Lines changed: 84 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
<script setup lang="ts">
2-
import { VueUiQuadrant } from 'vue-data-ui/vue-ui-quadrant';
3-
import { NO_DEPENDENCY_ID } from '~/composables/usePackageComparison';
4-
import { getFrameworkColor, isListedFramework } from '~/utils/frameworks';
5-
import { createQuadrantDataset } from '~/utils/compare-quadrant-chart';
6-
import type {
7-
VueUiQuadrantConfig,
8-
VueUiQuadrantDatasetItem,
9-
} from 'vue-data-ui';
10-
import { sanitise, loadFile, applyEllipsis, copyAltTextForCompareQuadrantChart } from '~/utils/charts';
2+
import { VueUiQuadrant } from 'vue-data-ui/vue-ui-quadrant'
3+
import { NO_DEPENDENCY_ID } from '~/composables/usePackageComparison'
4+
import { getFrameworkColor, isListedFramework } from '~/utils/frameworks'
5+
import { createQuadrantDataset } from '~/utils/compare-quadrant-chart'
6+
import type { VueUiQuadrantConfig, VueUiQuadrantDatasetItem } from 'vue-data-ui'
7+
import {
8+
sanitise,
9+
loadFile,
10+
applyEllipsis,
11+
copyAltTextForCompareQuadrantChart,
12+
} from '~/utils/charts'
1113
import { drawNpmxLogoAndTaglineWatermark } from '~/composables/useChartWatermark'
1214
13-
import('vue-data-ui/style.css');
15+
import('vue-data-ui/style.css')
1416
1517
const props = defineProps<{
16-
packagesData: ReadonlyArray<PackageComparisonData | null>;
17-
packages: string[];
18-
}>();
18+
packagesData: ReadonlyArray<PackageComparisonData | null>
19+
packages: string[]
20+
}>()
1921
2022
console.log(props.packagesData)
2123
22-
const colorMode = useColorMode();
23-
const resolvedMode = shallowRef<'light' | 'dark'>('light');
24-
const rootEl = shallowRef<HTMLElement | null>(null);
25-
const { width } = useElementSize(rootEl);
26-
const { copy, copied } = useClipboard();
27-
const compactNumberFormatter = useCompactNumberFormatter();
28-
const bytesFormatter = useBytesFormatter();
24+
const colorMode = useColorMode()
25+
const resolvedMode = shallowRef<'light' | 'dark'>('light')
26+
const rootEl = shallowRef<HTMLElement | null>(null)
27+
const { width } = useElementSize(rootEl)
28+
const { copy, copied } = useClipboard()
29+
const compactNumberFormatter = useCompactNumberFormatter()
30+
const bytesFormatter = useBytesFormatter()
2931
30-
const mobileBreakpointWidth = 640;
31-
const isMobile = computed(
32-
() => width.value > 0 && width.value < mobileBreakpointWidth,
33-
);
32+
const mobileBreakpointWidth = 640
33+
const isMobile = computed(() => width.value > 0 && width.value < mobileBreakpointWidth)
3434
3535
const { colors } = useCssVariables(
3636
[
@@ -49,28 +49,28 @@ const { colors } = useCssVariables(
4949
watchHtmlAttributes: true,
5050
watchResize: false,
5151
},
52-
);
52+
)
5353
5454
const watermarkColors = computed(() => ({
5555
fg: colors.value.fg ?? OKLCH_NEUTRAL_FALLBACK,
5656
bg: colors.value.bg ?? OKLCH_NEUTRAL_FALLBACK,
5757
fgSubtle: colors.value.fgSubtle ?? OKLCH_NEUTRAL_FALLBACK,
58-
}));
58+
}))
5959
6060
onMounted(async () => {
61-
rootEl.value = document.documentElement;
62-
resolvedMode.value = colorMode.value === 'dark' ? 'dark' : 'light';
63-
});
61+
rootEl.value = document.documentElement
62+
resolvedMode.value = colorMode.value === 'dark' ? 'dark' : 'light'
63+
})
6464
6565
watch(
6666
() => colorMode.value,
67-
(value) => {
68-
resolvedMode.value = value === 'dark' ? 'dark' : 'light';
67+
value => {
68+
resolvedMode.value = value === 'dark' ? 'dark' : 'light'
6969
},
7070
{ flush: 'sync' },
71-
);
71+
)
7272
73-
const isDarkMode = computed(() => resolvedMode.value === 'dark');
73+
const isDarkMode = computed(() => resolvedMode.value === 'dark')
7474
7575
const source = computed<PackageQuadrantInput[]>(() => {
7676
if (!props.packagesData?.length) return []
@@ -88,7 +88,7 @@ const source = computed<PackageQuadrantInput[]>(() => {
8888
const hasTypes = typesKind === 'included' || typesKind === '@types'
8989
9090
return {
91-
license: packageItem.metadata?.license ?? "",
91+
license: packageItem.metadata?.license ?? '',
9292
id: packageItem.package.name,
9393
name: packageItem.package.name,
9494
downloads: Number(packageItem.downloads ?? 0),
@@ -106,27 +106,25 @@ const source = computed<PackageQuadrantInput[]>(() => {
106106
.filter((packageItem): packageItem is PackageQuadrantInput => packageItem !== null)
107107
})
108108
109-
const rawQuadrant = computed(() => createQuadrantDataset(source.value));
109+
const rawQuadrant = computed(() => createQuadrantDataset(source.value))
110110
const dataset = computed<VueUiQuadrantDatasetItem[]>(() => {
111111
return rawQuadrant.value.map((el: any) => {
112112
return {
113113
...el,
114114
fullname: el.name,
115115
name: applyEllipsis(el.name, 20),
116116
shape: 'circle',
117-
color: isListedFramework(el.name)
118-
? getFrameworkColor(el.name)
119-
: undefined,
117+
color: isListedFramework(el.name) ? getFrameworkColor(el.name) : undefined,
120118
series: [
121119
{
122120
name: applyEllipsis(el.name, 20),
123121
x: el.x,
124122
y: el.y,
125123
},
126124
],
127-
};
128-
});
129-
});
125+
}
126+
})
127+
})
130128
131129
function buildExportFilename(extension: string): string {
132130
const translatedPrefix = sanitise($t('compare.quadrant_chart.filename'))
@@ -156,17 +154,17 @@ const config = computed<VueUiQuadrantConfig>(() => {
156154
close: $t('package.trends.close_options'),
157155
},
158156
callbacks: {
159-
img: (args) => {
160-
const imageUri = args?.imageUri;
161-
if (!imageUri) return;
162-
loadFile(imageUri, buildExportFilename('png'));
157+
img: args => {
158+
const imageUri = args?.imageUri
159+
if (!imageUri) return
160+
loadFile(imageUri, buildExportFilename('png'))
163161
},
164-
svg: (args) => {
165-
const blob = args?.blob;
166-
if (!blob) return;
167-
const url = URL.createObjectURL(blob);
168-
loadFile(url, buildExportFilename('svg'));
169-
URL.revokeObjectURL(url);
162+
svg: args => {
163+
const blob = args?.blob
164+
if (!blob) return
165+
const url = URL.createObjectURL(blob)
166+
loadFile(url, buildExportFilename('svg'))
167+
URL.revokeObjectURL(url)
170168
},
171169
altCopy: ({ dataset: dst, config: cfg }) => {
172170
copyAltTextForCompareQuadrantChart({
@@ -193,7 +191,7 @@ const config = computed<VueUiQuadrantConfig>(() => {
193191
color: colors.value.border,
194192
steps: 5,
195193
roundingForce: 6,
196-
fill: isDarkMode.value
194+
fill: isDarkMode.value,
197195
},
198196
xAxis: {
199197
name: $t('compare.quadrant_chart.label_x_axis'),
@@ -214,7 +212,7 @@ const config = computed<VueUiQuadrantConfig>(() => {
214212
},
215213
plotLabels: {
216214
offsetY: 12,
217-
color: colors.value.fg
215+
color: colors.value.fg,
218216
},
219217
quadrantLabels: {
220218
tr: {
@@ -252,26 +250,26 @@ const config = computed<VueUiQuadrantConfig>(() => {
252250
backgroundColor: 'transparent',
253251
showShape: false,
254252
customFormat: ({ datapoint }) => {
255-
const isDeprecated = !!datapoint?.category?.metrics?.deprecated;
253+
const isDeprecated = !!datapoint?.category?.metrics?.deprecated
256254
return `
257255
<div class="font-mono p-3 border border-border rounded-md bg-[var(--bg)]/10 backdrop-blur-md">
258256
<div class="grid grid-cols-[12px_minmax(0,1fr)_max-content] items-center gap-x-3 border-b border-border pb-2 mb-2">
259257
260258
<div class="w-3 h-3">
261259
<svg viewBox="0 0 20 20" class="w-full h-full" aria-hidden="true">
262-
<circle cx="10" cy="10" r="10" fill="${datapoint?.color ?? "transparent"}" />
260+
<circle cx="10" cy="10" r="10" fill="${datapoint?.color ?? 'transparent'}" />
263261
</svg>
264262
</div>
265263
<span class="text-3xs uppercase tracking-wide text-[var(--fg)]/70 truncate">
266264
${datapoint?.name ?? ''}
267265
</span>
268-
266+
269267
<div class="text-fg-subtle text-xs border border-border rounded-sm px-1">
270268
${datapoint?.category?.license}
271269
</div>
272270
</div>
273-
274-
${isDeprecated ? `<div class="text-xs text-red-700 dark:text-red-400 my-1">${$t("package.deprecation.package")}</div>` : ``}
271+
272+
${isDeprecated ? `<div class="text-xs text-red-700 dark:text-red-400 my-1">${$t('package.deprecation.package')}</div>` : ``}
275273
276274
<div class="text-fg text-xs">${$t('compare.quadrant_chart.label_x_axis')}</div>
277275
<div class="flex flex-col text-xs">
@@ -311,18 +309,17 @@ const config = computed<VueUiQuadrantConfig>(() => {
311309
</div>
312310
<div class="flex flex-row items-baseline gap-2">
313311
<span class="text-fg-subtle">${$t('compare.facets.items.types.label')}</span>
314-
<span class="text-fg text-sm">${datapoint?.category?.metrics.types ? "Yes" : "No"}</span>
312+
<span class="text-fg text-sm">${datapoint?.category?.metrics.types ? 'Yes' : 'No'}</span>
315313
</div>
316314
</div>
317315
</div>
318-
`;
316+
`
319317
},
320318
},
321319
},
322320
},
323-
};
324-
});
325-
321+
}
322+
})
326323
</script>
327324

328325
<template>
@@ -331,24 +328,24 @@ const config = computed<VueUiQuadrantConfig>(() => {
331328
{{ $t('compare.quadrant_chart.title') }}
332329
<TooltipApp interactive>
333330
<button
334-
type="button"
335-
class="i-lucide:info w-3.5 h-3.5 text-fg-muted cursor-help"
336-
:aria-label="$t('compare.quadrant_chart.title')"
337-
/>
338-
<template #content>
339-
<div class="flex flex-col gap-3">
340-
<p class="text-xs text-fg-muted">
341-
{{ $t('compare.quadrant_chart.explanation.introduction') }}
342-
</p>
343-
<ul class="text-xs text-fg-subtle list-disc list-inside">
344-
<li>{{ $t('compare.quadrant_chart.explanation.adoption') }}</li>
345-
<li>{{ $t('compare.quadrant_chart.explanation.efficiency') }}</li>
346-
</ul>
347-
<p class="text-xs text-fg-muted">
348-
{{ $t('compare.quadrant_chart.explanation.impact_details') }}
349-
</p>
350-
</div>
351-
</template>
331+
type="button"
332+
class="i-lucide:info w-3.5 h-3.5 text-fg-muted cursor-help"
333+
:aria-label="$t('compare.quadrant_chart.title')"
334+
/>
335+
<template #content>
336+
<div class="flex flex-col gap-3">
337+
<p class="text-xs text-fg-muted">
338+
{{ $t('compare.quadrant_chart.explanation.introduction') }}
339+
</p>
340+
<ul class="text-xs text-fg-subtle list-disc list-inside">
341+
<li>{{ $t('compare.quadrant_chart.explanation.adoption') }}</li>
342+
<li>{{ $t('compare.quadrant_chart.explanation.efficiency') }}</li>
343+
</ul>
344+
<p class="text-xs text-fg-muted">
345+
{{ $t('compare.quadrant_chart.explanation.impact_details') }}
346+
</p>
347+
</div>
348+
</template>
352349
</TooltipApp>
353350
</div>
354351
<ClientOnly>
@@ -364,27 +361,23 @@ const config = computed<VueUiQuadrantConfig>(() => {
364361
drawingArea: {
365362
top: svg.top,
366363
height: svg.height,
367-
}
364+
},
368365
},
369366
colors: watermarkColors,
370367
translateFn: $t,
371368
positioning: 'bottom',
372369
sizeRatioTagline: 0.6,
373370
sizeRatioLogo: 0.4,
374371
offsetYTagline: 20,
375-
offsetYLogo: 12
372+
offsetYLogo: 12,
376373
})
377374
"
378375
/>
379376
</template>
380377

381378
<template #menuIcon="{ isOpen }">
382379
<span v-if="isOpen" class="i-lucide:x w-6 h-6" aria-hidden="true" />
383-
<span
384-
v-else
385-
class="i-lucide:ellipsis-vertical w-6 h-6"
386-
aria-hidden="true"
387-
/>
380+
<span v-else class="i-lucide:ellipsis-vertical w-6 h-6" aria-hidden="true" />
388381
</template>
389382
<template #optionImg>
390383
<span class="text-fg-subtle font-mono pointer-events-none">PNG</span>
@@ -401,11 +394,7 @@ const config = computed<VueUiQuadrantConfig>(() => {
401394
/>
402395
</template>
403396
<template #annotator-action-color="{ color }">
404-
<span
405-
class="i-lucide:palette w-6 h-6"
406-
:style="{ color }"
407-
aria-hidden="true"
408-
/>
397+
<span class="i-lucide:palette w-6 h-6" :style="{ color }" aria-hidden="true" />
409398
</template>
410399
<template #annotator-action-draw="{ mode }">
411400
<span
@@ -468,9 +457,7 @@ const config = computed<VueUiQuadrantConfig>(() => {
468457
<span
469458
class="w-6 h-6"
470459
:class="
471-
copied
472-
? 'i-lucide:check text-accent'
473-
: 'i-lucide:person-standing text-fg-subtle'
460+
copied ? 'i-lucide:check text-accent' : 'i-lucide:person-standing text-fg-subtle'
474461
"
475462
style="pointer-events: none"
476463
aria-hidden="true"
@@ -492,4 +479,4 @@ const config = computed<VueUiQuadrantConfig>(() => {
492479
outline: 0.1rem solid var(--accent-color) !important;
493480
border-radius: 0.25rem;
494481
}
495-
</style>
482+
</style>

app/composables/useChartWatermark.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function drawNpmxLogoAndTaglineWatermark({
7979
sizeRatioLogo = 1,
8080
sizeRatioTagline = 1,
8181
offsetYTagline = -6,
82-
offsetYLogo = 0
82+
offsetYLogo = 0,
8383
}: {
8484
svg: Record<string, any>
8585
colors: WatermarkColors
@@ -102,7 +102,9 @@ export function drawNpmxLogoAndTaglineWatermark({
102102
: svg.height - npmxLogoHeight
103103

104104
const taglineY =
105-
positioning === 'belowDrawingArea' ? watermarkY + offsetYTagline : svg.height - npmxLogoHeight + offsetYTagline
105+
positioning === 'belowDrawingArea'
106+
? watermarkY + offsetYTagline
107+
: svg.height - npmxLogoHeight + offsetYTagline
106108

107109
// Center the watermark horizontally relative to the full SVG width
108110
const watermarkX = svg.width / 2 - npmxLogoWidth / 2

app/pages/compare.vue

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ useSeoMeta({
273273
</div>
274274

275275
<div v-else-if="packagesData && packagesData.some(p => p !== null)">
276-
277276
<!-- View tabs -->
278277
<TabRoot
279278
v-model="comparisonView"
@@ -355,11 +354,7 @@ useSeoMeta({
355354
<p v-else class="py-12 text-center text-fg-subtle">
356355
{{ $t('compare.packages.no_chartable_data') }}
357356
</p>
358-
<FacetQuadrantChart
359-
v-if="packages.length"
360-
:packages-data="packagesData"
361-
:packages="packages"
362-
/>
357+
<FacetQuadrantChart v-if="packages.length" :packages-data="packagesData" :packages="packages" />
363358
</TabPanel>
364359
</TabRoot>
365360

0 commit comments

Comments
 (0)