@easygov/react-components 0.4.8 → 0.5.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
@@ -114,6 +114,67 @@ document.addEventListener('contextchange', (e) => {
114
114
  that receives `contextJwt` must verify its signature against core-backend's published JWKS
115
115
  before trusting a claim.
116
116
 
117
+ ### Reading the display language
118
+
119
+ The header owns the display language and publishes it the same way. It resolves from a cookie
120
+ shared across every EasyGov subdomain, then the browser language, then `'de'` — so a language
121
+ picked on the info module still applies after navigating to core or a Fachmodul:
122
+
123
+ ```tsx
124
+ import { useEasygovDisplayLanguage } from '@easygov/react-components';
125
+
126
+ function Greeting() {
127
+ const language = useEasygovDisplayLanguage(); // 'de' | 'en' | 'fr' | 'it'
128
+ return <p>{greetings[language]}</p>;
129
+ }
130
+ ```
131
+
132
+ Unlike `useEasygovHeaderContext`, this never returns a placeholder. The value needs no network
133
+ call, so it is correct on first paint and even before an `EasygovHeader` has mounted. Outside a
134
+ component, `getEasygovDisplayLanguage()` returns the same value and
135
+ `subscribeEasygovDisplayLanguage(fn)` notifies you when it changes.
136
+
137
+ The cookie is written **only** when the user picks a language in the header's switcher, never
138
+ when the browser language is auto-detected. That is deliberate: it keeps the browser language a
139
+ live default, so a user who has never made an explicit choice follows their browser even if
140
+ they change it later.
141
+
142
+ A module that has to set the language itself — a `/fr/…` route, say — calls the setter rather
143
+ than rendering a second picker:
144
+
145
+ ```ts
146
+ import { setEasygovDisplayLanguage } from '@easygov/react-components';
147
+
148
+ setEasygovDisplayLanguage('fr');
149
+ ```
150
+
151
+ That writes the same cookie the switcher writes, so there is exactly one source of truth and
152
+ every subscribed module re-renders with it.
153
+
154
+ Outside React — including `<eg-easygov-header>` — listen on the header element:
155
+
156
+ ```js
157
+ document.querySelector('eg-easygov-header')
158
+ .addEventListener('languagechange', (e) => {
159
+ const { locale } = e.detail;
160
+ });
161
+ ```
162
+
163
+ **Listen on the element, never on `window`.** The event bubbles and is `composed`, so it does
164
+ reach `window` — where it is indistinguishable from the browser's *own* `languagechange` event,
165
+ which fires when the user changes their OS language and carries no `detail`. A `window` listener
166
+ reading `e.detail.locale` throws as soon as that happens.
167
+
168
+ **A page using `<eg-easygov-header>` must not read the language through the npm hook.** That
169
+ bundle is self-contained and inlines its own copy of this library, so the hook would resolve to
170
+ a different store instance than the element is using, and the two drift apart the moment someone
171
+ picks a language. Use the event above, or `easygov.getDisplayLanguage()` on the global the bundle
172
+ defines.
173
+
174
+ **Upgrading from 0.4.x:** the `locale` prop and the `locale` attribute are gone. The header owns
175
+ the language now — read it with `useEasygovDisplayLanguage()`, set it with
176
+ `setEasygovDisplayLanguage()`.
177
+
117
178
  ## License
118
179
 
119
180
  MIT
@@ -496,8 +496,17 @@ declare function useEasygovAuthStatus(): AuthStatus;
496
496
  * against core-backend's published JWKS.
497
497
  */
498
498
  declare function useEasygovHeaderContext(): EasygovHeaderContext;
499
+ /**
500
+ * The current DisplayLanguage (EGOV-1451). Resolved as: the `eg-display-language` cookie shared
501
+ * across every EasyGov subdomain, else the browser language, else "de". The cookie is written only
502
+ * on an explicit pick in the header's switcher, so the browser-language default stays live until
503
+ * the user overrides it.
504
+ *
505
+ * Unlike useEasygovHeaderContext this never returns a placeholder: the value needs no network
506
+ * call, so a module can read it before any header has mounted.
507
+ */
508
+ declare function useEasygovDisplayLanguage(): Locale;
499
509
  interface EasygovHeaderProps {
500
- readonly locale?: Locale;
501
510
  readonly onLanguageChange?: (locale: Locale) => void;
502
511
  readonly onNavigate?: (path: string) => void;
503
512
  /**
@@ -524,7 +533,7 @@ interface EasygovHeaderProps {
524
533
  readonly onContextChange?: (contextJwt: string, claims: HeaderContextClaims) => void;
525
534
  readonly onLogout?: () => void;
526
535
  }
527
- declare function EasygovHeader({ locale: localeProp, onLanguageChange, onNavigate, onContextChange, onLogout, }: EasygovHeaderProps): React__default.JSX.Element;
536
+ declare function EasygovHeader({ onLanguageChange, onNavigate, onContextChange, onLogout, }: EasygovHeaderProps): React__default.JSX.Element;
528
537
  interface RequireSessionProps {
529
538
  readonly children: React__default.ReactNode;
530
539
  readonly fallback?: React__default.ReactNode;
@@ -538,4 +547,30 @@ interface RequireCustomerAccountProps {
538
547
  }
539
548
  declare function RequireCustomerAccount({ children, onNavigate, }: RequireCustomerAccountProps): React__default.JSX.Element;
540
549
 
541
- export { type AuthStatus, BrandBase, BrandEasygov, BrandFacebook, BrandKdk, BrandLinkedin, type BrandProps, BrandSeg, BrandSgv, BrandSsv, BrandSwiss, BrandXing, BrandYoutube, Button, type ButtonProps, type DesktopSpan, Dropdown, DropdownChip, DropdownChipsOverflow, type DropdownChipsOverflowProps, DropdownChipsTrigger, type DropdownChipsTriggerProps, DropdownCollection, DropdownEmpty, DropdownGroup, DropdownGroupLabel, DropdownHelperText, type DropdownHelperTextProps, DropdownInput, DropdownItem, type DropdownItemProps, DropdownItemText, DropdownLabel, type DropdownLabelProps, DropdownList, DropdownPopup, type DropdownPopupProps, DropdownSeparator, DropdownToggle, DropdownTrigger, type DropdownTriggerProps, DropdownValue, EasygovFooter, EasygovHeader, type EasygovHeaderContext, type EasygovHeaderProps, type EasygovSession, Grid, GridItem, type GridItemProps, type GridProps, type AccountVerificationStatus as HeaderContextAccountVerificationStatus, type HeaderContextClaims, type IndividualAccount as HeaderContextIndividualAccount, type ManagementRole as HeaderContextManagementRole, type ManagementRoleStatus as HeaderContextManagementRoleStatus, type ManagementRoleType as HeaderContextManagementRoleType, type OrganizationAccount as HeaderContextOrganizationAccount, type ProcessStatus as HeaderContextProcessStatus, type UserProfile as HeaderContextUserProfile, Heading, type HeadingProps, Input, type InputProps, type Locale, type MobileSpan, NavigationMenu, NavigationMenuAnchor, type NavigationMenuAnchorProps, NavigationMenuContent, type NavigationMenuContentProps, NavigationMenuItem, type NavigationMenuItemProps, NavigationMenuLink, type NavigationMenuLinkProps, NavigationMenuList, type NavigationMenuListProps, type NavigationMenuProps, NavigationMenuTrigger, type NavigationMenuTriggerProps, RequireCustomerAccount, type RequireCustomerAccountProps, RequireSession, type RequireSessionProps, Select, SelectContent, type SelectContentProps, SelectGroup, SelectGroupLabel, type SelectGroupLabelProps, SelectHelperText, type SelectHelperTextProps, SelectItem, type SelectItemProps, SelectLabel, type SelectLabelProps, SelectSeparator, type SelectSeparatorProps, SelectTrigger, type SelectTriggerProps, type SelectedCustomerAccount, type SelectedProcess, type SessionUser, type TabletSpan, Text, TextLink, type TextLinkProps, type TextProps, buttonVariants, getAuthStatus, headingVariants, requireSession, textLinkVariants, textVariants, useEasygovAuthStatus, useEasygovHeaderContext, useEasygovSession, useRequireCustomerAccount };
550
+ /**
551
+ * The current DisplayLanguage. Safe to call at any time, including before any EasygovHeader has
552
+ * mounted — it resolves cookie -> browser language -> "de" with no I/O. Identity is a plain
553
+ * string, so it is a valid `useSyncExternalStore` snapshot.
554
+ *
555
+ * Caching begins only once listeners are installed, i.e. after the first
556
+ * `subscribeEasygovDisplayLanguage`. Until then every call re-resolves, because nothing would
557
+ * invalidate a cache: a module that imports this getter and polls it without ever subscribing —
558
+ * exactly the second-bundle-instance topology the sync event exists for — would otherwise be
559
+ * pinned to the first value it ever read, for the life of the page. Installing from here is not an
560
+ * option: React calls this during render, which must stay side-effect free.
561
+ */
562
+ declare function getEasygovDisplayLanguage(): Locale;
563
+ /**
564
+ * Sets the DisplayLanguage as an explicit user choice: writes the cookie, updates this store, and
565
+ * announces it to sibling bundle instances. Called by the header's language switcher, and
566
+ * available to modules that must set the language themselves (e.g. a deep link into a /fr/… route)
567
+ * — going through the same path is what keeps one source of truth.
568
+ *
569
+ * The cookie is written ONLY here, never when the browser language is auto-detected. That is what
570
+ * keeps "default is the browser language" true: baking a detected language into the cookie on
571
+ * first page view would freeze it for a user who later changes their browser.
572
+ */
573
+ declare function setEasygovDisplayLanguage(locale: Locale): void;
574
+ declare function subscribeEasygovDisplayLanguage(listener: () => void): () => void;
575
+
576
+ export { type AuthStatus, BrandBase, BrandEasygov, BrandFacebook, BrandKdk, BrandLinkedin, type BrandProps, BrandSeg, BrandSgv, BrandSsv, BrandSwiss, BrandXing, BrandYoutube, Button, type ButtonProps, type DesktopSpan, Dropdown, DropdownChip, DropdownChipsOverflow, type DropdownChipsOverflowProps, DropdownChipsTrigger, type DropdownChipsTriggerProps, DropdownCollection, DropdownEmpty, DropdownGroup, DropdownGroupLabel, DropdownHelperText, type DropdownHelperTextProps, DropdownInput, DropdownItem, type DropdownItemProps, DropdownItemText, DropdownLabel, type DropdownLabelProps, DropdownList, DropdownPopup, type DropdownPopupProps, DropdownSeparator, DropdownToggle, DropdownTrigger, type DropdownTriggerProps, DropdownValue, EasygovFooter, EasygovHeader, type EasygovHeaderContext, type EasygovHeaderProps, type EasygovSession, Grid, GridItem, type GridItemProps, type GridProps, type AccountVerificationStatus as HeaderContextAccountVerificationStatus, type HeaderContextClaims, type IndividualAccount as HeaderContextIndividualAccount, type ManagementRole as HeaderContextManagementRole, type ManagementRoleStatus as HeaderContextManagementRoleStatus, type ManagementRoleType as HeaderContextManagementRoleType, type OrganizationAccount as HeaderContextOrganizationAccount, type ProcessStatus as HeaderContextProcessStatus, type UserProfile as HeaderContextUserProfile, Heading, type HeadingProps, Input, type InputProps, type Locale, type MobileSpan, NavigationMenu, NavigationMenuAnchor, type NavigationMenuAnchorProps, NavigationMenuContent, type NavigationMenuContentProps, NavigationMenuItem, type NavigationMenuItemProps, NavigationMenuLink, type NavigationMenuLinkProps, NavigationMenuList, type NavigationMenuListProps, type NavigationMenuProps, NavigationMenuTrigger, type NavigationMenuTriggerProps, RequireCustomerAccount, type RequireCustomerAccountProps, RequireSession, type RequireSessionProps, Select, SelectContent, type SelectContentProps, SelectGroup, SelectGroupLabel, type SelectGroupLabelProps, SelectHelperText, type SelectHelperTextProps, SelectItem, type SelectItemProps, SelectLabel, type SelectLabelProps, SelectSeparator, type SelectSeparatorProps, SelectTrigger, type SelectTriggerProps, type SelectedCustomerAccount, type SelectedProcess, type SessionUser, type TabletSpan, Text, TextLink, type TextLinkProps, type TextProps, buttonVariants, getAuthStatus, getEasygovDisplayLanguage, headingVariants, requireSession, setEasygovDisplayLanguage, subscribeEasygovDisplayLanguage, textLinkVariants, textVariants, useEasygovAuthStatus, useEasygovDisplayLanguage, useEasygovHeaderContext, useEasygovSession, useRequireCustomerAccount };