@eifi1/ui-kit 0.28.0 → 0.28.1
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 +3 -3
- package/dist/chart.d.ts +1 -1
- package/dist/components/amount-input.d.ts +1 -1
- package/dist/components/button-group.d.ts +1 -1
- package/dist/components/calculator.d.ts +1 -1
- package/dist/components/confirm-dialog.d.ts +1 -1
- package/dist/components/copy-button.d.ts +1 -1
- package/dist/components/danger-confirm.d.ts +1 -1
- package/dist/components/facing-pair.d.ts +1 -1
- package/dist/components/file-button.d.ts +1 -1
- package/dist/components/file-dropzone.d.ts +1 -1
- package/dist/components/form-actions.d.ts +1 -1
- package/dist/components/iban-input.d.ts +1 -1
- package/dist/components/language-select.d.ts +1 -1
- package/dist/components/legal-page.d.ts +9 -3
- package/dist/components/legal-page.js +24 -5
- package/dist/components/legal-page.js.map +1 -1
- package/dist/components/legal.d.ts +1 -1
- package/dist/components/legal.js +49 -5
- package/dist/components/legal.js.map +1 -1
- package/dist/components/money-field.d.ts +1 -1
- package/dist/components/number-field.d.ts +1 -1
- package/dist/components/number-input.d.ts +1 -1
- package/dist/components/numpad-sheet.d.ts +1 -1
- package/dist/components/phone-input.d.ts +1 -1
- package/dist/components/series-chart.d.ts +1 -1
- package/dist/components/settings-fields.d.ts +1 -1
- package/dist/components/share-card.d.ts +1 -1
- package/dist/components/text-link.d.ts +1 -1
- package/dist/components/time-input.d.ts +1 -1
- package/dist/components/ui.d.ts +1 -1
- package/dist/feedback/feedback-attachment.d.ts +1 -1
- package/dist/feedback/feedback-context.d.ts +1 -1
- package/dist/feedback/feedback-crash.d.ts +1 -1
- package/dist/feedback/feedback-dialog.d.ts +1 -1
- package/dist/feedback/feedback-inbox.d.ts +1 -1
- package/dist/feedback/feedback-labels.d.ts +1 -1
- package/dist/feedback/feedback-menu.d.ts +1 -1
- package/dist/feedback/feedback-record.d.ts +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +1 -1
- package/dist/feedback/feedback-submit.d.ts +1 -1
- package/dist/feedback/feedback-swipe.d.ts +1 -1
- package/dist/feedback/feedback-table.d.ts +1 -1
- package/dist/feedback/feedback-thread.d.ts +1 -1
- package/dist/feedback.d.ts +1 -1
- package/dist/hooks/use-file-drop.d.ts +1 -1
- package/dist/i18n/defaults.d.ts +1 -1
- package/dist/i18n/german.d.ts +1 -1
- package/dist/i18n/german.js +8 -0
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +1 -1
- package/dist/i18n/languages.d.ts +1 -1
- package/dist/i18n/locales/de-CH.d.ts +1 -1
- package/dist/i18n/locales/en.d.ts +1 -1
- package/dist/i18n/locales/es.d.ts +1 -1
- package/dist/i18n/locales/es.js +11 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +1 -1
- package/dist/i18n/locales/fr.js +8 -0
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +1 -1
- package/dist/i18n/locales/hu.js +11 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +1 -1
- package/dist/i18n/locales/it.js +9 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +1 -1
- package/dist/i18n/locales/zh.js +9 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.d.ts +1 -1
- package/dist/i18n/review.js +9 -7
- package/dist/i18n/review.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/{kit-labels-SBN0biPl.d.ts → kit-labels-Du0uHBq4.d.ts} +41 -5
- package/dist/rhf/fields.d.ts +1 -1
- package/dist/rhf/form.d.ts +1 -1
- package/dist/rhf.d.ts +1 -1
- package/dist/shell/app-shell.d.ts +1 -1
- package/dist/shell/top-bar-brand.d.ts +1 -1
- package/dist/shell.d.ts +1 -1
- package/dist/wizard/stepper-nav.d.ts +1 -1
- package/dist/wizard.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/legal-page.tsx +35 -0
- package/src/components/legal.tsx +93 -7
- package/src/i18n/german.ts +10 -0
- package/src/i18n/locales/es.ts +13 -3
- package/src/i18n/locales/fr.ts +10 -0
- package/src/i18n/locales/hu.ts +13 -3
- package/src/i18n/locales/it.ts +11 -1
- package/src/i18n/locales/zh.ts +11 -1
- package/src/i18n/review.ts +7 -6
- package/src/index.ts +10 -1
package/src/components/legal.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
2
|
+
import type { MouseEvent, ReactNode } from "react";
|
|
3
3
|
|
|
4
4
|
import { useKitLabels } from "../i18n/kit-labels";
|
|
5
5
|
import type { LabelOverride } from "../i18n/kit-labels";
|
|
@@ -66,6 +66,14 @@ export interface LegalOperator {
|
|
|
66
66
|
country: string;
|
|
67
67
|
/** The contact address the imprint and the privacy policy print. */
|
|
68
68
|
email: string;
|
|
69
|
+
/**
|
|
70
|
+
* The language whose version of the legal texts is BINDING ("de-CH"), a BCP 47 code
|
|
71
|
+
* (0.28.1, Marcel 2026-10-05). The lawyer reviews that one; the others are translations
|
|
72
|
+
* for convenience. With it, {@link LegalPage} shows a note on every page read in
|
|
73
|
+
* another language, and the terms' `language` section says which version prevails.
|
|
74
|
+
* Only the language subtag counts: "de-CH" and "de" are the same language here.
|
|
75
|
+
*/
|
|
76
|
+
bindingLanguage?: string;
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
/**
|
|
@@ -78,10 +86,42 @@ export interface LegalOperator {
|
|
|
78
86
|
*/
|
|
79
87
|
export type LegalOperatorText = Readonly<Record<keyof LegalOperator, string>>;
|
|
80
88
|
|
|
89
|
+
/** The language subtag of a BCP 47 code, lower-cased: "de-CH" → "de". */
|
|
90
|
+
export function baseLanguage(code: string): string {
|
|
91
|
+
return code.split(/[-_]/)[0]!.toLowerCase();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const languageNamers = new Map<string, Intl.DisplayNames | null>();
|
|
95
|
+
|
|
96
|
+
/** The name of a language in `locale` — "Deutsch", "German", "allemand", "德语" — from its
|
|
97
|
+
* language subtag, so "de-CH" is plain "German", not "Swiss High German". The code itself
|
|
98
|
+
* when the runtime cannot name it. */
|
|
99
|
+
function languageName(code: string, locale: string): string {
|
|
100
|
+
let namer = languageNamers.get(locale);
|
|
101
|
+
if (namer === undefined) {
|
|
102
|
+
try {
|
|
103
|
+
namer = new Intl.DisplayNames([locale], { type: "language" });
|
|
104
|
+
} catch {
|
|
105
|
+
namer = null;
|
|
106
|
+
}
|
|
107
|
+
languageNamers.set(locale, namer);
|
|
108
|
+
}
|
|
109
|
+
const base = baseLanguage(code);
|
|
110
|
+
try {
|
|
111
|
+
return namer?.of(base) ?? base;
|
|
112
|
+
} catch {
|
|
113
|
+
return base;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
81
117
|
/** @internal The operator as the texts read it: its country named in `locale` (English
|
|
82
118
|
* without one — `countryName`'s rule, so an app that set no locale reads English). */
|
|
83
119
|
export function legalOperatorText(operator: LegalOperator, locale: string = "en"): LegalOperatorText {
|
|
84
|
-
return {
|
|
120
|
+
return {
|
|
121
|
+
...operator,
|
|
122
|
+
country: countryName(operator.country, locale),
|
|
123
|
+
bindingLanguage: operator.bindingLanguage ? languageName(operator.bindingLanguage, locale) : "",
|
|
124
|
+
};
|
|
85
125
|
}
|
|
86
126
|
|
|
87
127
|
// ── Labels ────────────────────────────────────────────────────────────────────
|
|
@@ -142,6 +182,16 @@ export interface LegalLabels {
|
|
|
142
182
|
beta: string;
|
|
143
183
|
privacy: string;
|
|
144
184
|
};
|
|
185
|
+
/**
|
|
186
|
+
* 0.28.1: on a page read in another language than the operator's `bindingLanguage` —
|
|
187
|
+
* `note` under the title, `show` on the button that switches to the binding version
|
|
188
|
+
* (when the app passes `onShowBindingLanguage`). `o.bindingLanguage` is the binding
|
|
189
|
+
* language's NAME in the reader's language ("German", "allemand").
|
|
190
|
+
*/
|
|
191
|
+
translation: {
|
|
192
|
+
note: (o: LegalOperatorText) => string;
|
|
193
|
+
show: (o: LegalOperatorText) => string;
|
|
194
|
+
};
|
|
145
195
|
/** The kit's sections (§4.3), by page and section key. */
|
|
146
196
|
sections: {
|
|
147
197
|
impressum: {
|
|
@@ -164,6 +214,8 @@ export interface LegalLabels {
|
|
|
164
214
|
warranty: LegalTextSectionLabels;
|
|
165
215
|
liability: LegalTextSectionLabels;
|
|
166
216
|
changes: LegalTextSectionLabels;
|
|
217
|
+
/** 0.28.1: which language's version prevails — `o.bindingLanguage`, named. */
|
|
218
|
+
language: LegalOperatorSectionLabels;
|
|
167
219
|
/** The place of jurisdiction is the operator's `{city} ({region}), {country}`. */
|
|
168
220
|
law: LegalOperatorSectionLabels;
|
|
169
221
|
};
|
|
@@ -189,6 +241,11 @@ export const DEFAULT_LEGAL_LABELS: LegalLabels = {
|
|
|
189
241
|
privacy:
|
|
190
242
|
"Closed beta. The legal wording below has not been reviewed by a lawyer yet and will be before a public launch. The technical descriptions — what is stored, where, and who can read it — describe what the software actually does today, and are meant to be checked against it.",
|
|
191
243
|
},
|
|
244
|
+
translation: {
|
|
245
|
+
note: (o) =>
|
|
246
|
+
`This is a translation for your convenience. The ${o.bindingLanguage} version is binding.`,
|
|
247
|
+
show: (o) => `Show the ${o.bindingLanguage} version`,
|
|
248
|
+
},
|
|
192
249
|
sections: {
|
|
193
250
|
impressum: {
|
|
194
251
|
operator: {
|
|
@@ -243,6 +300,11 @@ export const DEFAULT_LEGAL_LABELS: LegalLabels = {
|
|
|
243
300
|
title: "Changes to these terms",
|
|
244
301
|
body: "These terms may be updated as the service evolves. Material changes will be announced by email or in the app; continued use after a change means you accept it.",
|
|
245
302
|
},
|
|
303
|
+
language: {
|
|
304
|
+
title: "Language",
|
|
305
|
+
body: (o) =>
|
|
306
|
+
`These terms are written in ${o.bindingLanguage}. Translations into other languages are provided for convenience only; where a translation differs, the ${o.bindingLanguage} version prevails.`,
|
|
307
|
+
},
|
|
246
308
|
law: {
|
|
247
309
|
title: "Governing law",
|
|
248
310
|
body: (o) =>
|
|
@@ -375,6 +437,9 @@ export interface LegalLinksProps {
|
|
|
375
437
|
* links, so in a plain container — Kurvenschmiede's account-menu `<li>` — they ran
|
|
376
438
|
* together as "ImpressumDatenschutzerklärungNutz…" and overflowed). Default true. */
|
|
377
439
|
nav?: boolean;
|
|
440
|
+
/** Called on a click on any of the links, before it navigates — an account menu closes
|
|
441
|
+
* itself here (0.28.1, keksdose: it had to catch the click on a wrapping `<div>`). */
|
|
442
|
+
onLinkClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
378
443
|
labels?: LabelOverride<LegalLabels>;
|
|
379
444
|
className?: string;
|
|
380
445
|
}
|
|
@@ -396,12 +461,19 @@ function defaultLinks(labels: LegalLabels): LegalLink[] {
|
|
|
396
461
|
* already hears three links, and "middle dot" between them is noise. They are flex items
|
|
397
462
|
* of the row like the links, so the row's gap spaces them evenly.
|
|
398
463
|
*/
|
|
399
|
-
export function LegalLinks({
|
|
464
|
+
export function LegalLinks({
|
|
465
|
+
links,
|
|
466
|
+
currentHref,
|
|
467
|
+
nav = true,
|
|
468
|
+
onLinkClick,
|
|
469
|
+
labels: labelsProp,
|
|
470
|
+
className,
|
|
471
|
+
}: LegalLinksProps) {
|
|
400
472
|
const labels = useLegalLabels(labelsProp);
|
|
401
473
|
const shown = links ?? defaultLinks(labels);
|
|
402
474
|
const items = shown.flatMap((link, i) => [
|
|
403
475
|
...(i > 0 ? [<span key={`sep-${link.href}`} aria-hidden="true">·</span>] : []),
|
|
404
|
-
<TextLink key={link.href} href={link.href} tone="muted" current={link.href === currentHref}>
|
|
476
|
+
<TextLink key={link.href} href={link.href} tone="muted" current={link.href === currentHref} onClick={onLinkClick}>
|
|
405
477
|
{link.label}
|
|
406
478
|
</TextLink>,
|
|
407
479
|
]);
|
|
@@ -425,6 +497,14 @@ export interface LegalFooterProps {
|
|
|
425
497
|
/** Marks that link `aria-current="page"`. {@link LegalPage}'s default footer passes
|
|
426
498
|
* its own page. */
|
|
427
499
|
currentHref?: string;
|
|
500
|
+
/**
|
|
501
|
+
* Default true: the footer is a `<footer>`. `false` draws a `<div>` — for a host that is
|
|
502
|
+
* a footer already: `AuthLayout`'s `footer` slot is one, and HTML forbids a footer inside
|
|
503
|
+
* a footer (0.28.1, kastlan). On an `AuthLayout` page the usual choice is simpler still:
|
|
504
|
+
* `footer={<LegalLinks nav={false} />}` with `footerLabel` set to the kit's `navLabel`
|
|
505
|
+
* ({@link useLegalLabels}).
|
|
506
|
+
*/
|
|
507
|
+
landmark?: boolean;
|
|
428
508
|
className?: string;
|
|
429
509
|
labels?: LabelOverride<LegalLabels>;
|
|
430
510
|
}
|
|
@@ -440,9 +520,10 @@ export interface LegalFooterProps {
|
|
|
440
520
|
* only. Its palette classes (`border-slate-200 bg-white dark:…`) became the surface and
|
|
441
521
|
* border tokens, so it follows the theme like the rest of the kit.
|
|
442
522
|
*/
|
|
443
|
-
export function LegalFooter({ children, links, currentHref, className, labels }: LegalFooterProps) {
|
|
523
|
+
export function LegalFooter({ children, links, currentHref, landmark = true, className, labels }: LegalFooterProps) {
|
|
524
|
+
const Root = landmark ? "footer" : "div";
|
|
444
525
|
return (
|
|
445
|
-
<
|
|
526
|
+
<Root className={cn("border-t border-[var(--border)] bg-[var(--bg-surface)]", className)}>
|
|
446
527
|
<div className="mx-auto max-w-5xl px-4 py-8 text-sm text-[var(--text-muted)]">
|
|
447
528
|
<LegalLinks
|
|
448
529
|
links={links}
|
|
@@ -452,7 +533,7 @@ export function LegalFooter({ children, links, currentHref, className, labels }:
|
|
|
452
533
|
/>
|
|
453
534
|
{children !== undefined && children !== null && <p className="mt-4 text-center">{children}</p>}
|
|
454
535
|
</div>
|
|
455
|
-
</
|
|
536
|
+
</Root>
|
|
456
537
|
);
|
|
457
538
|
}
|
|
458
539
|
|
|
@@ -526,6 +607,9 @@ export interface LegalLayoutProps {
|
|
|
526
607
|
* than the others (its technical sections describe running code).
|
|
527
608
|
*/
|
|
528
609
|
notice?: ReactNode;
|
|
610
|
+
/** 0.28.1: under the title, before the notice — {@link LegalPage}'s note that this
|
|
611
|
+
* page is a translation and which language is binding. */
|
|
612
|
+
translationNote?: ReactNode;
|
|
529
613
|
/** The sections — {@link LegalSection}s. */
|
|
530
614
|
children: ReactNode;
|
|
531
615
|
/** The three pages, linked at the end of the column with the current one marked.
|
|
@@ -543,6 +627,7 @@ export function LegalLayout({
|
|
|
543
627
|
title,
|
|
544
628
|
back,
|
|
545
629
|
notice,
|
|
630
|
+
translationNote,
|
|
546
631
|
children,
|
|
547
632
|
links,
|
|
548
633
|
currentHref,
|
|
@@ -554,6 +639,7 @@ export function LegalLayout({
|
|
|
554
639
|
<article className={cn("mx-auto w-full max-w-3xl px-4 py-12", className)}>
|
|
555
640
|
{back !== undefined && <div className="mb-4 text-sm">{back}</div>}
|
|
556
641
|
<Heading className="text-3xl font-bold tracking-tight break-words text-[var(--text-primary)]">{title}</Heading>
|
|
642
|
+
{translationNote !== undefined && translationNote !== null && <div className="mt-3">{translationNote}</div>}
|
|
557
643
|
{notice !== undefined && notice !== null && (
|
|
558
644
|
<AlertBanner tone="warning" role="note" className="mt-4">
|
|
559
645
|
{notice}
|
package/src/i18n/german.ts
CHANGED
|
@@ -779,6 +779,11 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
779
779
|
privacy:
|
|
780
780
|
"Geschlossene Beta. Die rechtlichen Formulierungen unten sind noch nicht anwaltlich geprüft; das geschieht vor einem öffentlichen Start. Die technischen Angaben — was gespeichert wird, wo, und wer es lesen kann — beschreiben, was die Software heute tatsächlich tut, und sind ausdrücklich dazu da, daran überprüft zu werden.",
|
|
781
781
|
},
|
|
782
|
+
translation: {
|
|
783
|
+
note: (o) =>
|
|
784
|
+
`Dies ist eine Übersetzung zu Ihrer Information. Massgebend ist die Fassung auf ${o.bindingLanguage}.`,
|
|
785
|
+
show: (o) => `Fassung auf ${o.bindingLanguage} anzeigen`,
|
|
786
|
+
},
|
|
782
787
|
sections: {
|
|
783
788
|
impressum: {
|
|
784
789
|
operator: {
|
|
@@ -833,6 +838,11 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
833
838
|
title: "Änderungen dieser Bedingungen",
|
|
834
839
|
body: "Diese Bedingungen können im Zuge der Weiterentwicklung des Dienstes angepasst werden. Wesentliche Änderungen werden per E-Mail oder in der App angekündigt; die weitere Nutzung nach einer Änderung gilt als Zustimmung.",
|
|
835
840
|
},
|
|
841
|
+
language: {
|
|
842
|
+
title: "Sprache",
|
|
843
|
+
body: (o) =>
|
|
844
|
+
`Diese Bedingungen sind auf ${o.bindingLanguage} verfasst. Übersetzungen in andere Sprachen dienen nur der Information; weicht eine Übersetzung ab, ist die Fassung auf ${o.bindingLanguage} massgebend.`,
|
|
845
|
+
},
|
|
836
846
|
law: {
|
|
837
847
|
title: "Anwendbares Recht",
|
|
838
848
|
body: (o) =>
|
package/src/i18n/locales/es.ts
CHANGED
|
@@ -757,7 +757,12 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
757
757
|
notice: {
|
|
758
758
|
beta: "Beta cerrada. Estos textos aún no han sido revisados por un abogado y lo serán antes de un lanzamiento público.",
|
|
759
759
|
privacy:
|
|
760
|
-
"Beta cerrada. La redacción jurídica que sigue aún no ha sido revisada por un abogado y lo será antes de un lanzamiento público. Las descripciones técnicas —qué se guarda, dónde y quién puede leerlo— describen lo que el software hace realmente hoy y
|
|
760
|
+
"Beta cerrada. La redacción jurídica que sigue aún no ha sido revisada por un abogado y lo será antes de un lanzamiento público. Las descripciones técnicas —qué se guarda, dónde y quién puede leerlo— describen lo que el software hace realmente hoy y deben poder contrastarse con él.",
|
|
761
|
+
},
|
|
762
|
+
translation: {
|
|
763
|
+
note: (o) =>
|
|
764
|
+
`Esta es una traducción ofrecida para su comodidad. La versión vinculante es la versión en ${o.bindingLanguage}.`,
|
|
765
|
+
show: (o) => `Ver la versión en ${o.bindingLanguage}`,
|
|
761
766
|
},
|
|
762
767
|
sections: {
|
|
763
768
|
impressum: {
|
|
@@ -783,12 +788,12 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
783
788
|
},
|
|
784
789
|
legal_basis: {
|
|
785
790
|
title: "Base jurídica",
|
|
786
|
-
body: "Como el responsable
|
|
791
|
+
body: "Como el responsable reside en Suiza, el tratamiento se rige por la Ley Federal suiza de Protección de Datos (LPD). Cuando le sea aplicable el Reglamento General de Protección de Datos de la UE (RGPD), nos basamos en la ejecución de un contrato para prestar el servicio (art. 6.1.b RGPD) y en nuestro interés legítimo en operarlo y protegerlo (art. 6.1.f RGPD).",
|
|
787
792
|
},
|
|
788
793
|
browser: {
|
|
789
794
|
title: "Qué guarda su navegador",
|
|
790
795
|
lead: "Ninguna cookie. La aplicación guarda lo siguiente en el almacenamiento de su navegador:",
|
|
791
|
-
tail: "Nada de ello se usa para
|
|
796
|
+
tail: "Nada de ello se usa para rastrearle. Las entradas pendientes de envío se nos envían en cuanto sea posible; todo lo demás permanece en su dispositivo. Todo ello desaparece cuando borra los datos del sitio, y al cerrar sesión se eliminan los tokens de inicio de sesión.",
|
|
792
797
|
},
|
|
793
798
|
rights: {
|
|
794
799
|
title: "Sus derechos",
|
|
@@ -813,6 +818,11 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
813
818
|
title: "Cambios en estas condiciones",
|
|
814
819
|
body: "Estas condiciones pueden actualizarse a medida que evolucione el servicio. Los cambios importantes se anunciarán por correo electrónico o en la aplicación; si sigue usando el servicio después de un cambio, lo acepta.",
|
|
815
820
|
},
|
|
821
|
+
language: {
|
|
822
|
+
title: "Idioma",
|
|
823
|
+
body: (o) =>
|
|
824
|
+
`Estas condiciones están redactadas en ${o.bindingLanguage}. Las traducciones a otros idiomas se ofrecen solo por comodidad; en caso de discrepancia, prevalece la versión en ${o.bindingLanguage}.`,
|
|
825
|
+
},
|
|
816
826
|
law: {
|
|
817
827
|
title: "Legislación aplicable",
|
|
818
828
|
body: (o) =>
|
package/src/i18n/locales/fr.ts
CHANGED
|
@@ -777,6 +777,11 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
777
777
|
privacy:
|
|
778
778
|
"Bêta fermée. Les formulations juridiques ci-dessous n’ont pas encore été relues par un avocat\u202f; cela sera fait avant un lancement public. Les descriptions techniques — ce qui est stocké, où, et qui peut le lire — décrivent ce que fait réellement le logiciel aujourd’hui et sont faites pour être vérifiées par rapport à lui.",
|
|
779
779
|
},
|
|
780
|
+
translation: {
|
|
781
|
+
note: (o) =>
|
|
782
|
+
`Ceci est une traduction fournie pour votre commodité. Seule la version en ${o.bindingLanguage} fait foi.`,
|
|
783
|
+
show: (o) => `Afficher la version en ${o.bindingLanguage}`,
|
|
784
|
+
},
|
|
780
785
|
sections: {
|
|
781
786
|
impressum: {
|
|
782
787
|
operator: {
|
|
@@ -831,6 +836,11 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
831
836
|
title: "Modifications des présentes conditions",
|
|
832
837
|
body: "Ces conditions peuvent être mises à jour au fil de l’évolution du service. Les modifications importantes seront annoncées par e-mail ou dans l’app\u202f; continuer à utiliser le service après une modification vaut acceptation.",
|
|
833
838
|
},
|
|
839
|
+
language: {
|
|
840
|
+
title: "Langue",
|
|
841
|
+
body: (o) =>
|
|
842
|
+
`Les présentes conditions sont rédigées en ${o.bindingLanguage}. Les traductions dans d’autres langues sont fournies à titre indicatif uniquement\u202f; en cas de divergence, la version en ${o.bindingLanguage} prévaut.`,
|
|
843
|
+
},
|
|
834
844
|
law: {
|
|
835
845
|
title: "Droit applicable",
|
|
836
846
|
body: (o) =>
|
package/src/i18n/locales/hu.ts
CHANGED
|
@@ -761,12 +761,17 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
761
761
|
// The accusative ending is glued to the link, as Italian glues its article: "a
|
|
762
762
|
// Felhasználási feltételeket és az Adatvédelmi tájékoztatót". Nothing is added around
|
|
763
763
|
// a placeholder, and the articles fit these two titles (a F…, az A…).
|
|
764
|
-
accept: "Elfogadom a {terms}
|
|
764
|
+
accept: "Elfogadom a következőket: {terms} és {privacy}",
|
|
765
765
|
notice: {
|
|
766
766
|
beta: "Zárt béta. Ezeket a szövegeket ügyvéd még nem ellenőrizte; erre a nyilvános indulás előtt sor kerül.",
|
|
767
767
|
privacy:
|
|
768
768
|
"Zárt béta. Az alábbi jogi szövegezést ügyvéd még nem ellenőrizte; erre a nyilvános indulás előtt sor kerül. A műszaki leírások – mit tárolunk, hol és ki olvashatja – azt írják le, amit a szoftver ma ténylegesen tesz, és arra valók, hogy a szoftverrel össze lehessen vetni őket.",
|
|
769
769
|
},
|
|
770
|
+
translation: {
|
|
771
|
+
note: (o) =>
|
|
772
|
+
`Ez a szöveg tájékoztató jellegű fordítás; az irányadó változat nyelve: ${o.bindingLanguage}.`,
|
|
773
|
+
show: (o) => `Megjelenítés ezen a nyelven: ${o.bindingLanguage}`,
|
|
774
|
+
},
|
|
770
775
|
sections: {
|
|
771
776
|
impressum: {
|
|
772
777
|
operator: {
|
|
@@ -791,11 +796,11 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
791
796
|
},
|
|
792
797
|
legal_basis: {
|
|
793
798
|
title: "Jogalap",
|
|
794
|
-
body: "Mivel az üzemeltető
|
|
799
|
+
body: "Mivel az üzemeltető lakóhelye Svájcban van, az adatkezelésre a svájci szövetségi adatvédelmi törvény (DSG/FADP) az irányadó. Ha Önre az EU általános adatvédelmi rendelete (GDPR) vonatkozik, a szolgáltatás nyújtására irányuló szerződés teljesítésére (GDPR 6. cikk (1) b) pont) és a szolgáltatás működtetéséhez és védelméhez fűződő jogos érdekünkre (GDPR 6. cikk (1) f) pont) támaszkodunk.",
|
|
795
800
|
},
|
|
796
801
|
browser: {
|
|
797
802
|
title: "Mit tárol az Ön böngészője",
|
|
798
|
-
lead: "Nincsenek sütik. Az alkalmazás a következőket tárolja
|
|
803
|
+
lead: "Nincsenek sütik. Az alkalmazás a következőket tárolja az Ön böngészőjének tárhelyén:",
|
|
799
804
|
tail: "Egyiket sem használjuk az Ön követésére. A küldésre váró bejegyzéseket a böngésző elküldi nekünk, amint lehetséges; minden más az Ön eszközén marad. Mindez eltűnik, amikor törli a webhely adatait, kijelentkezéskor pedig a bejelentkezési tokenek törlődnek.",
|
|
800
805
|
},
|
|
801
806
|
rights: {
|
|
@@ -821,6 +826,11 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
821
826
|
title: "A feltételek módosítása",
|
|
822
827
|
body: "Ezek a feltételek a szolgáltatás fejlődésével módosulhatnak. A lényeges változásokat e-mailben vagy az alkalmazásban jelentjük be; aki a változás után tovább használja a szolgáltatást, elfogadja azt.",
|
|
823
828
|
},
|
|
829
|
+
language: {
|
|
830
|
+
title: "Nyelv",
|
|
831
|
+
body: (o) =>
|
|
832
|
+
`Ezek a feltételek ${o.bindingLanguage} nyelven készültek. A más nyelvű fordítások csak tájékoztató jellegűek; eltérés esetén az eredeti, ${o.bindingLanguage} nyelvű változat az irányadó.`,
|
|
833
|
+
},
|
|
824
834
|
law: {
|
|
825
835
|
title: "Irányadó jog",
|
|
826
836
|
body: (o) =>
|
package/src/i18n/locales/it.ts
CHANGED
|
@@ -764,6 +764,11 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
764
764
|
privacy:
|
|
765
765
|
"Beta chiusa. Le formulazioni legali qui sotto non sono ancora state verificate da un avvocato; lo saranno prima di un lancio pubblico. Le descrizioni tecniche — cosa viene memorizzato, dove e chi può leggerlo — descrivono ciò che il software fa davvero oggi e sono pensate per essere verificate rispetto a esso.",
|
|
766
766
|
},
|
|
767
|
+
translation: {
|
|
768
|
+
note: (o) =>
|
|
769
|
+
`Questa è una traduzione fornita per Sua comodità. Fa fede la versione in ${o.bindingLanguage}.`,
|
|
770
|
+
show: (o) => `Mostra la versione in ${o.bindingLanguage}`,
|
|
771
|
+
},
|
|
767
772
|
sections: {
|
|
768
773
|
impressum: {
|
|
769
774
|
operator: {
|
|
@@ -790,7 +795,7 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
790
795
|
},
|
|
791
796
|
legal_basis: {
|
|
792
797
|
title: "Base giuridica",
|
|
793
|
-
body: "Poiché il gestore
|
|
798
|
+
body: "Poiché il gestore risiede in Svizzera, il trattamento è disciplinato dalla Legge federale svizzera sulla protezione dei dati (LPD). Dove il Regolamento generale sulla protezione dei dati dell’UE (GDPR) si applica a Lei, ci basiamo sull’esecuzione di un contratto per fornire il servizio (art. 6, par. 1, lett. b GDPR) e sul nostro legittimo interesse a gestirlo e proteggerlo (art. 6, par. 1, lett. f GDPR).",
|
|
794
799
|
},
|
|
795
800
|
browser: {
|
|
796
801
|
title: "Che cosa salva il Suo browser",
|
|
@@ -820,6 +825,11 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
820
825
|
title: "Modifiche a queste condizioni",
|
|
821
826
|
body: "Queste condizioni possono essere aggiornate con l’evoluzione del servizio. Le modifiche sostanziali saranno annunciate via email o nell’app; l’uso continuato dopo una modifica ne implica l’accettazione.",
|
|
822
827
|
},
|
|
828
|
+
language: {
|
|
829
|
+
title: "Lingua",
|
|
830
|
+
body: (o) =>
|
|
831
|
+
`Le presenti condizioni sono redatte in ${o.bindingLanguage}. Le traduzioni in altre lingue sono fornite solo per comodità; in caso di divergenza prevale la versione in ${o.bindingLanguage}.`,
|
|
832
|
+
},
|
|
823
833
|
law: {
|
|
824
834
|
title: "Legge applicabile",
|
|
825
835
|
body: (o) =>
|
package/src/i18n/locales/zh.ts
CHANGED
|
@@ -736,12 +736,17 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
736
736
|
},
|
|
737
737
|
backHome: "返回首页",
|
|
738
738
|
// Book-title marks around the two documents, outside the links.
|
|
739
|
-
accept: "
|
|
739
|
+
accept: "我已阅读并同意《{terms}》和《{privacy}》",
|
|
740
740
|
notice: {
|
|
741
741
|
beta: "封闭测试阶段。这些文本尚未经律师审阅,将在公开发布之前完成审阅。",
|
|
742
742
|
privacy:
|
|
743
743
|
"封闭测试阶段。以下法律措辞尚未经律师审阅,将在公开发布之前完成审阅。其中的技术说明——存储了什么、存储在哪里以及谁可以读取——描述的是软件目前的实际行为,旨在供人对照软件加以核实。",
|
|
744
744
|
},
|
|
745
|
+
translation: {
|
|
746
|
+
note: (o) =>
|
|
747
|
+
`本页为方便阅读而提供的译文,以${o.bindingLanguage}版本为准。`,
|
|
748
|
+
show: (o) => `查看${o.bindingLanguage}版本`,
|
|
749
|
+
},
|
|
745
750
|
sections: {
|
|
746
751
|
impressum: {
|
|
747
752
|
operator: {
|
|
@@ -796,6 +801,11 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
796
801
|
title: "条款变更",
|
|
797
802
|
body: "本条款可能会随着服务的发展而更新。重大变更将通过电子邮件或在应用程序中公布;变更后继续使用本服务即表示您接受变更。",
|
|
798
803
|
},
|
|
804
|
+
language: {
|
|
805
|
+
title: "语言",
|
|
806
|
+
body: (o) =>
|
|
807
|
+
`本条款以${o.bindingLanguage}撰写。其他语言的译文仅供参考;如译文与原文不一致,以${o.bindingLanguage}版本为准。`,
|
|
808
|
+
},
|
|
799
809
|
law: {
|
|
800
810
|
title: "适用法律",
|
|
801
811
|
body: (o) =>
|
package/src/i18n/review.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { legalOperatorText } from "../components/legal";
|
|
1
2
|
import type { LegalOperator, LegalOperatorText } from "../components/legal";
|
|
2
|
-
import { countryName } from "../lib/countries";
|
|
3
3
|
import type { UiKitLabels } from "./kit-labels";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -40,7 +40,7 @@ import type { UiKitLabels } from "./kit-labels";
|
|
|
40
40
|
*/
|
|
41
41
|
export function kitLabelStrings(labels: UiKitLabels, options: KitLabelStringsOptions = {}): Record<string, string> {
|
|
42
42
|
const out: Record<string, string> = {};
|
|
43
|
-
const operator = options.operator &&
|
|
43
|
+
const operator = options.operator && legalOperatorText(options.operator, options.locale);
|
|
44
44
|
const walk = (node: unknown, path: string) => {
|
|
45
45
|
if (typeof node === "string") {
|
|
46
46
|
out[path] = node;
|
|
@@ -76,10 +76,6 @@ export interface KitLabelStringsOptions {
|
|
|
76
76
|
locale?: string;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function operatorText(operator: LegalOperator, locale = "en"): LegalOperatorText {
|
|
80
|
-
return { ...operator, country: countryName(operator.country, locale) };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
79
|
function render(label: (...args: unknown[]) => unknown, args: readonly unknown[]): string {
|
|
84
80
|
try {
|
|
85
81
|
return String(label(...args));
|
|
@@ -112,6 +108,7 @@ const LEGAL_OPERATOR_SAMPLE: LegalOperatorText = Object.freeze({
|
|
|
112
108
|
region: "{{region}}",
|
|
113
109
|
country: "{{country}}",
|
|
114
110
|
email: "{{email}}",
|
|
111
|
+
bindingLanguage: "{{bindingLanguage}}",
|
|
115
112
|
});
|
|
116
113
|
const operatorSample = [[LEGAL_OPERATOR_SAMPLE]] as const;
|
|
117
114
|
|
|
@@ -293,4 +290,8 @@ export const KIT_LABEL_SAMPLES: Readonly<Record<string, readonly (readonly unkno
|
|
|
293
290
|
"legal.sections.privacy.controller.body": operatorSample,
|
|
294
291
|
"legal.sections.privacy.contact.body": operatorSample,
|
|
295
292
|
"legal.sections.terms.law.body": operatorSample,
|
|
293
|
+
// 0.28.1: the binding language, named in the reader's language.
|
|
294
|
+
"legal.sections.terms.language.body": operatorSample,
|
|
295
|
+
"legal.translation.note": operatorSample,
|
|
296
|
+
"legal.translation.show": operatorSample,
|
|
296
297
|
};
|
package/src/index.ts
CHANGED
|
@@ -462,7 +462,16 @@ export type {
|
|
|
462
462
|
// The legal pages' shell (0.19, H10): Imprint, Privacy Policy, Terms in every app.
|
|
463
463
|
// 0.28 (docs/legal-harmonization.md): the shared wording, the page frame, the kit's
|
|
464
464
|
// sections, the public footer and the terms checkbox.
|
|
465
|
-
export {
|
|
465
|
+
export {
|
|
466
|
+
LegalLayout,
|
|
467
|
+
LegalSection,
|
|
468
|
+
LegalLinks,
|
|
469
|
+
LegalFooter,
|
|
470
|
+
DEFAULT_LEGAL_LABELS,
|
|
471
|
+
LEGAL_HREFS,
|
|
472
|
+
legalOperatorText,
|
|
473
|
+
useLegalLabels,
|
|
474
|
+
} from "./components/legal";
|
|
466
475
|
export type {
|
|
467
476
|
LegalLabels,
|
|
468
477
|
LegalLink,
|