@livestorm/ui-vue 2.0.2 → 2.0.4
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.
- package/README.md +79 -93
- package/dist/{UiTimelineItem.vue_vue_type_style_index_0_lang-B0UKmlqE.mjs → UiTimelineItem.vue_vue_type_style_index_0_lang-BtG5oABt.mjs} +1595 -1594
- package/dist/components.mjs +1 -1
- package/dist/i18n-Cktw9hIu.mjs +49 -0
- package/dist/index.mjs +1 -1
- package/dist/integrations.mjs +10 -4
- package/dist/layouts.mjs +1 -1
- package/dist/types/src/components/Toast/ToastMessage.vue.d.ts +4 -4
- package/dist/types/src/components/UiBanner/UiBanner.vue.d.ts +2 -2
- package/dist/types/src/components/UiButton/UiButton.vue.d.ts +1 -1
- package/dist/types/src/components/UiButtonGroup/UiButtonGroup.vue.d.ts +1 -1
- package/dist/types/src/components/UiColorField/UiColorField.vue.d.ts +2 -2
- package/dist/types/src/components/UiColorPicker/UiColorPicker.vue.d.ts +2 -2
- package/dist/types/src/components/UiDropdown/UiDropdownTrigger.vue.d.ts +1 -1
- package/dist/types/src/components/UiFieldWrapper/UiFieldWrapper.vue.d.ts +1 -1
- package/dist/types/src/components/UiForm/UiFormField.vue.d.ts +1 -1
- package/dist/types/src/components/UiInputCheckbox/UiInputCheckbox.vue.d.ts +5 -5
- package/dist/types/src/components/UiInputSelect/UiInputSelect.vue.d.ts +3 -3
- package/dist/types/src/components/UiInputTextarea/UiInputTextarea.vue.d.ts +3 -3
- package/dist/types/src/components/UiTextField/UiTextField.vue.d.ts +5 -5
- package/dist/types/src/composables/useButtonStyles.d.ts +1 -1
- package/dist/types/src/integrations/index.d.ts +1 -0
- package/dist/types/src/utils/i18n.d.ts +51 -0
- package/dist/ui-vue.css +1 -1
- package/dist/{useThemeAndModes-DY5SDC0a.mjs → useThemeAndModes-CUK56j0z.mjs} +20 -21
- package/dist/utils.mjs +55 -55
- package/integrations.d.ts +1 -0
- package/package.json +26 -19
- package/src/components/UiBanner/UiBanner.vue +4 -2
- package/src/components/UiDialog/UiDialogContent.vue +12 -4
- package/src/components/UiSideMenu/UiSideMenu.vue +4 -3
- package/src/composables/useThemeAndModes.ts +8 -4
- package/src/css/body.css +15 -7
- package/src/css/fonts.css +10 -0
- package/src/integrations/index.js +1 -0
- package/src/utils/clipboard.js +5 -2
- package/src/utils/i18n.ts +113 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import i18next from 'i18next'
|
|
2
|
+
import { getCurrentInstance, inject } from 'vue'
|
|
3
|
+
import type { InjectionKey } from 'vue'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Built-in translations for the few strings components render themselves
|
|
7
|
+
* (aria-labels, tooltips). Keyed like the Livestorm app locales so a host
|
|
8
|
+
* app running i18next with these keys keeps full control.
|
|
9
|
+
*/
|
|
10
|
+
const FALLBACK_BUNDLES: Record<string, Record<string, string>> = {
|
|
11
|
+
en: {
|
|
12
|
+
general_close: 'Close',
|
|
13
|
+
general_dialog_title: 'Dialog',
|
|
14
|
+
'general_misc_copied-text': 'Copied!',
|
|
15
|
+
'room_bottom-bar_controls-label_more': 'More',
|
|
16
|
+
},
|
|
17
|
+
fr: {
|
|
18
|
+
general_close: 'Fermer',
|
|
19
|
+
general_dialog_title: 'Dialog',
|
|
20
|
+
'general_misc_copied-text': 'Copié !',
|
|
21
|
+
'room_bottom-bar_controls-label_more': 'Plus',
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Keys of the built-in labels. They MUST stay identical to the Livestorm
|
|
27
|
+
* app locale keys (Phrase): inside the app, translate() resolves through
|
|
28
|
+
* the app's i18next with these exact keys, and a silent mismatch would
|
|
29
|
+
* downgrade users to the EN/FR fallbacks. A spec in packages/frontend
|
|
30
|
+
* locks this contract against the app locales.
|
|
31
|
+
*/
|
|
32
|
+
export const BUILT_IN_LABEL_KEYS: readonly string[] = Object.freeze(Object.keys(FALLBACK_BUNDLES.en))
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A host-provided translate function. Return the translated string, or the
|
|
36
|
+
* key itself / null / undefined to decline and let the built-in bundles
|
|
37
|
+
* answer.
|
|
38
|
+
*/
|
|
39
|
+
export type Translator = (key: string) => string | null | undefined
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* App-scoped translator: `app.provide(UI_VUE_TRANSLATOR, fn)` wires the
|
|
43
|
+
* host's i18n per application instance. This is the ONLY safe wiring for
|
|
44
|
+
* SSR servers rendering per-request locales — module state is shared
|
|
45
|
+
* between concurrent requests, an app-provided translator is not.
|
|
46
|
+
*/
|
|
47
|
+
export const UI_VUE_TRANSLATOR: InjectionKey<Translator> = Symbol('ui-vue-translator')
|
|
48
|
+
|
|
49
|
+
let customTranslator: Translator | null = null
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Plug the host app's own i18n stack (an i18next `createInstance()`,
|
|
53
|
+
* vue-i18n, anything callable) into the library's built-in labels. An
|
|
54
|
+
* explicitly wired translator wins over the ambient i18next singleton.
|
|
55
|
+
* Pass null to restore the default behavior.
|
|
56
|
+
*
|
|
57
|
+
* This is process-level state, right for SPAs and static setups. On an SSR
|
|
58
|
+
* server with per-request locales, provide UI_VUE_TRANSLATOR on the app
|
|
59
|
+
* instead: concurrent renders would otherwise overwrite each other here.
|
|
60
|
+
*/
|
|
61
|
+
export function setTranslator (translator: Translator | null): void {
|
|
62
|
+
customTranslator = translator
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function resolve (translator: Translator | null | undefined, key: string): string | null {
|
|
66
|
+
if (!translator) return null
|
|
67
|
+
const value = translator(key)
|
|
68
|
+
return typeof value === 'string' && value !== key ? value : null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Translate a key for a component's built-in label. Resolution order:
|
|
73
|
+
* 1. the translator wired via setTranslator(), when it answers;
|
|
74
|
+
* 2. the ambient i18next singleton, when initialized and it has the key
|
|
75
|
+
* (the Livestorm app path);
|
|
76
|
+
* 3. the built-in EN/FR bundles, language picked from `<html lang>`.
|
|
77
|
+
* Apps not using i18next at all get proper strings instead of raw keys.
|
|
78
|
+
*
|
|
79
|
+
* Components call this through useTranslate(), which puts an app-provided
|
|
80
|
+
* UI_VUE_TRANSLATOR at the very top of that chain.
|
|
81
|
+
*/
|
|
82
|
+
export function translate (key: string): string {
|
|
83
|
+
return translateWith(null, key)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Component-side accessor: returns a translate function bound to the
|
|
88
|
+
* app-provided UI_VUE_TRANSLATOR when called inside setup(), falling back
|
|
89
|
+
* to the process-level chain otherwise. Safe to call outside a component.
|
|
90
|
+
*/
|
|
91
|
+
export function useTranslate (): (key: string) => string {
|
|
92
|
+
const injected = getCurrentInstance() ? inject(UI_VUE_TRANSLATOR, null) : null
|
|
93
|
+
return (key: string) => translateWith(injected, key)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function translateWith (appTranslator: Translator | null, key: string): string {
|
|
97
|
+
const fromApp = resolve(appTranslator, key)
|
|
98
|
+
if (fromApp !== null) return fromApp
|
|
99
|
+
|
|
100
|
+
const fromProcess = resolve(customTranslator, key)
|
|
101
|
+
if (fromProcess !== null) return fromProcess
|
|
102
|
+
|
|
103
|
+
if (i18next.isInitialized && i18next.exists(key)) {
|
|
104
|
+
return i18next.t(key)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const lang = typeof document === 'undefined'
|
|
108
|
+
? 'en'
|
|
109
|
+
: (document.documentElement.lang || 'en').toLowerCase().split('-')[0]
|
|
110
|
+
const bundle = FALLBACK_BUNDLES[lang] || FALLBACK_BUNDLES.en
|
|
111
|
+
|
|
112
|
+
return bundle[key] ?? FALLBACK_BUNDLES.en[key] ?? key
|
|
113
|
+
}
|