Skip to content

Commit d539b10

Browse files
authored
Merge branch 'main' into sb-recharging-page
2 parents f61f5b6 + c145e99 commit d539b10

File tree

21 files changed

+1838
-62
lines changed

21 files changed

+1838
-62
lines changed

.github/workflows/welcome-close.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
name: 🎉 Welcome new contributor
1717
steps:
1818
- name: 🎉 Welcome new contributor
19-
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
19+
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
2020
with:
2121
script: |
2222
const pr = context.payload.pull_request;

app/assets/main.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ html.light .shiki {
287287
}
288288
}
289289

290+
/* Settings-based configuration for code ligatures. On by default. */
291+
:root[data-code-ligatures='false'] code {
292+
font-variant-ligatures: none;
293+
}
294+
290295
/* Inline code in package descriptions */
291296
p > span > code,
292297
.line-clamp-2 code {

app/components/Compare/FacetScatterChart.vue

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ const props = defineProps<{
1616
const colorMode = useColorMode()
1717
const resolvedMode = shallowRef<'light' | 'dark'>('light')
1818
const rootEl = shallowRef<HTMLElement | null>(null)
19+
const { width } = useElementSize(rootEl)
1920
const { copy, copied } = useClipboard()
2021
22+
const mobileBreakpointWidth = 640
23+
const isMobile = computed(() => width.value > 0 && width.value < mobileBreakpointWidth)
24+
2125
const { colors } = useCssVariables(
2226
[
2327
'--bg',
@@ -277,6 +281,13 @@ const highlightedAxis = shallowRef<AxisHighlight>(null)
277281
function toggleAxisHighlight(state: AxisHighlight) {
278282
highlightedAxis.value = state
279283
}
284+
285+
const readyTeleport = shallowRef(false)
286+
287+
onMounted(async () => {
288+
await nextTick()
289+
readyTeleport.value = true
290+
})
280291
</script>
281292

282293
<template>
@@ -296,9 +307,7 @@ function toggleAxisHighlight(state: AxisHighlight) {
296307
</div>
297308

298309
<div class="flex flex-col sm:flex-row gap-4 items-start">
299-
<div
300-
class="w-full sm:w-fit order-1 sm:order-2 flex flex-row sm:flex-col gap-2 sm:self-end sm:mb-17"
301-
>
310+
<div class="w-full sm:w-fit order-1 sm:order-2 flex flex-row sm:flex-col gap-2">
302311
<SelectField
303312
class="w-full"
304313
id="select-facet-scatter-x"
@@ -327,6 +336,22 @@ function toggleAxisHighlight(state: AxisHighlight) {
327336
@focusin="toggleAxisHighlight('y')"
328337
@focusout="toggleAxisHighlight(null)"
329338
/>
339+
340+
<h3
341+
id="scatter-chart-legend-packages"
342+
:class="[
343+
'mb-1 font-mono text-fg-subtle tracking-wide uppercase mt-4 text-2xs',
344+
isMobile ? 'sr-only' : 'block',
345+
]"
346+
>
347+
{{ $t('compare.packages.section_packages') }}
348+
</h3>
349+
350+
<div
351+
id="compare-scatter-legend"
352+
:role="isMobile ? undefined : 'group'"
353+
:aria-labelledby="isMobile ? undefined : 'scatter-chart-legend-packages'"
354+
></div>
330355
</div>
331356

332357
<ClientOnly>
@@ -346,32 +371,46 @@ function toggleAxisHighlight(state: AxisHighlight) {
346371
<!-- Custom legend -->
347372
<template #legend="{ legend }">
348373
<div
349-
class="flex flex-row flex-wrap gap-x-6 justify-center gap-y-2 px-6 sm:px-10 text-xs"
374+
id="compare-scatter-legend-inner"
375+
:role="isMobile ? 'group' : undefined"
376+
:aria-labelledby="isMobile ? 'scatter-chart-legend-packages' : undefined"
377+
></div>
378+
<Teleport
379+
v-if="readyTeleport"
380+
:to="isMobile ? '#compare-scatter-legend-inner' : '#compare-scatter-legend'"
350381
>
351-
<button
352-
v-for="datapoint in legend"
353-
:key="datapoint.name"
354-
:aria-pressed="datapoint.isSegregated"
355-
:aria-label="datapoint.name"
356-
type="button"
357-
class="flex gap-1 place-items-center"
358-
@click="datapoint.segregate()"
382+
<ul
383+
:class="
384+
isMobile
385+
? 'flex flex-row flex-wrap gap-x-6 justify-center gap-y-2 px-6 sm:px-10 text-xs'
386+
: 'text-sm leading-6'
387+
"
359388
>
360-
<div class="h-3 w-3">
361-
<svg viewBox="0 0 2 2" class="w-full">
362-
<circle cx="1" cy="1" r="1" :fill="datapoint.color" />
363-
</svg>
364-
</div>
365-
<span
366-
class="text-fg"
367-
:style="{
368-
textDecoration: datapoint.isSegregated ? 'line-through' : undefined,
369-
}"
370-
>
371-
{{ datapoint.name }}
372-
</span>
373-
</button>
374-
</div>
389+
<li v-for="datapoint in legend" :key="datapoint.name">
390+
<button
391+
:aria-pressed="datapoint.isSegregated"
392+
:aria-label="datapoint.name"
393+
type="button"
394+
class="flex gap-1.5 place-items-center"
395+
@click="datapoint.segregate()"
396+
>
397+
<div class="h-3 w-3" aria-hidden="true">
398+
<svg viewBox="0 0 2 2" class="w-full">
399+
<circle cx="1" cy="1" r="1" :fill="datapoint.color" />
400+
</svg>
401+
</div>
402+
<span
403+
class="text-fg"
404+
:style="{
405+
textDecoration: datapoint.isSegregated ? 'line-through' : undefined,
406+
}"
407+
>
408+
{{ datapoint.name }}
409+
</span>
410+
</button>
411+
</li>
412+
</ul>
413+
</Teleport>
375414
</template>
376415

377416
<!-- Custom svg content -->

app/composables/useSettings.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export interface AppSettings {
3939
autoOpenURL: boolean
4040
}
4141
codeContainerFull: boolean
42+
/** Enable/disable ligatures in code */
43+
codeLigatures: boolean
4244
sidebar: {
4345
collapsed: string[]
4446
}
@@ -65,6 +67,7 @@ const DEFAULT_SETTINGS: AppSettings = {
6567
autoOpenURL: false,
6668
},
6769
codeContainerFull: false,
70+
codeLigatures: true,
6871
sidebar: {
6972
collapsed: [],
7073
},
@@ -253,3 +256,33 @@ export function useCodeContainer() {
253256
toggleCodeContainer,
254257
}
255258
}
259+
260+
export const useCodeLigatures = createSharedComposable(function useCodeLigatures() {
261+
const { settings } = useSettings()
262+
263+
const codeLigatures = computed(() => settings.value.codeLigatures)
264+
265+
if (import.meta.client) {
266+
// Sync the data attribute on root to the setting
267+
watch(
268+
codeLigatures,
269+
value => {
270+
if (value) {
271+
delete document.documentElement.dataset.codeLigatures
272+
} else {
273+
document.documentElement.dataset.codeLigatures = 'false'
274+
}
275+
},
276+
{ immediate: true },
277+
)
278+
}
279+
280+
function toggleCodeLigatures() {
281+
settings.value.codeLigatures = !settings.value.codeLigatures
282+
}
283+
284+
return {
285+
codeLigatures,
286+
toggleCodeLigatures,
287+
}
288+
})

app/pages/compare.vue

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,14 @@ function addNoDep() {
7575
// Get loading state for each column
7676
const columnLoading = computed(() => packages.value.map((_, i) => isColumnLoading(i)))
7777
78-
// FIXME(serhalp): canCompare only checks package count, not whether data has loaded.
79-
// Copy-markdown and view-switching commands appear as soon as one package loads, even if
80-
// other packages are still loading. The UI copy button has the same issue.
78+
// Makes sense to compare if there's 2 or more packages
8179
const canCompare = computed(() => packages.value.length >= 2)
8280
81+
// Allow copying only after all data is loaded
82+
const canCopyTable = computed(
83+
() => packagesData.value.length >= 1 && packagesData.value.every(data => data !== null),
84+
)
85+
8386
const comparisonView = usePermalink<'table' | 'charts'>('view', 'table')
8487
const hasChartableFacets = computed(() => selectedFacets.value.some(facet => facet.chartable))
8588
@@ -173,7 +176,7 @@ useCommandPaletteContextCommands(
173176
},
174177
]
175178
176-
if (canCompare.value && packagesData.value && packagesData.value.some(p => p !== null)) {
179+
if (canCompare.value && canCopyTable.value) {
177180
commands.push({
178181
id: 'compare-copy-markdown',
179182
group: 'actions',
@@ -335,7 +338,7 @@ useSeoMeta({
335338
<!-- Comparison grid -->
336339
<section v-if="canCompare" class="mt-10" aria-labelledby="comparison-heading">
337340
<CopyToClipboardButton
338-
v-if="packagesData && packagesData.some(p => p !== null)"
341+
v-if="canCopyTable"
339342
:copied="copied"
340343
:copy-text="$t('compare.packages.copy_as_markdown')"
341344
class="mb-4"

app/pages/settings.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { locale: currentLocale, locales, setLocale: setNuxti18nLocale } = useI18n
55
const colorMode = useColorMode()
66
const { currentLocaleStatus, isSourceLocale } = useI18nStatus()
77
const keyboardShortcutsEnabled = useKeyboardShortcuts()
8+
const { toggleCodeLigatures } = useCodeLigatures()
89
910
// Escape to go back (but not when focused on form elements or modal is open)
1011
onKeyStroke(
@@ -143,6 +144,16 @@ const setLocale: typeof setNuxti18nLocale = newLocale => {
143144
:description="$t('settings.enable_graph_pulse_loop_description')"
144145
v-model="settings.enableGraphPulseLooping"
145146
/>
147+
148+
<!-- Divider -->
149+
<div class="border-t border-border my-4" />
150+
151+
<!-- Code ligatures toggle -->
152+
<SettingsToggle
153+
:label="$t('settings.enable_code_ligatures')"
154+
:modelValue="settings.codeLigatures"
155+
@update:modelValue="() => toggleCodeLigatures()"
156+
/>
146157
</div>
147158
</section>
148159

app/utils/prehydrate.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,10 @@ export function initPreferencesOnPrehydrate() {
6666
if (settings.keyboardShortcuts === false) {
6767
document.documentElement.dataset.kbdShortcuts = 'false'
6868
}
69+
70+
// Code font ligatures (default: true)
71+
if (settings.codeLigatures === false) {
72+
document.documentElement.dataset.codeLigatures = 'false'
73+
}
6974
})
7075
}

config/i18n.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ export const countryLocaleVariants: Record<string, (LocaleObjectData & { country
8181
{ country: true, code: 'pt-PT', name: 'Português (Portugal)' },
8282
{ code: 'pt-BR', name: 'Português (Brasil)' },
8383
],*/
84+
nl: [
85+
{ country: true, code: 'nl-NL', name: 'Nederlands' },
86+
// { country: true, code: 'nl-BE', name: 'Vlaams' },
87+
],
8488
}
8589

8690
function createPluralRule(locale: string, mapping: Record<string, number>) {
@@ -218,11 +222,11 @@ const locales: (LocaleObjectData | (Omit<LocaleObjectData, 'code'> & { code: str
218222
file: 'ne-NP.json',
219223
name: 'नेपाली',
220224
},
221-
/*{
222-
code: 'nl-NL',
223-
file: 'nl-NL.json',
224-
name: 'Nederlands',
225-
},*/
225+
{
226+
code: 'nl',
227+
file: 'nl.json',
228+
name: 'Nederlands',
229+
},
226230
{
227231
code: 'es',
228232
file: 'es.json',

docs/content/2.guide/6.badges.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ npmx.dev offers many different SVG badges with stats about any package via its A
2828
- **maintainers**: Displays the total count of package maintainers. :img{src="https://img.shields.io/badge/%2306b6d4-06b6d4" class="inline align-middle h-5 w-14"}
2929
- **deprecated**: Shows if the package is active or deprecated. :img{src="https://img.shields.io/badge/%2322c55e-22c55e" class="inline align-middle h-5 w-14"} / :img{src="https://img.shields.io/badge/%23ef4444-ef4444" class="inline align-middle h-5 w-14"}
3030
- **name**: Simple badge displaying the package name. :img{src="https://img.shields.io/badge/%2364748b-64748b" class="inline align-middle h-5 w-14"}
31+
- **likes**: Shows the total count of package likes. :img{src="https://img.shields.io/badge/%23ef4444-ef4444" class="inline align-middle h-5 w-14"}
3132

3233
## Examples
3334

docs/shared/utils/badges.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const BADGE_TYPES = Object.freeze([
1616
'maintainers',
1717
'deprecated',
1818
'name',
19+
'likes',
1920
] as const)
2021

2122
export type BadgeType = (typeof BADGE_TYPES)[number]

0 commit comments

Comments
 (0)