@astryxdesign/core 0.7.1 → 0.7.2-canary.b06a093
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/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +38 -14
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +3 -1
- package/dist/Pagination/Pagination.d.ts +8 -5
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +21 -8
- package/dist/PowerSearch/PowerSearch.js +1 -1
- package/dist/Switch/Switch.d.ts +1 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +6 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +11 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +26 -0
- package/dist/astryx.css +1 -0
- package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/en.generated.js +19 -0
- package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
- package/dist/i18n/generated-locales/pseudo.generated.js +19 -0
- package/locales/en.json +76 -0
- package/locales/pseudo.json +57 -0
- package/package.json +4 -4
- package/src/Button/Button.doc.mjs +2 -2
- package/src/Button/Button.test.tsx +155 -9
- package/src/Button/Button.tsx +39 -16
- package/src/Button/__tests__/Button.a11y.known-failures.ts +1 -62
- package/src/Button/__tests__/Button.a11y.states.ts +0 -10
- package/src/IconButton/IconButton.doc.mjs +2 -2
- package/src/IconButton/IconButton.test.tsx +3 -1
- package/src/MultiSelector/hooks.ts +3 -1
- package/src/MultiSelector/useMultiCombobox.doc.mjs +267 -0
- package/src/Pagination/Pagination.doc.mjs +7 -7
- package/src/Pagination/Pagination.spec.md +9 -9
- package/src/Pagination/Pagination.test.tsx +242 -0
- package/src/Pagination/Pagination.tsx +27 -11
- package/src/PowerSearch/PowerSearch.test.tsx +85 -0
- package/src/PowerSearch/PowerSearch.tsx +2 -2
- package/src/Switch/Switch.test.tsx +28 -0
- package/src/Switch/Switch.tsx +6 -0
- package/src/Tokenizer/Tokenizer.test.tsx +54 -1
- package/src/Tooltip/useTooltip.test.tsx +13 -0
- package/src/Tooltip/useTooltip.tsx +11 -0
- package/src/Typeahead/BaseTypeahead.tsx +26 -0
- package/src/Typeahead/Typeahead.test.tsx +260 -2
- package/src/i18n/InternationalizationProvider.doc.mjs +8 -0
- package/src/i18n/InternationalizationProvider.spec.md +252 -0
- package/src/i18n/__tests__/InternationalizationProvider.test.tsx +128 -0
- package/src/i18n/generated-locales/en.generated.ts +21 -0
- package/src/i18n/generated-locales/pseudo.generated.ts +21 -0
- package/src/i18n/useTranslator.test.tsx +37 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file InternationalizationProvider.test.tsx
|
|
5
|
+
* @input packages/core/src/i18n/InternationalizationProvider.tsx, useTranslator,
|
|
6
|
+
* useDirection, useLocale
|
|
7
|
+
* @output Unit tests for the provider's update and nesting contract
|
|
8
|
+
* @position Colocated tests; targets re-rendering when messages, overrides, or
|
|
9
|
+
* dir change (locale is covered by useLocale/useTranslator tests) and a nested
|
|
10
|
+
* provider replacing rather than merging its parent's context.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {describe, expect, test} from 'vitest';
|
|
14
|
+
import {render} from '@testing-library/react';
|
|
15
|
+
import {InternationalizationProvider} from '../InternationalizationProvider';
|
|
16
|
+
import {useDirection} from '../useDirection';
|
|
17
|
+
import {useLocale} from '../useLocale';
|
|
18
|
+
import {useTranslator} from '../useTranslator';
|
|
19
|
+
import type {MessagesByLocale, Overrides} from '../types';
|
|
20
|
+
|
|
21
|
+
const NEXT = '@astryx.pagination.next';
|
|
22
|
+
const APP_KEY = '@myapp.save';
|
|
23
|
+
|
|
24
|
+
function Probe() {
|
|
25
|
+
const t = useTranslator();
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
<span data-testid="next">{t(NEXT)}</span>
|
|
29
|
+
<span data-testid="app">{t(APP_KEY)}</span>
|
|
30
|
+
<span data-testid="locale">{useLocale()}</span>
|
|
31
|
+
<span data-testid="dir">{useDirection()}</span>
|
|
32
|
+
</>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const FR_MESSAGES: MessagesByLocale = {
|
|
37
|
+
fr: {[APP_KEY]: {defaultMessage: 'Enregistrer'}},
|
|
38
|
+
};
|
|
39
|
+
const FR_MESSAGES_V2: MessagesByLocale = {
|
|
40
|
+
fr: {[APP_KEY]: {defaultMessage: 'Sauvegarder'}},
|
|
41
|
+
};
|
|
42
|
+
const FR_OVERRIDES: Overrides = {fr: {[NEXT]: 'Suivant'}};
|
|
43
|
+
const FR_OVERRIDES_V2: Overrides = {fr: {[NEXT]: 'Page suivante'}};
|
|
44
|
+
|
|
45
|
+
describe('InternationalizationProvider — re-rendering', () => {
|
|
46
|
+
test('re-renders consumers when messages change', () => {
|
|
47
|
+
const {getByTestId, rerender} = render(
|
|
48
|
+
<InternationalizationProvider locale="fr" messages={FR_MESSAGES}>
|
|
49
|
+
<Probe />
|
|
50
|
+
</InternationalizationProvider>,
|
|
51
|
+
);
|
|
52
|
+
expect(getByTestId('app').textContent).toBe('Enregistrer');
|
|
53
|
+
|
|
54
|
+
rerender(
|
|
55
|
+
<InternationalizationProvider locale="fr" messages={FR_MESSAGES_V2}>
|
|
56
|
+
<Probe />
|
|
57
|
+
</InternationalizationProvider>,
|
|
58
|
+
);
|
|
59
|
+
expect(getByTestId('app').textContent).toBe('Sauvegarder');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('re-renders consumers when overrides change', () => {
|
|
63
|
+
const {getByTestId, rerender} = render(
|
|
64
|
+
<InternationalizationProvider locale="fr" overrides={FR_OVERRIDES}>
|
|
65
|
+
<Probe />
|
|
66
|
+
</InternationalizationProvider>,
|
|
67
|
+
);
|
|
68
|
+
expect(getByTestId('next').textContent).toBe('Suivant');
|
|
69
|
+
|
|
70
|
+
rerender(
|
|
71
|
+
<InternationalizationProvider locale="fr" overrides={FR_OVERRIDES_V2}>
|
|
72
|
+
<Probe />
|
|
73
|
+
</InternationalizationProvider>,
|
|
74
|
+
);
|
|
75
|
+
expect(getByTestId('next').textContent).toBe('Page suivante');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('re-renders consumers when dir changes', () => {
|
|
79
|
+
const {getByTestId, rerender} = render(
|
|
80
|
+
<InternationalizationProvider locale="en" dir="rtl">
|
|
81
|
+
<Probe />
|
|
82
|
+
</InternationalizationProvider>,
|
|
83
|
+
);
|
|
84
|
+
expect(getByTestId('dir').textContent).toBe('rtl');
|
|
85
|
+
|
|
86
|
+
rerender(
|
|
87
|
+
<InternationalizationProvider locale="en" dir="ltr">
|
|
88
|
+
<Probe />
|
|
89
|
+
</InternationalizationProvider>,
|
|
90
|
+
);
|
|
91
|
+
expect(getByTestId('dir').textContent).toBe('ltr');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe('InternationalizationProvider — nesting', () => {
|
|
96
|
+
test('a nested provider replaces the parent context instead of merging it', () => {
|
|
97
|
+
const {getByTestId} = render(
|
|
98
|
+
<InternationalizationProvider
|
|
99
|
+
locale="fr"
|
|
100
|
+
dir="rtl"
|
|
101
|
+
messages={FR_MESSAGES}
|
|
102
|
+
overrides={FR_OVERRIDES}>
|
|
103
|
+
<InternationalizationProvider locale="fr">
|
|
104
|
+
<Probe />
|
|
105
|
+
</InternationalizationProvider>
|
|
106
|
+
</InternationalizationProvider>,
|
|
107
|
+
);
|
|
108
|
+
// Locale is the child's own; direction derives from it, not the parent's
|
|
109
|
+
// explicit rtl; parent overrides and catalogs do not leak into the child.
|
|
110
|
+
expect(getByTestId('locale').textContent).toBe('fr');
|
|
111
|
+
expect(getByTestId('dir').textContent).toBe('ltr');
|
|
112
|
+
expect(getByTestId('next').textContent).toBe('Go to next page');
|
|
113
|
+
expect(getByTestId('app').textContent).toBe(APP_KEY);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('a nested provider can narrow the locale for one subtree', () => {
|
|
117
|
+
const {getByTestId} = render(
|
|
118
|
+
<InternationalizationProvider locale="fr" overrides={FR_OVERRIDES}>
|
|
119
|
+
<InternationalizationProvider locale="de">
|
|
120
|
+
<Probe />
|
|
121
|
+
</InternationalizationProvider>
|
|
122
|
+
</InternationalizationProvider>,
|
|
123
|
+
);
|
|
124
|
+
expect(getByTestId('locale').textContent).toBe('de');
|
|
125
|
+
// No de override or catalog: shipped English wins.
|
|
126
|
+
expect(getByTestId('next').textContent).toBe('Go to next page');
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -158,6 +158,27 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
158
158
|
'{itemName} dropped at position {position, number} of {total, number}.',
|
|
159
159
|
'@astryx.listInput.announceAlreadyAtBoundary':
|
|
160
160
|
'This {itemName} is already {boundary, select, first {first} last {last} other {}}.',
|
|
161
|
+
'@astryx.diffViewer.label': 'Diff',
|
|
162
|
+
'@astryx.diffViewer.renamedPath': '{oldPath} → {newPath}',
|
|
163
|
+
'@astryx.diffViewer.statusAdded': 'Added',
|
|
164
|
+
'@astryx.diffViewer.statusDeleted': 'Deleted',
|
|
165
|
+
'@astryx.diffViewer.statusRenamed': 'Renamed',
|
|
166
|
+
'@astryx.diffViewer.addedCount': '+{count, number}',
|
|
167
|
+
'@astryx.diffViewer.removedCount': '−{count, number}',
|
|
168
|
+
'@astryx.diffViewer.stats':
|
|
169
|
+
'{added, plural, one {# line added} other {# lines added}}, {removed, plural, one {# line removed} other {# lines removed}}',
|
|
170
|
+
'@astryx.diffViewer.added': 'Added',
|
|
171
|
+
'@astryx.diffViewer.removed': 'Removed',
|
|
172
|
+
'@astryx.diffViewer.lineNumberButton':
|
|
173
|
+
'{side, select, old {Original line {line, number}} other {Changed line {line, number}}}',
|
|
174
|
+
'@astryx.diffViewer.columnOldLine': 'Original line number',
|
|
175
|
+
'@astryx.diffViewer.columnNewLine': 'Changed line number',
|
|
176
|
+
'@astryx.diffViewer.columnChange': 'Change',
|
|
177
|
+
'@astryx.diffViewer.columnCode': 'Code',
|
|
178
|
+
'@astryx.diffViewer.columnOldCode': 'Original code',
|
|
179
|
+
'@astryx.diffViewer.columnNewCode': 'Changed code',
|
|
180
|
+
'@astryx.diffViewer.binary': 'Binary file not shown',
|
|
181
|
+
'@astryx.diffViewer.noChanges': 'No content changes',
|
|
161
182
|
'@astryx.markdownHeadingLinks.copied': 'Link copied',
|
|
162
183
|
'@astryx.markdownHeadingLinks.copy': 'Copy link to {heading}',
|
|
163
184
|
'@astryx.richTextEditor.tabEscapeHint':
|
|
@@ -163,6 +163,27 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
|
|
|
163
163
|
'⟦{itemName} ðřóþþéð àţ þóšíţíóñ {position, number} óƒ {total, number}.⟧',
|
|
164
164
|
'@astryx.listInput.announceAlreadyAtBoundary':
|
|
165
165
|
'⟦Ţĥíš {itemName} íš àłřéàðý {boundary, select, first {first} last {last} other {}}.⟧',
|
|
166
|
+
'@astryx.diffViewer.label': '⟦Ð탃⟧',
|
|
167
|
+
'@astryx.diffViewer.renamedPath': '⟦{oldPath} → {newPath}⟧',
|
|
168
|
+
'@astryx.diffViewer.statusAdded': '⟦Àððéð⟧',
|
|
169
|
+
'@astryx.diffViewer.statusDeleted': '⟦Ðéłéţéð⟧',
|
|
170
|
+
'@astryx.diffViewer.statusRenamed': '⟦Řéñàɱéð⟧',
|
|
171
|
+
'@astryx.diffViewer.addedCount': '⟦+{count, number}⟧',
|
|
172
|
+
'@astryx.diffViewer.removedCount': '⟦−{count, number}⟧',
|
|
173
|
+
'@astryx.diffViewer.stats':
|
|
174
|
+
'⟦{added, plural, one {# line added} other {# lines added}}, {removed, plural, one {# line removed} other {# lines removed}}⟧',
|
|
175
|
+
'@astryx.diffViewer.added': '⟦Àððéð⟧',
|
|
176
|
+
'@astryx.diffViewer.removed': '⟦Řéɱóṽéð⟧',
|
|
177
|
+
'@astryx.diffViewer.lineNumberButton':
|
|
178
|
+
'⟦{side, select, old {Original line {line, number}} other {Changed line {line, number}}}⟧',
|
|
179
|
+
'@astryx.diffViewer.columnOldLine': '⟦Óříĝíñàł łíñé ñúɱƀéř⟧',
|
|
180
|
+
'@astryx.diffViewer.columnNewLine': '⟦Çĥàñĝéð łíñé ñúɱƀéř⟧',
|
|
181
|
+
'@astryx.diffViewer.columnChange': '⟦Çĥàñĝé⟧',
|
|
182
|
+
'@astryx.diffViewer.columnCode': '⟦Çóðé⟧',
|
|
183
|
+
'@astryx.diffViewer.columnOldCode': '⟦Óříĝíñàł çóðé⟧',
|
|
184
|
+
'@astryx.diffViewer.columnNewCode': '⟦Çĥàñĝéð çóðé⟧',
|
|
185
|
+
'@astryx.diffViewer.binary': '⟦Ɓíñàřý ƒíłé ñóţ šĥóŵñ⟧',
|
|
186
|
+
'@astryx.diffViewer.noChanges': '⟦Ñó çóñţéñţ çĥàñĝéš⟧',
|
|
166
187
|
'@astryx.markdownHeadingLinks.copied': '⟦Łíñķ çóþíéð⟧',
|
|
167
188
|
'@astryx.markdownHeadingLinks.copy': '⟦Çóþý łíñķ ţó {heading}⟧',
|
|
168
189
|
'@astryx.richTextEditor.tabEscapeHint':
|
|
@@ -32,6 +32,12 @@ const FR_MESSAGES: MessagesByLocale = {
|
|
|
32
32
|
const FR_RUNTIME_MESSAGES: ProviderMessagesByLocale = {
|
|
33
33
|
fr: {'@astryx.pagination.next': 'Page suivante compacte'},
|
|
34
34
|
};
|
|
35
|
+
// One messages value mixing shapes: a generated string map for the active
|
|
36
|
+
// locale and a rich catalog for its parent.
|
|
37
|
+
const MIXED_MESSAGES: ProviderMessagesByLocale = {
|
|
38
|
+
'fr-CA': {'@astryx.pagination.next': 'Page suivante (CA)'},
|
|
39
|
+
fr: {'@astryx.pagination.previous': {defaultMessage: 'Page précédente'}},
|
|
40
|
+
};
|
|
35
41
|
const FR_OVERRIDES: Overrides = {
|
|
36
42
|
fr: {'@astryx.pagination.next': 'Suivant'},
|
|
37
43
|
};
|
|
@@ -101,6 +107,37 @@ describe('useTranslator — resolution', () => {
|
|
|
101
107
|
).toEqual({defaultMessage: 'Page suivante compacte'});
|
|
102
108
|
});
|
|
103
109
|
|
|
110
|
+
it('resolves rich and runtime catalogs mixed in one messages value', () => {
|
|
111
|
+
const {result} = renderHook(
|
|
112
|
+
() => ({
|
|
113
|
+
context: use(InternationalizationContext),
|
|
114
|
+
translate: useTranslator(),
|
|
115
|
+
}),
|
|
116
|
+
{
|
|
117
|
+
wrapper: ({children}) => (
|
|
118
|
+
<InternationalizationProvider
|
|
119
|
+
locale="fr-CA"
|
|
120
|
+
messages={MIXED_MESSAGES}>
|
|
121
|
+
{children}
|
|
122
|
+
</InternationalizationProvider>
|
|
123
|
+
),
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(result.current.translate('@astryx.pagination.next')).toBe(
|
|
128
|
+
'Page suivante (CA)',
|
|
129
|
+
);
|
|
130
|
+
expect(result.current.translate('@astryx.pagination.previous')).toBe(
|
|
131
|
+
'Page précédente',
|
|
132
|
+
);
|
|
133
|
+
expect(result.current.context.messages).toEqual({
|
|
134
|
+
'fr-CA': {
|
|
135
|
+
'@astryx.pagination.next': {defaultMessage: 'Page suivante (CA)'},
|
|
136
|
+
},
|
|
137
|
+
fr: {'@astryx.pagination.previous': {defaultMessage: 'Page précédente'}},
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
104
141
|
it('lets a provider override beat the provider catalog', () => {
|
|
105
142
|
const {result} = renderHook(() => useTranslator(), {
|
|
106
143
|
wrapper: ({children}) => (
|