@konce-pt/i18n 0.11.2 → 0.14.0

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 CHANGED
@@ -1,11 +1,11 @@
1
1
  <p align="center">
2
- <img src="https://ui.konce.pt/images/koncept_ui_lib.png" alt="Koncept UI — Angular component library" width="100%" />
2
+ <img src="https://ui.konce.pt/images/koncept_ui_lib.png" alt="Koncept UI - Angular component library" width="100%" />
3
3
  </p>
4
4
 
5
5
  # @konce-pt/i18n
6
6
 
7
7
  Kontrakt tłumaczeń i słowniki bazowe (EN, PL) dla [Koncept UI](https://gitlab.com/konce-pt/koncept-ui).
8
- Czysty TypeScript, **zero zależności runtime**, bez wiązania z frameworkiem — jedno źródło prawdy
8
+ Czysty TypeScript, **zero zależności runtime**, bez wiązania z frameworkiem - jedno źródło prawdy
9
9
  dla `@konce-pt/angular` i `@konce-pt/react`.
10
10
 
11
11
  Zwykle nie instalujesz tego pakietu samodzielnie: biblioteki komponentów re-eksportują jego API
@@ -20,10 +20,10 @@ npm i @konce-pt/i18n
20
20
  import { KPT_MESSAGES_PL, translate } from '@konce-pt/i18n';
21
21
 
22
22
  translate(KPT_MESSAGES_PL, 'paginator.range', { start: 1, end: 10, total: 42 });
23
- // '1–10 z 42'
23
+ // '1-10 z 42'
24
24
 
25
25
  translate(KPT_MESSAGES_PL, 'nope.missing');
26
- // 'nope.missing' — brak klucza spada na EN, a potem na sam klucz
26
+ // 'nope.missing' - brak klucza spada na EN, a potem na sam klucz
27
27
  ```
28
28
 
29
29
  ## API
@@ -31,16 +31,16 @@ translate(KPT_MESSAGES_PL, 'nope.missing');
31
31
  | Eksport | Typ | Opis |
32
32
  |---|---|---|
33
33
  | `KptMessages` | `interface` | Kontrakt wszystkich etykiet UI biblioteki |
34
- | `KptLocale` | `type` | `'en' \| 'pl' \| (string & {})` — otwarty kod języka |
34
+ | `KptLocale` | `type` | `'en' \| 'pl' \| (string & {})` - otwarty kod języka |
35
35
  | `KPT_MESSAGES_EN` / `KPT_MESSAGES_PL` | `KptMessages` | Słowniki bazowe |
36
- | `translate(dict, key, params?)` | `string` | Klucz kropkowy + interpolacja `{name}`, fallback → EN → klucz |
36
+ | `translate(dict, key, params?)` | `string` | Klucz kropkowy + interpolacja `{name}`, fallback -> EN -> klucz |
37
37
  | `lookup(dict, key)` | `string \| undefined` | Surowa wartość spod klucza kropkowego |
38
38
  | `deepMerge(base, patch)` | `T` | Nakłada częściowy słownik na pełny |
39
39
  | `weekdayNames(locale)` | `string[]` | Skrócone nazwy dni, od poniedziałku |
40
40
  | `monthNames(locale)` | `string[]` | Pełne nazwy miesięcy |
41
41
  | `DeepPartial<T>`, `KptI18nConfig` | `type` | Typy używane przez wiązania frameworkowe |
42
42
 
43
- Nazw dni i miesięcy nie ma w słowniku — wyliczają się z `Intl` dla aktywnego locale, więc
43
+ Nazw dni i miesięcy nie ma w słowniku - wyliczają się z `Intl` dla aktywnego locale, więc
44
44
  kalendarze działają także w języku, którego nikt nie tłumaczył ręcznie.
45
45
 
46
46
  Pełny opis: [`llms.txt`](https://ui.konce.pt/llms/i18n/llms.txt) (EN)
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { KPT_MESSAGES_EN, KPT_MESSAGES_PL } from './messages.ts';
2
2
  export type { KptLocale, KptMessages } from './messages.ts';
3
3
  export { deepMerge, lookup, translate } from './translate.ts';
4
- export type { DeepPartial, KptI18nConfig } from './types.ts';
5
- export { monthNames, weekdayNames } from './intl.ts';
4
+ export type { DeepPartial, KptI18nConfig, KptMessageKey } from './types.ts';
5
+ export { byteUnitOf, formatBytes, monthNames, weekdayNames } from './intl.ts';
6
+ export type { KptByteUnit } from './intl.ts';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * @konce-pt/i18n — kontrakt tłumaczeń i słowniki bazowe Koncept UI.
2
+ * @konce-pt/i18n - kontrakt tłumaczeń i słowniki bazowe Koncept UI.
3
3
  *
4
4
  * Czysty TypeScript, zero zależności runtime. Współdzielony przez
5
5
  * `@konce-pt/angular` (serwis na sygnałach) i `@konce-pt/react` (Context + hook),
@@ -7,4 +7,4 @@
7
7
  */
8
8
  export { KPT_MESSAGES_EN, KPT_MESSAGES_PL } from "./messages.js";
9
9
  export { deepMerge, lookup, translate } from "./translate.js";
10
- export { monthNames, weekdayNames } from "./intl.js";
10
+ export { byteUnitOf, formatBytes, monthNames, weekdayNames } from "./intl.js";
package/dist/intl.d.ts CHANGED
@@ -1,4 +1,14 @@
1
- /** Krótkie nazwy dni tygodnia, zaczynając od poniedziałku (Pn…Nd). */
1
+ /** Krótkie nazwy dni tygodnia, zaczynając od poniedziałku (Pn...Nd). */
2
2
  export declare function weekdayNames(locale: string): string[];
3
- /** Pełne nazwy miesięcy (styczeń…grudzień / January…December). */
3
+ /** Pełne nazwy miesięcy (styczeń...grudzień / January...December). */
4
4
  export declare function monthNames(locale: string): string[];
5
+ /** Jednostka rozmiaru pliku w `formatBytes`. */
6
+ export type KptByteUnit = 'byte' | 'kilobyte' | 'megabyte' | 'gigabyte';
7
+ /** Największa jednostka, w której `bytes` ma co najmniej 1 (podstawa 1024, jak w `kpt-file-upload`). */
8
+ export declare function byteUnitOf(bytes: number): KptByteUnit;
9
+ /**
10
+ * Rozmiar w bajtach jako napis w języku interfejsu ("12.3 MB", "12,3 MB"). `unit` wymusza
11
+ * jednostkę - postęp pobierania pisze pobrane w jednostce całości ("0,4 MB z 24 MB", nie "410 kB").
12
+ * `fixed` trzyma jedno miejsce po przecinku, więc licznik w trakcie pobierania nie skacze szerokością.
13
+ */
14
+ export declare function formatBytes(bytes: number, locale: string, unit?: KptByteUnit, fixed?: boolean): string;
package/dist/intl.js CHANGED
@@ -1,16 +1,47 @@
1
1
  /*
2
- * Pomocniki nazw dni/miesięcy wyliczane z `Intl` — sterowane bieżącym locale i18n.
2
+ * Pomocniki nazw dni/miesięcy wyliczane z `Intl` - sterowane bieżącym locale i18n.
3
3
  * Dzięki temu kalendarze (`kpt-datepicker`, `kpt-date-range`) nie trzymają
4
4
  * zaszytych tablic nazw i działają dla dowolnego języka.
5
+ *
6
+ * Daty wzorcowe powstają jako północ UTC, więc formatter też musi liczyć w UTC. Bez
7
+ * `timeZone: 'UTC'` formatuje w strefie przeglądarki, a na zachód od Greenwich północ UTC
8
+ * to jeszcze poprzedni dzień: w Nowym Jorku tydzień zaczynał się od "Sun", a styczeń
9
+ * był podpisany "December".
5
10
  */
6
- /** Krótkie nazwy dni tygodnia, zaczynając od poniedziałku (Pn…Nd). */
11
+ /** Krótkie nazwy dni tygodnia, zaczynając od poniedziałku (Pn...Nd). */
7
12
  export function weekdayNames(locale) {
8
- const fmt = new Intl.DateTimeFormat(locale, { weekday: 'short' });
13
+ const fmt = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' });
9
14
  // 2024-01-01 (UTC) to poniedziałek.
10
15
  return Array.from({ length: 7 }, (_, i) => fmt.format(new Date(Date.UTC(2024, 0, 1 + i))));
11
16
  }
12
- /** Pełne nazwy miesięcy (styczeń…grudzień / January…December). */
17
+ /** Pełne nazwy miesięcy (styczeń...grudzień / January...December). */
13
18
  export function monthNames(locale) {
14
- const fmt = new Intl.DateTimeFormat(locale, { month: 'long' });
19
+ const fmt = new Intl.DateTimeFormat(locale, { month: 'long', timeZone: 'UTC' });
15
20
  return Array.from({ length: 12 }, (_, i) => fmt.format(new Date(Date.UTC(2024, i, 1))));
16
21
  }
22
+ const BYTE_UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte'];
23
+ /** Największa jednostka, w której `bytes` ma co najmniej 1 (podstawa 1024, jak w `kpt-file-upload`). */
24
+ export function byteUnitOf(bytes) {
25
+ let i = 0;
26
+ for (let v = Math.abs(bytes); v >= 1024 && i < BYTE_UNITS.length - 1; v /= 1024)
27
+ i++;
28
+ return BYTE_UNITS[i];
29
+ }
30
+ /**
31
+ * Rozmiar w bajtach jako napis w języku interfejsu ("12.3 MB", "12,3 MB"). `unit` wymusza
32
+ * jednostkę - postęp pobierania pisze pobrane w jednostce całości ("0,4 MB z 24 MB", nie "410 kB").
33
+ * `fixed` trzyma jedno miejsce po przecinku, więc licznik w trakcie pobierania nie skacze szerokością.
34
+ */
35
+ export function formatBytes(bytes, locale, unit = byteUnitOf(bytes), fixed = false) {
36
+ const value = bytes / Math.pow(1024, BYTE_UNITS.indexOf(unit));
37
+ // Krótki zapis bajtów w `Intl` to "900 byte" (en) - zostajemy przy symbolu B jak w innych jednostkach.
38
+ if (unit === 'byte')
39
+ return `${new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(value)} B`;
40
+ return new Intl.NumberFormat(locale, {
41
+ style: 'unit',
42
+ unit,
43
+ unitDisplay: 'short',
44
+ minimumFractionDigits: fixed ? 1 : 0,
45
+ maximumFractionDigits: 1,
46
+ }).format(value);
47
+ }
@@ -1,4 +1,4 @@
1
- /** Kod języka. Otwarty string — EN/PL mają podpowiedzi, ale dozwolony dowolny. */
1
+ /** Kod języka. Otwarty string - EN/PL mają podpowiedzi, ale dozwolony dowolny. */
2
2
  export type KptLocale = 'en' | 'pl' | (string & {});
3
3
  /** Pełny słownik etykiet UI używanych przez komponenty biblioteki. */
4
4
  export interface KptMessages {
@@ -39,12 +39,15 @@ export interface KptMessages {
39
39
  };
40
40
  roadmap: {
41
41
  empty: string;
42
- /** Prefiks numeru tygodnia na osi, np. „W" w „W35". */
42
+ /** Prefiks numeru tygodnia na osi, np. "W" w "W35". */
43
43
  week: string;
44
44
  today: string;
45
45
  milestone: string;
46
+ /** Dymek przełącznika grupy; nazwą dostępną przycisku jest nazwa grupy, stan niesie aria-expanded. */
46
47
  expandGroup: string;
47
48
  collapseGroup: string;
49
+ /** Postęp w nazwie dostępnej paska. Interpolacja: {percent}. */
50
+ progress: string;
48
51
  };
49
52
  map: {
50
53
  /** Pozycja menu po kliknięciu mapy prawym przyciskiem. */
@@ -104,7 +107,7 @@ export interface KptMessages {
104
107
  search: {
105
108
  /** Podpowiedź w pustym polu. */
106
109
  placeholder: string;
107
- /** Nazwa dostępna pola — nie ma przy nim widocznej etykiety. */
110
+ /** Nazwa dostępna pola - nie ma przy nim widocznej etykiety. */
108
111
  label: string;
109
112
  /** Etykieta listy podpowiedzi dla czytnika ekranu. */
110
113
  results: string;
@@ -116,7 +119,7 @@ export interface KptMessages {
116
119
  /** Liczba znalezionych podpowiedzi dla czytnika. Interpolacja: {count}. */
117
120
  found: string;
118
121
  };
119
- /** Pola formularza „dodaj lokalizację" poza wspólnymi komunikatami. */
122
+ /** Pola formularza "dodaj lokalizację" poza wspólnymi komunikatami. */
120
123
  field: {
121
124
  invalidEmail: string;
122
125
  invalidUrl: string;
@@ -154,8 +157,12 @@ export interface KptMessages {
154
157
  dateRange: string;
155
158
  min: string;
156
159
  max: string;
157
- /** Interpolacja: {column}. Aria-label edytowalnej komórki. */
160
+ /** Interpolacja: {column}. Opis edytowalnej komórki (`aria-describedby`) - nazwą zostaje jej wartość. */
158
161
  editCell: string;
162
+ /** Interpolacja: {column}. Nazwa uchwytu przestawiania kolumny (strzałki <- ->). */
163
+ moveColumn: string;
164
+ /** Interpolacja: {column}, {position}, {count}. Ogłoszenie po przestawieniu kolumny. */
165
+ columnMoved: string;
159
166
  /** Domyślna etykieta wiersza podsumowania (input `summaryLabel` ma priorytet). */
160
167
  total: string;
161
168
  };
@@ -165,8 +172,14 @@ export interface KptMessages {
165
172
  reject: string;
166
173
  };
167
174
  fileUpload: {
168
- /** Może zawierać `<strong>…</strong>`. */
175
+ /**
176
+ * Interpolacja: {action} - w to miejsce trafia `hintAction` pogrubione. Zwykły tekst, bez HTML:
177
+ * słowniki bywają z CMS-a albo od tłumaczy, więc nie mogą wstrzykiwać znaczników.
178
+ */
169
179
  hint: string;
180
+ /** Pogrubiona część podpowiedzi ("Kliknij"). */
181
+ hintAction: string;
182
+ /** Nazwa przycisku usunięcia; komponent dokleja nazwę pliku. */
170
183
  remove: string;
171
184
  };
172
185
  chipsInput: {
@@ -198,11 +211,25 @@ export interface KptMessages {
198
211
  rangeEnd: string;
199
212
  /** Interpolacja: {date}. Nazwa dnia wewnątrz zakresu. */
200
213
  inRange: string;
201
- /** Interpolacja: {date}. Komunikat po wyborze początku — czeka na koniec. */
214
+ /** Interpolacja: {date}. Komunikat po wyborze początku - czeka na koniec. */
202
215
  pickEnd: string;
203
216
  /** Interpolacja: {start}, {end}. Komunikat po wyborze całego zakresu. */
204
217
  picked: string;
205
218
  };
219
+ chart: {
220
+ /** Nazwa wykresu bez `ariaLabel` i bez tytułu. */
221
+ label: string;
222
+ /** Podpis ukrytej tabeli z danymi wykresu. */
223
+ dataTable: string;
224
+ /** Nagłówek kolumny etykiet w tabeli danych. */
225
+ category: string;
226
+ };
227
+ clock: {
228
+ /** Nazwa segmentu godzin (spinbutton) i tarczy w etapie godzin. */
229
+ hours: string;
230
+ /** Nazwa segmentu minut (spinbutton) i tarczy w etapie minut. */
231
+ minutes: string;
232
+ };
206
233
  datepicker: {
207
234
  prevMonth: string;
208
235
  nextMonth: string;
@@ -220,6 +247,10 @@ export interface KptMessages {
220
247
  time: string;
221
248
  /** Nazwa panelu kalendarza (dialog). */
222
249
  dialog: string;
250
+ /** Litery placeholdera: rok, miesiąc, dzień (EN `YYYY`/`MM`/`DD`, PL `RRRR`/`MM`/`DD`). */
251
+ yearToken: string;
252
+ monthToken: string;
253
+ dayToken: string;
223
254
  };
224
255
  pickList: {
225
256
  available: string;
@@ -228,10 +259,14 @@ export interface KptMessages {
228
259
  moveRight: string;
229
260
  moveLeft: string;
230
261
  moveAllLeft: string;
262
+ /** Ogłoszenie po przeniesieniu. Interpolacja: {count}, {list} (nagłówek listy docelowej). */
263
+ moved: string;
231
264
  };
232
265
  orderList: {
233
266
  up: string;
234
267
  down: string;
268
+ /** Ogłoszenie po przestawieniu. Interpolacja: {position}, {total}. */
269
+ moved: string;
235
270
  };
236
271
  inputNumber: {
237
272
  decrement: string;
@@ -240,7 +275,7 @@ export interface KptMessages {
240
275
  password: {
241
276
  show: string;
242
277
  hide: string;
243
- /** Etykiety miernika siły (indeksy 0–4). */
278
+ /** Etykiety miernika siły (indeksy 0-4). */
244
279
  strength: [string, string, string, string, string];
245
280
  };
246
281
  rating: {
@@ -279,6 +314,25 @@ export interface KptMessages {
279
314
  spinner: {
280
315
  label: string;
281
316
  };
317
+ /** `kpt-loader`: nazwa pętli i wyniku (region statusu, napis w kapsule `bridge`). */
318
+ loader: {
319
+ label: string;
320
+ success: string;
321
+ error: string;
322
+ };
323
+ /** `kpt-update`: stan pobierania i etykiety akcji. */
324
+ update: {
325
+ pending: string;
326
+ downloading: string;
327
+ /** Interpolacja: {loaded}, {total} (sformatowane bajty). */
328
+ size: string;
329
+ success: string;
330
+ error: string;
331
+ update: string;
332
+ cancel: string;
333
+ open: string;
334
+ retry: string;
335
+ };
282
336
  progress: {
283
337
  /** Interpolacja: {value}. */
284
338
  percent: string;
@@ -335,7 +389,7 @@ export interface KptMessages {
335
389
  label: string;
336
390
  /** Nazwa slajdu. Interpolacja: {index}, {total}. */
337
391
  slideOf: string;
338
- /** `aria-roledescription` regionu — czytnik mówi „karuzela” zamiast „region”. */
392
+ /** `aria-roledescription` regionu - czytnik mówi "karuzela" zamiast "region". */
339
393
  roleCarousel: string;
340
394
  /** `aria-roledescription` slajdu. */
341
395
  roleSlide: string;
@@ -351,7 +405,7 @@ export interface KptMessages {
351
405
  region: string;
352
406
  };
353
407
  avatarGroup: {
354
- /** Nazwa licznika „+N”. Interpolacja: {count}. */
408
+ /** Nazwa licznika "+N". Interpolacja: {count}. */
355
409
  more: string;
356
410
  };
357
411
  meterGroup: {
@@ -383,7 +437,7 @@ export interface KptMessages {
383
437
  table: string;
384
438
  clear: string;
385
439
  html: string;
386
- /** Styl bloku „Normalny" (select). */
440
+ /** Styl bloku "Normalny" (select). */
387
441
  styleNormal: string;
388
442
  /** Interpolacja: {level}. */
389
443
  styleHeading: string;
@@ -391,7 +445,7 @@ export interface KptMessages {
391
445
  htmlSource: string;
392
446
  /** Etykieta listy podpowiedzi wzmianek (`@`). */
393
447
  mentions: string;
394
- /** Etykieta „Własny…" przy pickerze koloru. */
448
+ /** Etykieta "Własny..." przy pickerze koloru. */
395
449
  paletteCustom: string;
396
450
  /** Przycisk zatwierdzający adres w okienku linku. */
397
451
  linkApply: string;
@@ -457,7 +511,7 @@ export interface KptMessages {
457
511
  email: string;
458
512
  emailPlaceholder: string;
459
513
  password: string;
460
- /** Interpolacja: {min} — minimalna długość hasła. */
514
+ /** Interpolacja: {min} - minimalna długość hasła. */
461
515
  passwordHint: string;
462
516
  confirmPassword: string;
463
517
  remember: string;
@@ -468,7 +522,7 @@ export interface KptMessages {
468
522
  signUpSubmit: string;
469
523
  resetSubmit: string;
470
524
  orContinueWith: string;
471
- /** Interpolacja: {provider} — nazwa dostawcy (etykieta przycisku). */
525
+ /** Interpolacja: {provider} - nazwa dostawcy (etykieta przycisku). */
472
526
  continueWith: string;
473
527
  noAccount: string;
474
528
  haveAccount: string;
@@ -480,7 +534,7 @@ export interface KptMessages {
480
534
  errorMinLength: string;
481
535
  errorMismatch: string;
482
536
  errorInvalid: string;
483
- /** Treść panelu promocyjnego — zachęca do trybu przeciwnego niż bieżący. */
537
+ /** Treść panelu promocyjnego - zachęca do trybu przeciwnego niż bieżący. */
484
538
  promo: {
485
539
  signInTitle: string;
486
540
  signInText: string;
@@ -493,9 +547,9 @@ export interface KptMessages {
493
547
  /** Separator dnia. Nazwy dni tygodnia i pełne daty daje `Intl`, nie słownik. */
494
548
  today: string;
495
549
  yesterday: string;
496
- /** Interpolacja: {name} — pisze jedna osoba. */
550
+ /** Interpolacja: {name} - pisze jedna osoba. */
497
551
  typing: string;
498
- /** Interpolacja: {count} — piszą co najmniej dwie osoby. */
552
+ /** Interpolacja: {count} - piszą co najmniej dwie osoby. */
499
553
  typingMany: string;
500
554
  sending: string;
501
555
  sent: string;
@@ -504,22 +558,24 @@ export interface KptMessages {
504
558
  failed: string;
505
559
  retry: string;
506
560
  offline: string;
507
- /** Interpolacja: {count} — wiadomości czekające na wysłanie. */
561
+ /** Interpolacja: {count} - wiadomości czekające na wysłanie. */
508
562
  pending: string;
509
563
  queue: string;
510
564
  /** Interpolacja: {count}. */
511
565
  newMessages: string;
512
566
  unread: string;
513
567
  empty: string;
568
+ /** Nazwa przewijanej historii rozmowy (`role="log"`), osiągalnej z klawiatury. */
569
+ history: string;
514
570
  send: string;
515
571
  placeholder: string;
516
572
  attach: string;
517
573
  removeAttachment: string;
518
- /** Interpolacja: {author} — autor cytowanej wiadomości. */
574
+ /** Interpolacja: {author} - autor cytowanej wiadomości. */
519
575
  replyTo: string;
520
576
  cancelReply: string;
521
577
  react: string;
522
- /** Etykiety wybieraka reakcji — kolejność jak w `KPT_CHAT_REACTIONS`. */
578
+ /** Etykiety wybieraka reakcji - kolejność jak w `KPT_CHAT_REACTIONS`. */
523
579
  reactLike: string;
524
580
  reactLove: string;
525
581
  reactSmile: string;
@@ -527,9 +583,32 @@ export interface KptMessages {
527
583
  reactSad: string;
528
584
  open: string;
529
585
  close: string;
530
- /** Interpolacja: {count} — plakietka nieprzeczytanych na docku. */
586
+ /** Interpolacja: {count} - plakietka nieprzeczytanych na docku. */
531
587
  unreadBadge: string;
532
588
  };
589
+ /** Dyktowanie (kpt-speech-button i mikrofony wbudowane w pola). */
590
+ speech: {
591
+ /** Stała nazwa przycisku mikrofonu - stan niesie `aria-pressed`, nie zmiana etykiety. */
592
+ dictate: string;
593
+ /** Komunikaty regionu `aria-live`: start i koniec nasłuchu. */
594
+ listening: string;
595
+ stopped: string;
596
+ /** iOS: restart bez gestu użytkownika jest zawodny - prosimy o ponowne dotknięcie. */
597
+ tapToContinue: string;
598
+ /** Komunikaty błędów - klucze z `speechErrorMessageKey()` w `@konce-pt/speech`. */
599
+ errors: {
600
+ notAllowed: string;
601
+ serviceNotAllowed: string;
602
+ noSpeech: string;
603
+ audioCapture: string;
604
+ network: string;
605
+ languageNotSupported: string;
606
+ aborted: string;
607
+ unsupported: string;
608
+ insecureContext: string;
609
+ unknown: string;
610
+ };
611
+ };
533
612
  }
534
613
  export declare const KPT_MESSAGES_EN: KptMessages;
535
614
  export declare const KPT_MESSAGES_PL: KptMessages;
package/dist/messages.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Kontrakt tłumaczeń Koncept UI + słowniki bazowe (EN, PL).
3
3
  *
4
- * Plik jest celowo wolny od zależności frameworka — to czysty TypeScript/JSON.
4
+ * Plik jest celowo wolny od zależności frameworka - to czysty TypeScript/JSON.
5
5
  * Dzięki temu ten sam kontrakt (`KptMessages`) i te same słowniki obsługują
6
6
  * `@konce-pt/angular` (serwis na sygnałach) i `@konce-pt/react` (Context + hook).
7
7
  *
@@ -22,17 +22,17 @@ export const KPT_MESSAGES_EN = {
22
22
  },
23
23
  paginator: {
24
24
  rowsPerPage: 'Rows:',
25
- range: '{start}–{end} of {total}',
25
+ range: '{start}-{end} of {total}',
26
26
  prevPage: 'Previous page',
27
27
  nextPage: 'Next page',
28
28
  },
29
29
  select: {
30
- search: 'Search…',
30
+ search: 'Search...',
31
31
  noResults: 'No results',
32
32
  removeChip: 'Remove',
33
33
  },
34
34
  listbox: {
35
- search: 'Search…',
35
+ search: 'Search...',
36
36
  empty: 'No items',
37
37
  },
38
38
  dataView: {
@@ -49,6 +49,7 @@ export const KPT_MESSAGES_EN = {
49
49
  milestone: 'Milestone',
50
50
  expandGroup: 'Expand group',
51
51
  collapseGroup: 'Collapse group',
52
+ progress: '{percent}% complete',
52
53
  },
53
54
  map: {
54
55
  addLocation: 'Add location',
@@ -65,7 +66,7 @@ export const KPT_MESSAGES_EN = {
65
66
  cluster: 'Group of {count} locations',
66
67
  clusterItems: 'Locations in this group',
67
68
  fieldRequired: '{label} is required',
68
- lookingUpAddress: 'Looking up the address…',
69
+ lookingUpAddress: 'Looking up the address...',
69
70
  addressNotFound: 'No address found for this point',
70
71
  latitude: 'Latitude',
71
72
  longitude: 'Longitude',
@@ -93,13 +94,13 @@ export const KPT_MESSAGES_EN = {
93
94
  noPhoto: 'No photo',
94
95
  },
95
96
  search: {
96
- placeholder: 'Search for an address…',
97
+ placeholder: 'Search for an address...',
97
98
  label: 'Search for an address',
98
99
  results: 'Address suggestions',
99
100
  clear: 'Clear the search',
100
101
  noResults: 'No matching places',
101
102
  minLength: 'Type at least {count} characters',
102
- searching: 'Searching…',
103
+ searching: 'Searching...',
103
104
  found: '{count} suggestions',
104
105
  },
105
106
  field: {
@@ -120,9 +121,9 @@ export const KPT_MESSAGES_EN = {
120
121
  },
121
122
  },
122
123
  dataTable: {
123
- search: 'Search…',
124
+ search: 'Search...',
124
125
  exportCsv: 'Export CSV',
125
- loading: 'Loading…',
126
+ loading: 'Loading...',
126
127
  empty: 'No data',
127
128
  selectAll: 'Select all',
128
129
  selectRow: 'Select row',
@@ -135,6 +136,8 @@ export const KPT_MESSAGES_EN = {
135
136
  min: 'min',
136
137
  max: 'max',
137
138
  editCell: 'Edit: {column}',
139
+ moveColumn: 'Move column: {column}',
140
+ columnMoved: '{column}: position {position} of {count}',
138
141
  total: 'Total',
139
142
  },
140
143
  confirm: {
@@ -143,11 +146,12 @@ export const KPT_MESSAGES_EN = {
143
146
  reject: 'Cancel',
144
147
  },
145
148
  fileUpload: {
146
- hint: '<strong>Click</strong> or drag files here',
149
+ hint: '{action} or drag files here',
150
+ hintAction: 'Click',
147
151
  remove: 'Remove',
148
152
  },
149
153
  chipsInput: {
150
- placeholder: 'Add and press Enter…',
154
+ placeholder: 'Add and press Enter...',
151
155
  added: 'Added: {value}',
152
156
  removed: 'Removed: {value}',
153
157
  duplicate: 'Already on the list: {value}',
@@ -167,7 +171,16 @@ export const KPT_MESSAGES_EN = {
167
171
  rangeEnd: '{date}, end of range',
168
172
  inRange: '{date}, in range',
169
173
  pickEnd: 'Start: {date}. Choose the end date.',
170
- picked: 'Range: {start} – {end}',
174
+ picked: 'Range: {start} - {end}',
175
+ },
176
+ chart: {
177
+ label: 'Chart',
178
+ dataTable: 'Chart data',
179
+ category: 'Category',
180
+ },
181
+ clock: {
182
+ hours: 'Hours',
183
+ minutes: 'Minutes',
171
184
  },
172
185
  datepicker: {
173
186
  prevMonth: 'Previous month',
@@ -185,6 +198,9 @@ export const KPT_MESSAGES_EN = {
185
198
  month: 'Month',
186
199
  time: 'Time',
187
200
  dialog: 'Choose a date',
201
+ yearToken: 'YYYY',
202
+ monthToken: 'MM',
203
+ dayToken: 'DD',
188
204
  },
189
205
  pickList: {
190
206
  available: 'Available',
@@ -193,10 +209,12 @@ export const KPT_MESSAGES_EN = {
193
209
  moveRight: 'Move right',
194
210
  moveLeft: 'Move left',
195
211
  moveAllLeft: 'Move all left',
212
+ moved: 'Moved {count} to {list}',
196
213
  },
197
214
  orderList: {
198
215
  up: 'Up',
199
216
  down: 'Down',
217
+ moved: 'Moved to position {position} of {total}',
200
218
  },
201
219
  inputNumber: {
202
220
  decrement: 'Decrease',
@@ -236,6 +254,22 @@ export const KPT_MESSAGES_EN = {
236
254
  spinner: {
237
255
  label: 'Loading',
238
256
  },
257
+ loader: {
258
+ label: 'Loading',
259
+ success: 'Done',
260
+ error: 'Something went wrong',
261
+ },
262
+ update: {
263
+ pending: 'Waiting to download',
264
+ downloading: 'Downloading...',
265
+ size: '{loaded} of {total}',
266
+ success: 'Updated',
267
+ error: 'Download interrupted',
268
+ update: 'Update',
269
+ cancel: 'Cancel',
270
+ open: 'Open',
271
+ retry: 'Retry',
272
+ },
239
273
  progress: {
240
274
  percent: '{value}%',
241
275
  fraction: '{value} / {max}',
@@ -322,7 +356,7 @@ export const KPT_MESSAGES_EN = {
322
356
  linkPrompt: 'URL:',
323
357
  htmlSource: 'HTML source',
324
358
  mentions: 'Mention suggestions',
325
- paletteCustom: 'Custom…',
359
+ paletteCustom: 'Custom...',
326
360
  linkApply: 'Insert link',
327
361
  swatches: {
328
362
  black: 'Black',
@@ -358,7 +392,7 @@ export const KPT_MESSAGES_EN = {
358
392
  alignRight: 'Right',
359
393
  mergeCells: 'Merge cells',
360
394
  splitCell: 'Split cell',
361
- border: 'Border…',
395
+ border: 'Border...',
362
396
  deleteTable: 'Delete table',
363
397
  },
364
398
  border: {
@@ -368,7 +402,7 @@ export const KPT_MESSAGES_EN = {
368
402
  thin: 'Thin',
369
403
  medium: 'Medium',
370
404
  thick: 'Thick',
371
- customColor: 'Color…',
405
+ customColor: 'Color...',
372
406
  },
373
407
  },
374
408
  auth: {
@@ -412,8 +446,8 @@ export const KPT_MESSAGES_EN = {
412
446
  chat: {
413
447
  today: 'Today',
414
448
  yesterday: 'Yesterday',
415
- typing: '{name} is typing…',
416
- typingMany: '{count} people are typing…',
449
+ typing: '{name} is typing...',
450
+ typingMany: '{count} people are typing...',
417
451
  sending: 'Sending',
418
452
  sent: 'Sent',
419
453
  delivered: 'Delivered',
@@ -426,8 +460,9 @@ export const KPT_MESSAGES_EN = {
426
460
  newMessages: '{count} new messages',
427
461
  unread: 'Unread messages',
428
462
  empty: 'No messages yet',
463
+ history: 'Conversation history',
429
464
  send: 'Send',
430
- placeholder: 'Write a message…',
465
+ placeholder: 'Write a message...',
431
466
  attach: 'Attach a file',
432
467
  removeAttachment: 'Remove attachment',
433
468
  replyTo: 'Replying to {author}',
@@ -442,6 +477,24 @@ export const KPT_MESSAGES_EN = {
442
477
  close: 'Close chat',
443
478
  unreadBadge: '{count} unread messages',
444
479
  },
480
+ speech: {
481
+ dictate: 'Dictate',
482
+ listening: 'Listening...',
483
+ stopped: 'Dictation stopped',
484
+ tapToContinue: 'Tap the microphone to continue',
485
+ errors: {
486
+ notAllowed: 'Microphone access was denied. Allow it in the browser settings.',
487
+ serviceNotAllowed: 'Speech recognition is blocked in this browser.',
488
+ noSpeech: 'No speech was detected.',
489
+ audioCapture: 'No microphone was found, or another app is using it.',
490
+ network: 'Speech recognition is unavailable in this browser.',
491
+ languageNotSupported: 'This language is not supported for dictation.',
492
+ aborted: 'Dictation was interrupted.',
493
+ unsupported: 'This browser does not support dictation.',
494
+ insecureContext: 'Dictation requires a secure connection (https).',
495
+ unknown: 'Dictation failed. Try again.',
496
+ },
497
+ },
445
498
  };
446
499
  export const KPT_MESSAGES_PL = {
447
500
  common: {
@@ -455,17 +508,17 @@ export const KPT_MESSAGES_PL = {
455
508
  },
456
509
  paginator: {
457
510
  rowsPerPage: 'Wierszy:',
458
- range: '{start}–{end} z {total}',
511
+ range: '{start}-{end} z {total}',
459
512
  prevPage: 'Poprzednia strona',
460
513
  nextPage: 'Następna strona',
461
514
  },
462
515
  select: {
463
- search: 'Szukaj…',
516
+ search: 'Szukaj...',
464
517
  noResults: 'Brak wyników',
465
518
  removeChip: 'Usuń',
466
519
  },
467
520
  listbox: {
468
- search: 'Szukaj…',
521
+ search: 'Szukaj...',
469
522
  empty: 'Brak pozycji',
470
523
  },
471
524
  dataView: {
@@ -482,6 +535,7 @@ export const KPT_MESSAGES_PL = {
482
535
  milestone: 'Kamień milowy',
483
536
  expandGroup: 'Rozwiń grupę',
484
537
  collapseGroup: 'Zwiń grupę',
538
+ progress: 'ukończono {percent}%',
485
539
  },
486
540
  map: {
487
541
  addLocation: 'Dodaj lokalizację',
@@ -497,8 +551,8 @@ export const KPT_MESSAGES_PL = {
497
551
  hideCategory: 'Ukryj: {category}',
498
552
  cluster: 'Grupa {count} lokalizacji',
499
553
  clusterItems: 'Lokalizacje w tej grupie',
500
- fieldRequired: 'Pole „{label}" jest wymagane',
501
- lookingUpAddress: 'Szukam adresu…',
554
+ fieldRequired: 'Pole "{label}" jest wymagane',
555
+ lookingUpAddress: 'Szukam adresu...',
502
556
  addressNotFound: 'Nie znaleziono adresu dla tego punktu',
503
557
  latitude: 'Szerokość',
504
558
  longitude: 'Długość',
@@ -526,13 +580,13 @@ export const KPT_MESSAGES_PL = {
526
580
  noPhoto: 'Brak zdjęcia',
527
581
  },
528
582
  search: {
529
- placeholder: 'Szukaj adresu…',
583
+ placeholder: 'Szukaj adresu...',
530
584
  label: 'Szukaj adresu',
531
585
  results: 'Podpowiedzi adresów',
532
586
  clear: 'Wyczyść wyszukiwanie',
533
587
  noResults: 'Brak pasujących miejsc',
534
588
  minLength: 'Wpisz więcej znaków (minimum: {count})',
535
- searching: 'Szukam…',
589
+ searching: 'Szukam...',
536
590
  found: 'Podpowiedzi: {count}',
537
591
  },
538
592
  field: {
@@ -553,9 +607,9 @@ export const KPT_MESSAGES_PL = {
553
607
  },
554
608
  },
555
609
  dataTable: {
556
- search: 'Szukaj…',
610
+ search: 'Szukaj...',
557
611
  exportCsv: 'Eksport CSV',
558
- loading: 'Ładowanie…',
612
+ loading: 'Ładowanie...',
559
613
  empty: 'Brak danych',
560
614
  selectAll: 'Zaznacz wszystkie',
561
615
  selectRow: 'Zaznacz wiersz',
@@ -568,6 +622,8 @@ export const KPT_MESSAGES_PL = {
568
622
  min: 'min',
569
623
  max: 'max',
570
624
  editCell: 'Edytuj: {column}',
625
+ moveColumn: 'Przesuń kolumnę: {column}',
626
+ columnMoved: '{column}: pozycja {position} z {count}',
571
627
  total: 'Razem',
572
628
  },
573
629
  confirm: {
@@ -576,11 +632,12 @@ export const KPT_MESSAGES_PL = {
576
632
  reject: 'Anuluj',
577
633
  },
578
634
  fileUpload: {
579
- hint: '<strong>Kliknij</strong> lub przeciągnij pliki tutaj',
635
+ hint: '{action} lub przeciągnij pliki tutaj',
636
+ hintAction: 'Kliknij',
580
637
  remove: 'Usuń',
581
638
  },
582
639
  chipsInput: {
583
- placeholder: 'Dodaj i naciśnij Enter…',
640
+ placeholder: 'Dodaj i naciśnij Enter...',
584
641
  added: 'Dodano: {value}',
585
642
  removed: 'Usunięto: {value}',
586
643
  duplicate: 'Już jest na liście: {value}',
@@ -600,7 +657,16 @@ export const KPT_MESSAGES_PL = {
600
657
  rangeEnd: '{date}, koniec zakresu',
601
658
  inRange: '{date}, w zakresie',
602
659
  pickEnd: 'Początek: {date}. Wybierz datę końcową.',
603
- picked: 'Zakres: {start} – {end}',
660
+ picked: 'Zakres: {start} - {end}',
661
+ },
662
+ chart: {
663
+ label: 'Wykres',
664
+ dataTable: 'Dane wykresu',
665
+ category: 'Kategoria',
666
+ },
667
+ clock: {
668
+ hours: 'Godziny',
669
+ minutes: 'Minuty',
604
670
  },
605
671
  datepicker: {
606
672
  prevMonth: 'Poprzedni miesiąc',
@@ -618,6 +684,9 @@ export const KPT_MESSAGES_PL = {
618
684
  month: 'Miesiąc',
619
685
  time: 'Godzina',
620
686
  dialog: 'Wybierz datę',
687
+ yearToken: 'RRRR',
688
+ monthToken: 'MM',
689
+ dayToken: 'DD',
621
690
  },
622
691
  pickList: {
623
692
  available: 'Dostępne',
@@ -626,10 +695,12 @@ export const KPT_MESSAGES_PL = {
626
695
  moveRight: 'Przenieś w prawo',
627
696
  moveLeft: 'Przenieś w lewo',
628
697
  moveAllLeft: 'Przenieś wszystko w lewo',
698
+ moved: 'Przeniesiono {count} do: {list}',
629
699
  },
630
700
  orderList: {
631
701
  up: 'W górę',
632
702
  down: 'W dół',
703
+ moved: 'Przeniesiono na pozycję {position} z {total}',
633
704
  },
634
705
  inputNumber: {
635
706
  decrement: 'Zmniejsz',
@@ -669,6 +740,22 @@ export const KPT_MESSAGES_PL = {
669
740
  spinner: {
670
741
  label: 'Ładowanie',
671
742
  },
743
+ loader: {
744
+ label: 'Ładowanie',
745
+ success: 'Gotowe',
746
+ error: 'Coś poszło nie tak',
747
+ },
748
+ update: {
749
+ pending: 'Oczekuje na pobranie',
750
+ downloading: 'Pobieranie...',
751
+ size: '{loaded} z {total}',
752
+ success: 'Zaktualizowano',
753
+ error: 'Pobieranie przerwane',
754
+ update: 'Aktualizuj',
755
+ cancel: 'Anuluj',
756
+ open: 'Otwórz',
757
+ retry: 'Ponów',
758
+ },
672
759
  progress: {
673
760
  percent: '{value}%',
674
761
  fraction: '{value} / {max}',
@@ -755,7 +842,7 @@ export const KPT_MESSAGES_PL = {
755
842
  linkPrompt: 'Adres URL:',
756
843
  htmlSource: 'Źródło HTML',
757
844
  mentions: 'Podpowiedzi wzmianek',
758
- paletteCustom: 'Własny…',
845
+ paletteCustom: 'Własny...',
759
846
  linkApply: 'Wstaw link',
760
847
  swatches: {
761
848
  black: 'Czarny',
@@ -791,7 +878,7 @@ export const KPT_MESSAGES_PL = {
791
878
  alignRight: 'Do prawej',
792
879
  mergeCells: 'Scal komórki',
793
880
  splitCell: 'Podziel komórkę',
794
- border: 'Obramowanie…',
881
+ border: 'Obramowanie...',
795
882
  deleteTable: 'Usuń tabelę',
796
883
  },
797
884
  border: {
@@ -801,7 +888,7 @@ export const KPT_MESSAGES_PL = {
801
888
  thin: 'Cienkie',
802
889
  medium: 'Średnie',
803
890
  thick: 'Grube',
804
- customColor: 'Kolor…',
891
+ customColor: 'Kolor...',
805
892
  },
806
893
  },
807
894
  auth: {
@@ -845,8 +932,8 @@ export const KPT_MESSAGES_PL = {
845
932
  chat: {
846
933
  today: 'Dziś',
847
934
  yesterday: 'Wczoraj',
848
- typing: '{name} pisze…',
849
- typingMany: '{count} osoby piszą…',
935
+ typing: '{name} pisze...',
936
+ typingMany: '{count} osoby piszą...',
850
937
  sending: 'Wysyłanie',
851
938
  sent: 'Wysłano',
852
939
  delivered: 'Dostarczono',
@@ -859,8 +946,9 @@ export const KPT_MESSAGES_PL = {
859
946
  newMessages: '{count} nowych wiadomości',
860
947
  unread: 'Nieprzeczytane',
861
948
  empty: 'Brak wiadomości',
949
+ history: 'Historia rozmowy',
862
950
  send: 'Wyślij',
863
- placeholder: 'Napisz wiadomość…',
951
+ placeholder: 'Napisz wiadomość...',
864
952
  attach: 'Dołącz plik',
865
953
  removeAttachment: 'Usuń załącznik',
866
954
  replyTo: 'Odpowiedź do: {author}',
@@ -875,4 +963,22 @@ export const KPT_MESSAGES_PL = {
875
963
  close: 'Zamknij czat',
876
964
  unreadBadge: '{count} nieprzeczytanych wiadomości',
877
965
  },
966
+ speech: {
967
+ dictate: 'Dyktuj',
968
+ listening: 'Słucham...',
969
+ stopped: 'Dyktowanie zatrzymane',
970
+ tapToContinue: 'Dotknij mikrofonu, aby kontynuować',
971
+ errors: {
972
+ notAllowed: 'Brak dostępu do mikrofonu. Zezwól na niego w ustawieniach przeglądarki.',
973
+ serviceNotAllowed: 'Rozpoznawanie mowy jest zablokowane w tej przeglądarce.',
974
+ noSpeech: 'Nie usłyszano mowy.',
975
+ audioCapture: 'Nie znaleziono mikrofonu albo używa go inna aplikacja.',
976
+ network: 'Rozpoznawanie mowy jest niedostępne w tej przeglądarce.',
977
+ languageNotSupported: 'Ten język nie jest obsługiwany przy dyktowaniu.',
978
+ aborted: 'Dyktowanie zostało przerwane.',
979
+ unsupported: 'Ta przeglądarka nie obsługuje dyktowania.',
980
+ insecureContext: 'Dyktowanie wymaga bezpiecznego połączenia (https).',
981
+ unknown: 'Dyktowanie nie powiodło się. Spróbuj ponownie.',
982
+ },
983
+ },
878
984
  };
package/dist/translate.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Rdzeń tłumaczeń — czysty TypeScript, bez zależności od frameworka.
2
+ * Rdzeń tłumaczeń - czysty TypeScript, bez zależności od frameworka.
3
3
  *
4
4
  * Angular owija te funkcje w serwis na sygnałach (`KptI18n`), React w Context
5
5
  * i hook (`useKptI18n`). Semantyka wyszukiwania, fallbacku i interpolacji żyje
package/dist/types.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { KptLocale, KptMessages } from './messages.ts';
2
- /** Głęboko-opcjonalna wersja typu — dla nadpisań/częściowych słowników. */
2
+ /** Głęboko-opcjonalna wersja typu - dla nadpisań/częściowych słowników. */
3
3
  export type DeepPartial<T> = {
4
4
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
5
5
  };
6
- /** Konfiguracja i18n — wspólna dla portu Angulara i Reacta. */
6
+ /** Konfiguracja i18n - wspólna dla portu Angulara i Reacta. */
7
7
  export interface KptI18nConfig {
8
8
  /** Język początkowy (domyślnie 'en'). */
9
9
  locale?: KptLocale;
@@ -14,3 +14,14 @@ export interface KptI18nConfig {
14
14
  */
15
15
  messages?: Record<string, DeepPartial<KptMessages>>;
16
16
  }
17
+ /** Ścieżki liści drzewa w notacji kropkowej (`'paginator.range'`); tablice napisów są liśćmi. */
18
+ type LeafPaths<T, Prefix extends string = ''> = {
19
+ [K in keyof T & string]: T[K] extends string | readonly string[] ? `${Prefix}${K}` : LeafPaths<T[K], `${Prefix}${K}.`>;
20
+ }[keyof T & string];
21
+ /**
22
+ * Klucz tłumaczenia słownika bazowego (`'paginator.range'`, `'common.close'`...). `t()` przyjmuje go
23
+ * z podpowiedziami w edytorze, ale nadal też dowolny napis - klucze składane dynamicznie i klucze
24
+ * własnych słowników aplikacji.
25
+ */
26
+ export type KptMessageKey = LeafPaths<KptMessages>;
27
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@konce-pt/i18n",
3
- "version": "0.11.2",
4
- "description": "Translation contract and base dictionaries (EN, PL) for Koncept UI — shared by the Angular and React ports. Pure TypeScript, zero runtime dependencies.",
3
+ "version": "0.14.0",
4
+ "description": "Translation contract and base dictionaries (EN, PL) for Koncept UI - shared by the Angular and React ports. Pure TypeScript, zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "author": "konce.pt",
7
7
  "homepage": "https://ui.konce.pt/",
@@ -39,6 +39,8 @@
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -p tsconfig.build.json",
42
+ "test": "node --test \"src/**/*.test.ts\"",
43
+ "lint": "eslint .",
42
44
  "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\""
43
45
  }
44
46
  }