diff --git a/packages/calcite-components/src/utils/locale.ts b/packages/calcite-components/src/utils/locale.ts index 51e751c0853..b6b5e0f8c76 100644 --- a/packages/calcite-components/src/utils/locale.ts +++ b/packages/calcite-components/src/utils/locale.ts @@ -1,6 +1,4 @@ -import { closestElementCrossShadowBoundary, containsCrossShadowBoundary } from "./dom"; import { BigDecimal, isValidNumber, sanitizeExponentialNumberString } from "./number"; -import { createObserver } from "./observers"; export const defaultLocale = "en"; @@ -196,119 +194,6 @@ export function getDateFormatSupportedLocale(locale: string): string { } } -/** This interface is for components that need to determine locale from the lang attribute. */ -export interface LocalizedComponent { - el: HTMLElement; - - /** - * Used to store the effective locale to avoid multiple lookups. - * - * This is an internal property and should: - * - * - use the `@State` decorator - * - be initialized to "" - * - * Components should watch this prop to ensure messages are updated. - * - * @Watch ("effectiveLocale") - * effectiveLocaleChange(): void { - * updateMessages(this, this.effectiveLocale); - * } - */ - effectiveLocale: string; -} - -const connectedComponents = new Set(); - -/** - * This utility sets up internals for messages support. - * - * It needs to be called in `connectedCallback` before any logic that depends on locale - * - * @param component - */ -export function connectLocalized(component: LocalizedComponent): void { - updateEffectiveLocale(component); - - if (connectedComponents.size === 0) { - mutationObserver?.observe(document.documentElement, { - attributes: true, - attributeFilter: ["lang"], - subtree: true, - }); - } - - connectedComponents.add(component); -} - -/** - * This is only exported for components that implemented the now deprecated `locale` prop. - * - * Do not use this utils for new components. - * - * @param component - */ -export function updateEffectiveLocale(component: LocalizedComponent): void { - component.effectiveLocale = getLocale(component); -} - -/** - * This utility tears down internals for messages support. - * - * It needs to be called in `disconnectedCallback` - * - * @param component - */ -export function disconnectLocalized(component: LocalizedComponent): void { - connectedComponents.delete(component); - - if (connectedComponents.size === 0) { - mutationObserver.disconnect(); - } -} - -const mutationObserver = createObserver("mutation", (records) => { - records.forEach((record) => { - const el = record.target as HTMLElement; - - connectedComponents.forEach((component) => { - const inUnrelatedSubtree = !containsCrossShadowBoundary(el, component.el); - - if (inUnrelatedSubtree) { - return; - } - - const closestLangEl = closestElementCrossShadowBoundary(component.el, "[lang]"); - - if (!closestLangEl) { - component.effectiveLocale = defaultLocale; - return; - } - - const closestLang = closestLangEl.lang; - - component.effectiveLocale = - // user set lang="" means unknown language, so we use default - closestLangEl.hasAttribute("lang") && closestLang === "" ? defaultLocale : closestLang; - }); - }); -}); - -/** - * This util helps resolve a component's locale. - * It will also fall back on the deprecated `locale` if a component implemented this previously. - * - * @param component - */ -function getLocale(component: LocalizedComponent): string { - return ( - component.el.lang || - closestElementCrossShadowBoundary(component.el, "[lang]")?.lang || - document.documentElement.lang || - defaultLocale - ); -} - export interface NumberStringFormatOptions extends Intl.NumberFormatOptions { numberingSystem: NumberingSystem; locale: string;