Skip to content

Commit 20a290a

Browse files
committed
fix(NcDateTimePicker): use translated words in dates formatted with a format string
Signed-off-by: Oleksandr Dzhychko <hey@oleks.dev>
1 parent ebcc3dd commit 20a290a

9 files changed

Lines changed: 352 additions & 199 deletions

File tree

build/date-fns-locales-plugin.mts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*!
2+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: CC0-1.0
4+
*/
5+
import type { Plugin } from 'vite'
6+
7+
import { exactRegex } from '@rolldown/pluginutils'
8+
import { glob } from 'fs/promises'
9+
import { createRequire } from 'module'
10+
import { dirname, join } from 'path'
11+
12+
/**
13+
* This plugin generates a module that can be used to dynamically load locales from `date-fns`.
14+
* It generates it in a way that it works with the externalization of the `date-fns` locales
15+
* and with Vite and Webpack apps.
16+
*
17+
* A plugin is used because Vite's dynamic imports and glob imports cannot generate imports in such a way.
18+
*/
19+
export default () => {
20+
let localeFiles: string[] = []
21+
const virtualModuleId = 'virtual:date-fns-locales'
22+
const resolvedVirtualModuleId = '\0' + virtualModuleId
23+
return {
24+
name: 'date-fns-locales-plugin',
25+
enforce: 'pre',
26+
async buildStart() {
27+
this.info('Collectioning locales in date-fns/locales')
28+
const require = createRequire(import.meta.url)
29+
const pkgJsonPath = require.resolve('date-fns/package.json')
30+
const localeDir = join(dirname(pkgJsonPath), 'locale')
31+
localeFiles = await Array.fromAsync(glob('*.js', {
32+
cwd: localeDir,
33+
exclude: ['types.js', 'en-US.js', 'cdn.js', 'cdn.min.js'],
34+
}))
35+
},
36+
resolveId: {
37+
filter: { id: /dateFnsLocaleLoader\.ts$/ },
38+
handler() {
39+
return resolvedVirtualModuleId
40+
},
41+
},
42+
load: {
43+
filter: { id: exactRegex(resolvedVirtualModuleId) },
44+
handler() {
45+
let content = ''
46+
content += 'const loader = {}\n'
47+
content += 'export default loader\n'
48+
for (const localeFile of localeFiles) {
49+
// e.g., "pt-BR.js" -> "pt-BR"
50+
const localeCode = localeFile.slice(0, -3)
51+
let exportName = localeCode.replaceAll('-', '')
52+
// One locale is named inconsistently...
53+
if (localeCode === 'be-tarask') {
54+
exportName = 'beTarasak'
55+
}
56+
content += `loader['${localeCode}'] = async () => (await import('date-fns/locale/${localeCode}')).${exportName}\n`
57+
}
58+
return content
59+
},
60+
},
61+
} as Plugin
62+
}

0 commit comments

Comments
 (0)