bruh 2.0.0-beta.3 → 2.0.0-beta.5
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/browser.mjs +56 -34
- package/dist/browser.mjs.map +1 -1
- package/dist/components/aside-toc.mjs +13 -12
- package/dist/components/aside-toc.mjs.map +1 -1
- package/dist/components/intl/date-time.mjs +1 -3
- package/dist/components/intl/date-time.mjs.map +1 -1
- package/dist/components/intl/display-name.mjs +1 -3
- package/dist/components/intl/display-name.mjs.map +1 -1
- package/dist/components/intl/language-picker.mjs +21 -22
- package/dist/components/intl/language-picker.mjs.map +1 -1
- package/dist/components/intl/list.mjs +1 -3
- package/dist/components/intl/list.mjs.map +1 -1
- package/dist/components/intl/number.mjs +1 -3
- package/dist/components/intl/number.mjs.map +1 -1
- package/dist/components/intl/plural.mjs +2 -4
- package/dist/components/intl/plural.mjs.map +1 -1
- package/dist/components/intl/utils.mjs +5 -5
- package/dist/components/intl/utils.mjs.map +1 -1
- package/dist/components/misc.mjs +18 -0
- package/dist/components/misc.mjs.map +1 -0
- package/dist/reactive.mjs +264 -132
- package/dist/reactive.mjs.map +1 -1
- package/dist/types/components/misc.d.mts +35 -0
- package/dist/types/dom/index.browser.d.mts +2 -3
- package/dist/types/dom/index.browser.test-d.d.mts +1 -0
- package/dist/types/reactive/index.d.mts +71 -47
- package/dist/types/utils/index.d.mts +25 -4
- package/dist/utils.mjs +57 -12
- package/dist/utils.mjs.map +1 -1
- package/package.json +5 -1
|
@@ -29,7 +29,6 @@ class BruhDisplayName extends BruhCustomElementBase {
|
|
|
29
29
|
constructor() {
|
|
30
30
|
super();
|
|
31
31
|
this.#locales = r(
|
|
32
|
-
[this.bruh.attributes.locales, userLanguages],
|
|
33
32
|
() => parseLocales([
|
|
34
33
|
...this.bruh.attributes.locales.value ?? [],
|
|
35
34
|
...userLanguages.value
|
|
@@ -44,12 +43,11 @@ class BruhDisplayName extends BruhCustomElementBase {
|
|
|
44
43
|
() => mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || void 0])
|
|
45
44
|
);
|
|
46
45
|
this.#formatter = r(
|
|
47
|
-
[this.#locales, this.#options],
|
|
48
46
|
() => attempt(
|
|
49
47
|
() => new Intl.DisplayNames(this.#locales.value, this.#options.value)
|
|
50
48
|
)
|
|
51
49
|
);
|
|
52
|
-
this.#formatted = r(
|
|
50
|
+
this.#formatted = r(() => {
|
|
53
51
|
const formatter = this.#formatter.value;
|
|
54
52
|
const code = this.bruh.attributes.code.value;
|
|
55
53
|
if (!formatter || !code)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-name.mjs","sources":["../../../src/components/intl/display-name.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, languageDisplayName, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n localeMatcher: \"locale-matcher\",\n style: \"format-style\",\n type: \"type\",\n languageDisplay: \"language-display\"\n} as const\n\ntype BruhDisplayNameAttributes = {\n \"code\"?: string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.DisplayNamesOptions[\"localeMatcher\"],\n \"format-style\"?: Intl.DisplayNamesOptions[\"style\"],\n \"type\"?: Intl.DisplayNamesOptions[\"type\"],\n \"language-display\"?: Intl.DisplayNamesOptions[\"languageDisplay\"]\n}\n\nexport class BruhDisplayName extends BruhCustomElementBase<BruhDisplayNameAttributes> {\n static observedAttributes = [\n \"code\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ] as const\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r(
|
|
1
|
+
{"version":3,"file":"display-name.mjs","sources":["../../../src/components/intl/display-name.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, languageDisplayName, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n localeMatcher: \"locale-matcher\",\n style: \"format-style\",\n type: \"type\",\n languageDisplay: \"language-display\"\n} as const\n\ntype BruhDisplayNameAttributes = {\n \"code\"?: string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.DisplayNamesOptions[\"localeMatcher\"],\n \"format-style\"?: Intl.DisplayNamesOptions[\"style\"],\n \"type\"?: Intl.DisplayNamesOptions[\"type\"],\n \"language-display\"?: Intl.DisplayNamesOptions[\"languageDisplay\"]\n}\n\nexport class BruhDisplayName extends BruhCustomElementBase<BruhDisplayNameAttributes> {\n static observedAttributes = [\n \"code\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ] as const\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r(() =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.DisplayNamesOptions>\n )\n\n this.#formatter = r(() =>\n attempt(() =>\n new Intl.DisplayNames(this.#locales.value, this.#options.value as any)\n )\n )\n\n this.#formatted = r(() => {\n const formatter = this.#formatter.value\n const code = this.bruh.attributes.code.value\n if (!formatter || !code)\n return\n\n const { locale, type } = formatter.resolvedOptions()\n const direction = inferDirection(locale)\n\n const value =\n type === \"language\"\n ? languageDisplayName(formatter, code)\n : attempt(() => formatter.of(code)) ?? code\n\n return <bdi lang={locale} dir={direction}>{value}</bdi> as HTMLElement\n })\n }\n\n mountedCallback() {\n const children = bruhChildrenToNodes([this.#formatted])\n this.replaceChildren(...children)\n }\n}\n\ncustomElements.define(\"bruh-display-name\", BruhDisplayName)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-display-name\": BruhDisplayName\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-display-name\": {\n \"code\": string,\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.DisplayNamesOptions[\"localeMatcher\"],\n \"format-style\"?: Intl.DisplayNamesOptions[\"style\"],\n \"type\": Intl.DisplayNamesOptions[\"type\"],\n \"language-display\"?: Intl.DisplayNamesOptions[\"languageDisplay\"]\n }\n }\n}\n"],"names":[],"mappings":";;;;;;;AAQA,MAAM,iBAAoB,GAAA;AAAA,EACxB,aAAe,EAAA,gBAAA;AAAA,EACf,KAAO,EAAA,cAAA;AAAA,EACP,IAAM,EAAA,MAAA;AAAA,EACN,eAAiB,EAAA;AACnB,CAAA;AAWO,MAAM,wBAAwB,qBAAiD,CAAA;AAAA,EACpF,OAAO,kBAAqB,GAAA;AAAA,IAC1B,MAAA;AAAA,IACA,SAAA;AAAA,IACA,GAAG,MAAO,CAAA,MAAA,CAAO,iBAAiB;AAAA,GACpC;AAAA,EAEA,OAAO,IAAO,GAAA;AAAA,IACZ,eAAiB,EAAA;AAAA,MACf,OAAS,EAAA;AAAA;AACX,GACF;AAAA,EAEA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EAEA,WAAc,GAAA;AACZ,IAAM,KAAA,EAAA;AAEN,IAAA,IAAA,CAAK,QAAW,GAAA,CAAA;AAAA,MAAE,MAChB,YAAa,CAAA;AAAA,QACX,GAAG,IAAK,CAAA,IAAA,CAAK,UAAW,CAAA,OAAA,CAAQ,SAAS,EAAC;AAAA,QAC1C,GAAG,aAAc,CAAA;AAAA,OAClB;AAAA,KACH;AAEA,IAAA,MAAM,yBAA4B,GAAA,SAAA;AAAA,MAAU,iBAAA;AAAA,MAC1C,CAAC,CAAC,MAAA,EAAQ,SAAS,CAAA,KAAM,CAAC,MAAA,EAAQ,IAAK,CAAA,IAAA,CAAK,UAAW,CAAA,SAAS,CAAC;AAAA,KACnE;AACA,IAAA,IAAA,CAAK,QAAW,GAAA,CAAA;AAAA,MAAE,MAAA,CAAO,OAAO,yBAAyB,CAAA;AAAA,MAAG,MAC1D,SAAA,CAAU,yBAA2B,EAAA,CAAC,CAAC,MAAA,EAAQ,SAAS,CAAA,KAAM,CAAC,MAAA,EAAQ,SAAU,CAAA,KAAA,IAAS,MAAS,CAAC;AAAA,KACtG;AAEA,IAAA,IAAA,CAAK,UAAa,GAAA,CAAA;AAAA,MAAE,MAClB,OAAA;AAAA,QAAQ,MACN,IAAI,IAAK,CAAA,YAAA,CAAa,KAAK,QAAS,CAAA,KAAA,EAAO,IAAK,CAAA,QAAA,CAAS,KAAY;AAAA;AACvE,KACF;AAEA,IAAK,IAAA,CAAA,UAAA,GAAa,EAAE,MAAM;AACxB,MAAM,MAAA,SAAA,GAAY,KAAK,UAAW,CAAA,KAAA;AAClC,MAAA,MAAM,IAAO,GAAA,IAAA,CAAK,IAAK,CAAA,UAAA,CAAW,IAAK,CAAA,KAAA;AACvC,MAAI,IAAA,CAAC,aAAa,CAAC,IAAA;AACjB,QAAA;AAEF,MAAA,MAAM,EAAE,MAAA,EAAQ,IAAK,EAAA,GAAI,UAAU,eAAgB,EAAA;AACnD,MAAM,MAAA,SAAA,GAAY,eAAe,MAAM,CAAA;AAEvC,MAAA,MAAM,KACJ,GAAA,IAAA,KAAS,UACL,GAAA,mBAAA,CAAoB,SAAW,EAAA,IAAI,CACnC,GAAA,OAAA,CAAQ,MAAM,SAAA,CAAU,EAAG,CAAA,IAAI,CAAC,CAAK,IAAA,IAAA;AAE3C,MAAA,2BAAQ,KAAI,EAAA,EAAA,IAAA,EAAM,MAAQ,EAAA,GAAA,EAAK,WAAY,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,KAClD,CAAA;AAAA;AACH,EAEA,eAAkB,GAAA;AAChB,IAAA,MAAM,QAAW,GAAA,mBAAA,CAAoB,CAAC,IAAA,CAAK,UAAU,CAAC,CAAA;AACtD,IAAK,IAAA,CAAA,eAAA,CAAgB,GAAG,QAAQ,CAAA;AAAA;AAEpC;AAEA,cAAe,CAAA,MAAA,CAAO,qBAAqB,eAAe,CAAA;;;;"}
|
|
@@ -5,14 +5,31 @@ import { BruhCustomElementBase } from '../custom-elements.mjs';
|
|
|
5
5
|
import { userLanguages, parseLocales, languagePickerLanguages, inferDirection, bestAvailableLocales, languageDisplayName } from './utils.mjs';
|
|
6
6
|
|
|
7
7
|
const userLanguageDisplayNames = r(
|
|
8
|
-
[userLanguages],
|
|
9
8
|
() => new Intl.DisplayNames(userLanguages.value, { type: "language" })
|
|
10
9
|
);
|
|
10
|
+
const makeOptionElement = ({ native, current }) => {
|
|
11
|
+
const currentElement = /* @__PURE__ */ jsx("bdi", { lang: current.language, dir: current.direction, children: current.name });
|
|
12
|
+
let friendly;
|
|
13
|
+
if (native.name === void 0 || native.name === current.name)
|
|
14
|
+
friendly = currentElement;
|
|
15
|
+
else {
|
|
16
|
+
const nativeElement = /* @__PURE__ */ jsx("bdi", { lang: native.language, dir: native.direction, children: native.name });
|
|
17
|
+
friendly = /* @__PURE__ */ jsx(Fragment, { children: [
|
|
18
|
+
nativeElement,
|
|
19
|
+
" — ",
|
|
20
|
+
currentElement
|
|
21
|
+
] });
|
|
22
|
+
}
|
|
23
|
+
const isSelected = r(() => native.language === userLanguages.value[0] + "" || void 0);
|
|
24
|
+
const directionOverride = native.name && native.direction !== current.direction ? native.direction : void 0;
|
|
25
|
+
const option = /* @__PURE__ */ jsx("option", { value: native.language, selected: isSelected, dir: directionOverride, children: friendly });
|
|
26
|
+
return option;
|
|
27
|
+
};
|
|
11
28
|
const SelectLanguage = ({
|
|
12
29
|
languages,
|
|
13
30
|
name = "language"
|
|
14
31
|
}) => {
|
|
15
|
-
const options = r(
|
|
32
|
+
const options = r(() => {
|
|
16
33
|
const currentLanguage = userLanguageDisplayNames.value.resolvedOptions().locale;
|
|
17
34
|
const currentDirection = inferDirection(currentLanguage);
|
|
18
35
|
const { matches, alsoAvailable } = bestAvailableLocales(languages.value, userLanguages.value);
|
|
@@ -41,25 +58,7 @@ const SelectLanguage = ({
|
|
|
41
58
|
})
|
|
42
59
|
};
|
|
43
60
|
});
|
|
44
|
-
const selectOptions = r(
|
|
45
|
-
const makeOptionElement = ({ native, current }) => {
|
|
46
|
-
const currentElement = /* @__PURE__ */ jsx("bdi", { lang: current.language, dir: current.direction, children: current.name });
|
|
47
|
-
let friendly;
|
|
48
|
-
if (native.name === void 0 || native.name === current.name)
|
|
49
|
-
friendly = currentElement;
|
|
50
|
-
else {
|
|
51
|
-
const nativeElement = /* @__PURE__ */ jsx("bdi", { lang: native.language, dir: native.direction, children: native.name });
|
|
52
|
-
friendly = /* @__PURE__ */ jsx(Fragment, { children: [
|
|
53
|
-
nativeElement,
|
|
54
|
-
" — ",
|
|
55
|
-
currentElement
|
|
56
|
-
] });
|
|
57
|
-
}
|
|
58
|
-
const isSelected = r([userLanguages], () => native.language === userLanguages.value[0] + "" || void 0);
|
|
59
|
-
const directionOverride = native.name && native.direction !== current.direction ? native.direction : void 0;
|
|
60
|
-
const option = /* @__PURE__ */ jsx("option", { value: native.language, selected: isSelected, dir: directionOverride, children: friendly });
|
|
61
|
-
return option;
|
|
62
|
-
};
|
|
61
|
+
const selectOptions = r(() => {
|
|
63
62
|
const matches = options.value.matches.map(makeOptionElement);
|
|
64
63
|
const alsoAvailable = options.value.alsoAvailable.map(makeOptionElement);
|
|
65
64
|
if (matches.length && alsoAvailable.length)
|
|
@@ -77,7 +76,7 @@ class BruhLanguagePicker extends BruhCustomElementBase {
|
|
|
77
76
|
languages: spaceSeparated
|
|
78
77
|
}
|
|
79
78
|
};
|
|
80
|
-
#languages = r(
|
|
79
|
+
#languages = r(() => parseLocales(this.bruh.attributes.languages.value));
|
|
81
80
|
#select;
|
|
82
81
|
constructor() {
|
|
83
82
|
super();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language-picker.mjs","sources":["../../../src/components/intl/language-picker.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport type { BruhChild } from \"bruh/browser\"\nimport { r, type
|
|
1
|
+
{"version":3,"file":"language-picker.mjs","sources":["../../../src/components/intl/language-picker.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport type { BruhChild } from \"bruh/browser\"\nimport { r, type Reactive } from \"../../reactive/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, languageDisplayName, bestAvailableLocales, parseLocales, userLanguages, languagePickerLanguages, type InputLocale } from \"./utils.mts\"\n\nconst userLanguageDisplayNames = r(() =>\n new Intl.DisplayNames(userLanguages.value, { type: \"language\" })\n)\n\ntype Option = {\n native: {\n name: string | undefined,\n language: string,\n direction: \"ltr\" | \"rtl\" | undefined\n },\n current: {\n name: string,\n language: string,\n direction: \"ltr\" | \"rtl\" | undefined\n }\n}\n\nconst makeOptionElement = ({ native, current }: Option) => {\n const currentElement = <bdi lang={current.language} dir={current.direction}>{current.name}</bdi> as HTMLElement\n\n let friendly: BruhChild\n if (native.name === undefined || native.name === current.name)\n friendly = currentElement\n else {\n const nativeElement = <bdi lang={native.language} dir={native.direction}>{native.name}</bdi> as HTMLElement\n friendly = <>{nativeElement} — {currentElement}</>\n }\n\n const isSelected = r(() => native.language === userLanguages.value[0] + \"\" || undefined)\n\n const directionOverride =\n native.name && native.direction !== current.direction\n ? native.direction\n : undefined\n\n const option: HTMLOptionElement =\n <option value={native.language} selected={isSelected} dir={directionOverride}>\n {friendly}\n </option>\n\n return option\n}\n\nconst SelectLanguage = (\n {\n languages,\n name = \"language\"\n }: {\n languages: Reactive<ReadonlyArray<InputLocale>>,\n name?: string\n }\n) => {\n const options = r(() => {\n const currentLanguage = userLanguageDisplayNames.value.resolvedOptions().locale\n const currentDirection = inferDirection(currentLanguage)\n\n const { matches, alsoAvailable } = bestAvailableLocales(languages.value, userLanguages.value)\n\n const makeOption = (language: Intl.Locale): Option => {\n const nativeNameSupported = Intl.DisplayNames.supportedLocalesOf(language).length > 0\n return {\n native: {\n name:\n nativeNameSupported\n ? languageDisplayName(new Intl.DisplayNames(language, { type: \"language\" }), language)\n : undefined,\n language: language + \"\",\n direction: inferDirection(language)\n },\n current: {\n name: languageDisplayName(userLanguageDisplayNames.value, language),\n language: currentLanguage,\n direction: currentDirection\n }\n }\n }\n\n const { compare } = new Intl.Collator(userLanguages.value, { usage: \"sort\" })\n\n return {\n matches: matches.map(makeOption),\n alsoAvailable: alsoAvailable.map(makeOption)\n .sort((a, b) => {\n const aName = a.native.name ?? a.current.name\n const bName = b.native.name ?? b.current.name\n return compare(aName, bName)\n })\n }\n })\n\n const selectOptions = r(() => {\n const matches = options.value.matches.map(makeOptionElement)\n const alsoAvailable = options.value.alsoAvailable.map(makeOptionElement)\n\n if (matches.length && alsoAvailable.length)\n return [...matches, <hr /> as HTMLHRElement, ...alsoAvailable]\n else\n return [...matches, ...alsoAvailable]\n })\n\n const select =\n <select name={name}>\n {selectOptions}\n </select>\n\n return select\n}\n\ntype BruhLanguagePickerAttributes = {\n \"languages\": ReadonlyArray<Intl.Locale>\n}\n\nexport class BruhLanguagePicker extends BruhCustomElementBase<BruhLanguagePickerAttributes> {\n static observedAttributes = [\"languages\"]\n\n static bruh = {\n parseAttributes: {\n languages: spaceSeparated\n }\n }\n\n #languages = r(() => parseLocales(this.bruh.attributes.languages.value))\n\n #select\n\n constructor() {\n super()\n\n this.#select = <SelectLanguage languages={this.#languages} />\n this.#select.addEventListener(\"change\", () => {\n languagePickerLanguages.value = parseLocales([this.#select.value])\n localStorage.setItem(\n \"bruh-language-picker-languages\",\n JSON.stringify(\n languagePickerLanguages.value\n .map(language => language + \"\")\n )\n )\n })\n }\n\n mountedCallback() {\n this.replaceChildren(this.#select)\n }\n}\n\ncustomElements.define(\"bruh-language-picker\", BruhLanguagePicker)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-language-picker\": BruhLanguagePicker\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-language-picker\": {\n /**\n * Space separated list of locales\n */\n \"languages\": string\n }\n }\n}\n"],"names":["jsxs"],"mappings":"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"}
|
|
@@ -28,7 +28,6 @@ class BruhList extends BruhCustomElementBase {
|
|
|
28
28
|
constructor() {
|
|
29
29
|
super();
|
|
30
30
|
this.#locales = r(
|
|
31
|
-
[this.bruh.attributes.locales, userLanguages],
|
|
32
31
|
() => parseLocales([
|
|
33
32
|
...this.bruh.attributes.locales.value ?? [],
|
|
34
33
|
...userLanguages.value
|
|
@@ -43,14 +42,13 @@ class BruhList extends BruhCustomElementBase {
|
|
|
43
42
|
() => mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || void 0])
|
|
44
43
|
);
|
|
45
44
|
this.#formatter = r(
|
|
46
|
-
[this.#locales, this.#options],
|
|
47
45
|
() => attempt(() => new Intl.ListFormat(this.#locales.value, this.#options.value)) ?? new Intl.ListFormat(this.#locales.value)
|
|
48
46
|
);
|
|
49
47
|
const renderParts = (parts) => parts.map((part) => {
|
|
50
48
|
const partAttribute = `part ${part.type}`;
|
|
51
49
|
return part.type === "element" ? /* @__PURE__ */ jsx("bdi", { part: partAttribute, role: "listitem", children: /* @__PURE__ */ jsx("slot", { name: part.value }) }) : /* @__PURE__ */ jsx("span", { part: partAttribute, children: part.value });
|
|
52
50
|
});
|
|
53
|
-
this.#formatted = r(
|
|
51
|
+
this.#formatted = r(() => {
|
|
54
52
|
if (!this.#itemSlotNames.value)
|
|
55
53
|
return;
|
|
56
54
|
const formatter = this.#formatter.value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.mjs","sources":["../../../src/components/intl/list.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n \"locale-matcher\": \"locale-matcher\",\n \"type\": \"type\",\n \"style\": \"format-style\"\n} as const\n\ntype BruhListAttributes = {\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.ListFormatOptions[\"localeMatcher\"],\n \"type\"?: Intl.ListFormatOptions[\"type\"],\n \"format-style\"?: Intl.ListFormatOptions[\"style\"]\n}\n\nexport class BruhList extends BruhCustomElementBase<BruhListAttributes> {\n static observedAttributes = [\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #itemSlotNames = r<ReadonlyArray<`${number}`>>()\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r(
|
|
1
|
+
{"version":3,"file":"list.mjs","sources":["../../../src/components/intl/list.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n \"locale-matcher\": \"locale-matcher\",\n \"type\": \"type\",\n \"style\": \"format-style\"\n} as const\n\ntype BruhListAttributes = {\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.ListFormatOptions[\"localeMatcher\"],\n \"type\"?: Intl.ListFormatOptions[\"type\"],\n \"format-style\"?: Intl.ListFormatOptions[\"style\"]\n}\n\nexport class BruhList extends BruhCustomElementBase<BruhListAttributes> {\n static observedAttributes = [\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #itemSlotNames = r<ReadonlyArray<`${number}`>>()\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r(() =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.ListFormatOptions>\n )\n\n this.#formatter = r(() =>\n attempt(() => new Intl.ListFormat(this.#locales.value, this.#options.value))\n ?? new Intl.ListFormat(this.#locales.value)\n )\n\n type ListFormatPart = ReturnType<Intl.ListFormat[\"formatToParts\"]>[number]\n const renderParts = (parts: ReadonlyArray<ListFormatPart>) =>\n parts.map(part => {\n const partAttribute = `part ${part.type}`\n return part.type === \"element\"\n ? <bdi part={partAttribute} role=\"listitem\"><slot name={part.value} /></bdi> as HTMLElement\n : <span part={partAttribute}>{part.value}</span> as HTMLSpanElement\n })\n\n this.#formatted = r(() => {\n if (!this.#itemSlotNames.value)\n return\n\n const formatter = this.#formatter.value\n const { locale } = formatter.resolvedOptions()\n const direction = inferDirection(locale)\n\n const result = renderParts(formatter.formatToParts(this.#itemSlotNames.value))\n\n return <bdi lang={locale} dir={direction} role=\"list\">{result}</bdi> as HTMLElement\n })\n\n const shadowContent = bruhChildrenToNodes([this.#formatted])\n this\n .attachShadow({ mode: \"open\" })\n .append(...shadowContent)\n }\n\n mountedCallback() {\n const assignSlots = () => {\n this.#itemSlotNames.value = [...this.children].map((child, i) => {\n const slot = \"\" + (i + 1) as `${number}`\n child.slot = slot\n return slot\n })\n }\n assignSlots()\n new MutationObserver(assignSlots).observe(this, { childList: true })\n }\n}\n\ncustomElements.define(\"bruh-list\", BruhList)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-list\": BruhList\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-list\": {\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.ListFormatOptions[\"localeMatcher\"],\n \"type\"?: Intl.ListFormatOptions[\"type\"],\n \"format-style\"?: Intl.ListFormatOptions[\"style\"]\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -52,7 +52,6 @@ class BruhNumber extends BruhCustomElementBase {
|
|
|
52
52
|
constructor() {
|
|
53
53
|
super();
|
|
54
54
|
this.#locales = r(
|
|
55
|
-
[this.bruh.attributes.locales, userLanguages],
|
|
56
55
|
() => parseLocales([
|
|
57
56
|
...this.bruh.attributes.locales.value ?? [],
|
|
58
57
|
...userLanguages.value
|
|
@@ -67,7 +66,6 @@ class BruhNumber extends BruhCustomElementBase {
|
|
|
67
66
|
() => mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || void 0])
|
|
68
67
|
);
|
|
69
68
|
this.#formatter = r(
|
|
70
|
-
[this.#locales, this.#options],
|
|
71
69
|
() => attempt(() => new Intl.NumberFormat(this.#locales.value, this.#options.value)) ?? new Intl.NumberFormat(this.#locales.value)
|
|
72
70
|
);
|
|
73
71
|
const numberToFormat = this.bruh.attributes.number;
|
|
@@ -97,7 +95,7 @@ class BruhNumber extends BruhCustomElementBase {
|
|
|
97
95
|
(parts2) => /* @__PURE__ */ jsx("span", { class: `bruh-number-source bruh-number-source--${parts2[0].source}`, children: renderParts(parts2) })
|
|
98
96
|
);
|
|
99
97
|
};
|
|
100
|
-
this.#formatted = r(
|
|
98
|
+
this.#formatted = r(() => {
|
|
101
99
|
if (!numberToFormat.value)
|
|
102
100
|
return;
|
|
103
101
|
const formatter = this.#formatter.value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"number.mjs","sources":["../../../src/components/intl/number.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes, type BruhChild } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n // locale options\n localeMatcher: \"locale-matcher\",\n numberingSystem: \"numbering-system\",\n // style options\n style: \"format-style\",\n currency: \"currency\",\n currencyDisplay: \"currency-display\",\n currencySign: \"currency-sign\",\n unit: \"unit\",\n unitDisplay: \"unit-display\",\n // digit options\n minimumIntegerDigits: \"minimum-integer-digits\",\n minimumFractionDigits: \"minimum-fraction-digits\",\n maximumFractionDigits: \"maximum-fraction-digits\",\n minimumSignificantDigits: \"minimum-significant-digits\",\n maximumSignificantDigits: \"maximum-significant-digits\",\n roundingPriority: \"rounding-priority\",\n roundingIncrement: \"rounding-increment\",\n roundingMode: \"rounding-mode\",\n trailingZeroDisplay: \"trailing-zero-display\",\n // other options\n notation: \"notation\",\n compactDisplay: \"compact-display\",\n useGrouping: \"use-grouping\",\n signDisplay: \"sign-display\"\n} as const\n\ntype BruhNumberAttributes = {\n \"number\"?: Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.NumberFormatOptions[\"localeMatcher\"],\n \"numbering-system\"?: Intl.NumberFormatOptions[\"numberingSystem\"],\n \"format-style\"?: Intl.NumberFormatOptions[\"style\"],\n \"currency\"?: Intl.NumberFormatOptions[\"currency\"],\n \"currency-display\"?: Intl.NumberFormatOptions[\"currencyDisplay\"],\n \"currency-sign\"?: Intl.NumberFormatOptions[\"currencySign\"],\n \"unit\"?: Intl.NumberFormatOptions[\"unit\"],\n \"unit-display\"?: Intl.NumberFormatOptions[\"unitDisplay\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"],\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"],\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"],\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"],\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"],\n \"rounding-priority\"?: Intl.NumberFormatOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.NumberFormatOptions[\"roundingIncrement\"],\n \"rounding-mode\"?: Intl.NumberFormatOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.NumberFormatOptions[\"trailingZeroDisplay\"],\n \"notation\"?: Intl.NumberFormatOptions[\"notation\"],\n \"compact-display\"?: Intl.NumberFormatOptions[\"compactDisplay\"],\n \"use-grouping\"?: Intl.NumberFormatOptions[\"useGrouping\"],\n \"sign-display\"?: Intl.NumberFormatOptions[\"signDisplay\"]\n}\n\nconst isParseable = (s: string | number | bigint): s is Intl.StringNumericLiteral | number | bigint =>\n new Intl.NumberFormat()\n .formatToParts(s as any as number)\n .every(part => part.type !== \"nan\")\n\nexport class BruhNumber extends BruhCustomElementBase<BruhNumberAttributes> {\n static observedAttributes = [\n \"number\",\n \"end-number\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r([this.bruh.attributes.locales, userLanguages], () =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.NumberFormatOptions>\n )\n\n this.#formatter = r([this.#locales, this.#options], () =>\n attempt(() => new Intl.NumberFormat(this.#locales.value, this.#options.value))\n ?? new Intl.NumberFormat(this.#locales.value)\n )\n\n const numberToFormat = this.bruh.attributes.number\n const rangeEndNumberToFormat = this.bruh.attributes[\"end-number\"]\n\n const renderParts = (parts: ReadonlyArray<Intl.NumberFormatPart>, fallback?: BruhChild) =>\n parts.map(part => {\n const value =\n part.type !== \"nan\" || !fallback\n ? part.value\n : <bdi>{fallback}</bdi> as HTMLElement\n\n return <span class={`bruh-number-part bruh-number-part--${part.type}`}>{value}</span> as HTMLSpanElement\n })\n\n const renderSingle = (number: string | number | bigint) =>\n renderParts(this.#formatter.value.formatToParts(number as number), number)\n\n const renderRange = (\n start: string | number | bigint,\n end: string | number | bigint\n ) => {\n const formatter = this.#formatter.value\n\n const canRenderRangeDirectly =\n \"formatRangeToParts\" in formatter\n && isParseable(start)\n && isParseable(end)\n if (!canRenderRangeDirectly)\n return <>{renderSingle(start)}–{renderSingle(end)}</> as BruhChild\n\n const parts = formatter.formatRangeToParts(start, end)\n const bySource = parts.reduce<Intl.NumberRangeFormatPart[][]>((bySource, part, i) => {\n if (!i || parts[i - 1].source !== part.source)\n bySource.push([])\n bySource[bySource.length - 1].push(part)\n return bySource\n }, [])\n return bySource.map(parts =>\n <span class={`bruh-number-source bruh-number-source--${parts[0].source}`}>{renderParts(parts)}</span>\n )\n }\n\n this.#formatted = r([this.#formatter, numberToFormat, rangeEndNumberToFormat], () => {\n if (!numberToFormat.value)\n return\n\n const formatter = this.#formatter.value\n const { locale } = formatter.resolvedOptions()\n const direction = inferDirection(locale)\n\n const result =\n rangeEndNumberToFormat.value\n ? renderRange(numberToFormat.value, rangeEndNumberToFormat.value)\n : renderSingle(numberToFormat.value)\n\n return <bdi lang={locale} dir={direction}>{result}</bdi>\n })\n }\n\n mountedCallback() {\n const children = bruhChildrenToNodes([this.#formatted])\n this.replaceChildren(...children)\n }\n}\n\ncustomElements.define(\"bruh-number\", BruhNumber)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-number\": BruhNumber\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-number\": {\n \"number\": Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.NumberFormatOptions[\"localeMatcher\"],\n \"numbering-system\"?: Intl.NumberFormatOptions[\"numberingSystem\"],\n \"format-style\"?: Intl.NumberFormatOptions[\"style\"],\n \"currency\"?: Intl.NumberFormatOptions[\"currency\"],\n \"currency-display\"?: Intl.NumberFormatOptions[\"currencyDisplay\"],\n \"currency-sign\"?: Intl.NumberFormatOptions[\"currencySign\"],\n \"unit\"?: Intl.NumberFormatOptions[\"unit\"],\n \"unit-display\"?: Intl.NumberFormatOptions[\"unitDisplay\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"] | `${number}`,\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"] | `${number}`,\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"] | `${number}`,\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"] | `${number}`,\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"] | `${number}`,\n \"rounding-priority\"?: Intl.NumberFormatOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.NumberFormatOptions[\"roundingIncrement\"] | `${Intl.NumberFormatOptions[\"roundingIncrement\"]}`,\n \"rounding-mode\"?: Intl.NumberFormatOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.NumberFormatOptions[\"trailingZeroDisplay\"],\n \"notation\"?: Intl.NumberFormatOptions[\"notation\"],\n \"compact-display\"?: Intl.NumberFormatOptions[\"compactDisplay\"],\n \"use-grouping\"?: Intl.NumberFormatOptions[\"useGrouping\"],\n \"sign-display\"?: Intl.NumberFormatOptions[\"signDisplay\"]\n }\n }\n}\n"],"names":["jsxs","bySource","parts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"number.mjs","sources":["../../../src/components/intl/number.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes, type BruhChild } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n // locale options\n localeMatcher: \"locale-matcher\",\n numberingSystem: \"numbering-system\",\n // style options\n style: \"format-style\",\n currency: \"currency\",\n currencyDisplay: \"currency-display\",\n currencySign: \"currency-sign\",\n unit: \"unit\",\n unitDisplay: \"unit-display\",\n // digit options\n minimumIntegerDigits: \"minimum-integer-digits\",\n minimumFractionDigits: \"minimum-fraction-digits\",\n maximumFractionDigits: \"maximum-fraction-digits\",\n minimumSignificantDigits: \"minimum-significant-digits\",\n maximumSignificantDigits: \"maximum-significant-digits\",\n roundingPriority: \"rounding-priority\",\n roundingIncrement: \"rounding-increment\",\n roundingMode: \"rounding-mode\",\n trailingZeroDisplay: \"trailing-zero-display\",\n // other options\n notation: \"notation\",\n compactDisplay: \"compact-display\",\n useGrouping: \"use-grouping\",\n signDisplay: \"sign-display\"\n} as const\n\ntype BruhNumberAttributes = {\n \"number\"?: Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.NumberFormatOptions[\"localeMatcher\"],\n \"numbering-system\"?: Intl.NumberFormatOptions[\"numberingSystem\"],\n \"format-style\"?: Intl.NumberFormatOptions[\"style\"],\n \"currency\"?: Intl.NumberFormatOptions[\"currency\"],\n \"currency-display\"?: Intl.NumberFormatOptions[\"currencyDisplay\"],\n \"currency-sign\"?: Intl.NumberFormatOptions[\"currencySign\"],\n \"unit\"?: Intl.NumberFormatOptions[\"unit\"],\n \"unit-display\"?: Intl.NumberFormatOptions[\"unitDisplay\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"],\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"],\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"],\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"],\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"],\n \"rounding-priority\"?: Intl.NumberFormatOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.NumberFormatOptions[\"roundingIncrement\"],\n \"rounding-mode\"?: Intl.NumberFormatOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.NumberFormatOptions[\"trailingZeroDisplay\"],\n \"notation\"?: Intl.NumberFormatOptions[\"notation\"],\n \"compact-display\"?: Intl.NumberFormatOptions[\"compactDisplay\"],\n \"use-grouping\"?: Intl.NumberFormatOptions[\"useGrouping\"],\n \"sign-display\"?: Intl.NumberFormatOptions[\"signDisplay\"]\n}\n\nconst isParseable = (s: string | number | bigint): s is Intl.StringNumericLiteral | number | bigint =>\n new Intl.NumberFormat()\n .formatToParts(s as any as number)\n .every(part => part.type !== \"nan\")\n\nexport class BruhNumber extends BruhCustomElementBase<BruhNumberAttributes> {\n static observedAttributes = [\n \"number\",\n \"end-number\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r(() =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.NumberFormatOptions>\n )\n\n this.#formatter = r(() =>\n attempt(() => new Intl.NumberFormat(this.#locales.value, this.#options.value))\n ?? new Intl.NumberFormat(this.#locales.value)\n )\n\n const numberToFormat = this.bruh.attributes.number\n const rangeEndNumberToFormat = this.bruh.attributes[\"end-number\"]\n\n const renderParts = (parts: ReadonlyArray<Intl.NumberFormatPart>, fallback?: BruhChild) =>\n parts.map(part => {\n const value =\n part.type !== \"nan\" || !fallback\n ? part.value\n : <bdi>{fallback}</bdi> as HTMLElement\n\n return <span class={`bruh-number-part bruh-number-part--${part.type}`}>{value}</span> as HTMLSpanElement\n })\n\n const renderSingle = (number: string | number | bigint) =>\n renderParts(this.#formatter.value.formatToParts(number as number), number)\n\n const renderRange = (\n start: string | number | bigint,\n end: string | number | bigint\n ) => {\n const formatter = this.#formatter.value\n\n const canRenderRangeDirectly =\n \"formatRangeToParts\" in formatter\n && isParseable(start)\n && isParseable(end)\n if (!canRenderRangeDirectly)\n return <>{renderSingle(start)}–{renderSingle(end)}</> as BruhChild\n\n const parts = formatter.formatRangeToParts(start, end)\n const bySource = parts.reduce<Intl.NumberRangeFormatPart[][]>((bySource, part, i) => {\n if (!i || parts[i - 1].source !== part.source)\n bySource.push([])\n bySource[bySource.length - 1].push(part)\n return bySource\n }, [])\n return bySource.map(parts =>\n <span class={`bruh-number-source bruh-number-source--${parts[0].source}`}>{renderParts(parts)}</span>\n )\n }\n\n this.#formatted = r(() => {\n if (!numberToFormat.value)\n return\n\n const formatter = this.#formatter.value\n const { locale } = formatter.resolvedOptions()\n const direction = inferDirection(locale)\n\n const result =\n rangeEndNumberToFormat.value\n ? renderRange(numberToFormat.value, rangeEndNumberToFormat.value)\n : renderSingle(numberToFormat.value)\n\n return <bdi lang={locale} dir={direction}>{result}</bdi>\n })\n }\n\n mountedCallback() {\n const children = bruhChildrenToNodes([this.#formatted])\n this.replaceChildren(...children)\n }\n}\n\ncustomElements.define(\"bruh-number\", BruhNumber)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-number\": BruhNumber\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-number\": {\n \"number\": Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.NumberFormatOptions[\"localeMatcher\"],\n \"numbering-system\"?: Intl.NumberFormatOptions[\"numberingSystem\"],\n \"format-style\"?: Intl.NumberFormatOptions[\"style\"],\n \"currency\"?: Intl.NumberFormatOptions[\"currency\"],\n \"currency-display\"?: Intl.NumberFormatOptions[\"currencyDisplay\"],\n \"currency-sign\"?: Intl.NumberFormatOptions[\"currencySign\"],\n \"unit\"?: Intl.NumberFormatOptions[\"unit\"],\n \"unit-display\"?: Intl.NumberFormatOptions[\"unitDisplay\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"] | `${number}`,\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"] | `${number}`,\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"] | `${number}`,\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"] | `${number}`,\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"] | `${number}`,\n \"rounding-priority\"?: Intl.NumberFormatOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.NumberFormatOptions[\"roundingIncrement\"] | `${Intl.NumberFormatOptions[\"roundingIncrement\"]}`,\n \"rounding-mode\"?: Intl.NumberFormatOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.NumberFormatOptions[\"trailingZeroDisplay\"],\n \"notation\"?: Intl.NumberFormatOptions[\"notation\"],\n \"compact-display\"?: Intl.NumberFormatOptions[\"compactDisplay\"],\n \"use-grouping\"?: Intl.NumberFormatOptions[\"useGrouping\"],\n \"sign-display\"?: Intl.NumberFormatOptions[\"signDisplay\"]\n }\n }\n}\n"],"names":["jsxs","bySource","parts"],"mappings":"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"}
|
|
@@ -39,7 +39,6 @@ class BruhPlural extends BruhCustomElementBase {
|
|
|
39
39
|
constructor() {
|
|
40
40
|
super();
|
|
41
41
|
this.#locales = r(
|
|
42
|
-
[this.bruh.attributes.locales, userLanguages],
|
|
43
42
|
() => parseLocales([
|
|
44
43
|
...this.bruh.attributes.locales.value ?? [],
|
|
45
44
|
...userLanguages.value
|
|
@@ -54,17 +53,16 @@ class BruhPlural extends BruhCustomElementBase {
|
|
|
54
53
|
() => mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || void 0])
|
|
55
54
|
);
|
|
56
55
|
this.#pluralRules = r(
|
|
57
|
-
[this.#locales, this.#options],
|
|
58
56
|
() => attempt(() => new Intl.PluralRules(this.#locales.value, this.#options.value)) ?? new Intl.PluralRules(this.#locales.value)
|
|
59
57
|
);
|
|
60
58
|
const numberToSelect = this.bruh.attributes.number;
|
|
61
59
|
const rangeEndNumberToSelect = this.bruh.attributes["end-number"];
|
|
62
|
-
this.#selected = r(
|
|
60
|
+
this.#selected = r(() => {
|
|
63
61
|
if (!numberToSelect.value)
|
|
64
62
|
return;
|
|
65
63
|
const pluralRules = this.#pluralRules.value;
|
|
66
64
|
const { locale } = pluralRules.resolvedOptions();
|
|
67
|
-
if (!this.#locales.
|
|
65
|
+
if (!this.#locales.peek().some((preferred) => locale === preferred + ""))
|
|
68
66
|
console.warn(`Resolved locale (${locale}) does not match`);
|
|
69
67
|
const category = rangeEndNumberToSelect.value ? pluralRules.selectRange(numberToSelect.value, rangeEndNumberToSelect.value) : pluralRules.select(numberToSelect.value);
|
|
70
68
|
return [.../* @__PURE__ */ new Set([category, ...categories])].reduceRight(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plural.mjs","sources":["../../../src/components/intl/plural.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n localeMatcher: \"locale-matcher\",\n type: \"type\",\n // digit options\n minimumIntegerDigits: \"minimum-integer-digits\",\n minimumFractionDigits: \"minimum-fraction-digits\",\n maximumFractionDigits: \"maximum-fraction-digits\",\n minimumSignificantDigits: \"minimum-significant-digits\",\n maximumSignificantDigits: \"maximum-significant-digits\",\n roundingPriority: \"rounding-priority\",\n roundingIncrement: \"rounding-increment\",\n roundingMode: \"rounding-mode\",\n trailingZeroDisplay: \"trailing-zero-display\"\n} as const\n\ntype BruhPluralAttributes = {\n \"number\"?: Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.PluralRulesOptions[\"localeMatcher\"],\n \"type\"?: Intl.PluralRulesOptions[\"type\"],\n \"minimum-integer-digits\"?: Intl.PluralRulesOptions[\"minimumIntegerDigits\"],\n \"minimum-fraction-digits\"?: Intl.PluralRulesOptions[\"minimumFractionDigits\"],\n \"maximum-fraction-digits\"?: Intl.PluralRulesOptions[\"maximumFractionDigits\"],\n \"minimum-significant-digits\"?: Intl.PluralRulesOptions[\"minimumSignificantDigits\"],\n \"maximum-significant-digits\"?: Intl.PluralRulesOptions[\"maximumSignificantDigits\"],\n \"rounding-priority\"?: Intl.PluralRulesOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.PluralRulesOptions[\"roundingIncrement\"],\n \"rounding-mode\"?: Intl.PluralRulesOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.PluralRulesOptions[\"trailingZeroDisplay\"]\n}\n\nconst categories = [\"zero\", \"one\", \"two\", \"few\", \"many\", \"other\"] as const satisfies Intl.LDMLPluralRule[]\n\nexport class BruhPlural extends BruhCustomElementBase<BruhPluralAttributes> {\n static observedAttributes = [\n \"number\",\n \"end-number\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #pluralRules\n #selected\n\n constructor() {\n super()\n\n this.#locales = r(
|
|
1
|
+
{"version":3,"file":"plural.mjs","sources":["../../../src/components/intl/plural.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n localeMatcher: \"locale-matcher\",\n type: \"type\",\n // digit options\n minimumIntegerDigits: \"minimum-integer-digits\",\n minimumFractionDigits: \"minimum-fraction-digits\",\n maximumFractionDigits: \"maximum-fraction-digits\",\n minimumSignificantDigits: \"minimum-significant-digits\",\n maximumSignificantDigits: \"maximum-significant-digits\",\n roundingPriority: \"rounding-priority\",\n roundingIncrement: \"rounding-increment\",\n roundingMode: \"rounding-mode\",\n trailingZeroDisplay: \"trailing-zero-display\"\n} as const\n\ntype BruhPluralAttributes = {\n \"number\"?: Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.PluralRulesOptions[\"localeMatcher\"],\n \"type\"?: Intl.PluralRulesOptions[\"type\"],\n \"minimum-integer-digits\"?: Intl.PluralRulesOptions[\"minimumIntegerDigits\"],\n \"minimum-fraction-digits\"?: Intl.PluralRulesOptions[\"minimumFractionDigits\"],\n \"maximum-fraction-digits\"?: Intl.PluralRulesOptions[\"maximumFractionDigits\"],\n \"minimum-significant-digits\"?: Intl.PluralRulesOptions[\"minimumSignificantDigits\"],\n \"maximum-significant-digits\"?: Intl.PluralRulesOptions[\"maximumSignificantDigits\"],\n \"rounding-priority\"?: Intl.PluralRulesOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.PluralRulesOptions[\"roundingIncrement\"],\n \"rounding-mode\"?: Intl.PluralRulesOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.PluralRulesOptions[\"trailingZeroDisplay\"]\n}\n\nconst categories = [\"zero\", \"one\", \"two\", \"few\", \"many\", \"other\"] as const satisfies Intl.LDMLPluralRule[]\n\nexport class BruhPlural extends BruhCustomElementBase<BruhPluralAttributes> {\n static observedAttributes = [\n \"number\",\n \"end-number\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #pluralRules\n #selected\n\n constructor() {\n super()\n\n this.#locales = r(() =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.PluralRulesOptions>\n )\n\n this.#pluralRules = r(() =>\n attempt(() => new Intl.PluralRules(this.#locales.value, this.#options.value))\n ?? new Intl.PluralRules(this.#locales.value)\n )\n\n const numberToSelect = this.bruh.attributes.number\n const rangeEndNumberToSelect = this.bruh.attributes[\"end-number\"]\n\n this.#selected = r(() => {\n if (!numberToSelect.value)\n return\n\n const pluralRules = this.#pluralRules.value\n const { locale } = pluralRules.resolvedOptions()\n if (!this.#locales.peek().some(preferred => locale === preferred + \"\"))\n console.warn(`Resolved locale (${locale}) does not match`)\n\n const category =\n rangeEndNumberToSelect.value\n ? pluralRules.selectRange(numberToSelect.value as any as number, rangeEndNumberToSelect.value as any as number)\n : pluralRules.select(numberToSelect.value as any as number)\n\n // Render nested slots for fallback (no correct fallback order)\n return [...new Set([category, ...categories])]\n .reduceRight<HTMLSlotElement>((fallback, category) =>\n <slot name={category}>{fallback}</slot>\n , undefined as any)\n })\n\n const shadowContent = bruhChildrenToNodes([this.#selected])\n this\n .attachShadow({ mode: \"open\" })\n .append(...shadowContent)\n }\n}\n\ncustomElements.define(\"bruh-plural\", BruhPlural)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-plural\": BruhPlural\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-plural\": {\n \"number\": Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.PluralRulesOptions[\"localeMatcher\"],\n \"type\"?: Intl.PluralRulesOptions[\"type\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"] | `${number}`,\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"] | `${number}`,\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"] | `${number}`,\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"] | `${number}`,\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"] | `${number}`,\n \"rounding-priority\"?: Intl.PluralRulesOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.PluralRulesOptions[\"roundingIncrement\"] | `${Intl.PluralRulesOptions[\"roundingIncrement\"]}`,\n \"rounding-mode\"?: Intl.PluralRulesOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.PluralRulesOptions[\"trailingZeroDisplay\"]\n }\n }\n}\n"],"names":["category"],"mappings":"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"}
|
|
@@ -140,9 +140,9 @@ const reflectLanguagePickerLanguages = () => {
|
|
|
140
140
|
};
|
|
141
141
|
reflectLanguagePickerLanguages();
|
|
142
142
|
addEventListener("storage", reflectLanguagePickerLanguages);
|
|
143
|
-
const urlLocales = r(
|
|
144
|
-
const urlLanguages = r(
|
|
145
|
-
const urlRegions = r(
|
|
143
|
+
const urlLocales = r(() => parseLocales(currentUrl.value.searchParams.getAll("locale")));
|
|
144
|
+
const urlLanguages = r(() => parseLocales(currentUrl.value.searchParams.getAll("language")));
|
|
145
|
+
const urlRegions = r(() => {
|
|
146
146
|
const regions = /* @__PURE__ */ new Set();
|
|
147
147
|
for (const region of currentUrl.value.searchParams.getAll("region")) {
|
|
148
148
|
const parsed = parseRegion(region);
|
|
@@ -151,13 +151,13 @@ const urlRegions = r([currentUrl], () => {
|
|
|
151
151
|
}
|
|
152
152
|
return [...regions];
|
|
153
153
|
});
|
|
154
|
-
const userLanguages = r(
|
|
154
|
+
const userLanguages = r(() => [
|
|
155
155
|
...urlLanguages.value,
|
|
156
156
|
...urlLocales.value,
|
|
157
157
|
...languagePickerLanguages.value,
|
|
158
158
|
...browserLanguages.value
|
|
159
159
|
]);
|
|
160
|
-
const userRegions = r(
|
|
160
|
+
const userRegions = r(() => {
|
|
161
161
|
const regions = new Set(urlRegions.value);
|
|
162
162
|
const guessedRegions = /* @__PURE__ */ new Set();
|
|
163
163
|
const locales = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","sources":["../../../src/components/intl/utils.mts"],"sourcesContent":["import { r, type SourceNode } from \"../../reactive/index.mts\"\nimport { attempt, unique } from \"../../utils/index.mts\"\nimport { currentUrl } from \"../../utils/browser.mts\"\n\nexport type InputLocale = Intl.UnicodeBCP47LocaleIdentifier | Intl.Locale | null | undefined\n\nexport const parseLocale = (locale: InputLocale) => {\n if (locale)\n return attempt(() => new Intl.Locale(locale))\n}\n\nexport const parseLocales = (locales: ReadonlyArray<InputLocale> | InputLocale) => {\n if (Array.isArray(locales))\n return unique(\n locales.map(parseLocale).filter((locale): locale is Intl.Locale => !!locale),\n locale => locale + \"\"\n )\n\n const parsed = parseLocale(locales as InputLocale)\n if (parsed)\n return [parsed]\n\n return []\n}\n\nexport const parseRegion = (region?: string | null) => {\n if (region)\n return attempt(() => new Intl.Locale(\"xx\", { region }).region)\n}\n\nexport const inferRegion = (locale: InputLocale) =>\n parseLocale(locale)?.maximize().region\n\n// https://raw.githubusercontent.com/unicode-org/cldr/main/common/properties/scriptMetadata.txt\n// document.body.textContent.split(\"\\n\")\n// .map(line => line.trim())\n// .filter(line => line && !line.startsWith(\"#\"))\n// .reduce((scripts, line) => {\n// const columns = line.split(\";\")\n// .map(column => column.trim())\n// const script = columns[0]\n// const rtl = columns[6]\n// if (rtl === \"YES\")\n// scripts.push(script)\n// return scripts\n// }, [])\nconst rtlScripts = new Set([\n \"Arab\", \"Hebr\", \"Thaa\", \"Adlm\", \"Armi\", \"Avst\", \"Chrs\",\n \"Cprt\", \"Elym\", \"Hatr\", \"Hung\", \"Khar\", \"Lydi\", \"Mand\",\n \"Mani\", \"Mend\", \"Merc\", \"Mero\", \"Narb\", \"Nbat\", \"Nkoo\",\n \"Orkh\", \"Ougr\", \"Palm\", \"Phli\", \"Phlp\", \"Phnx\", \"Prti\",\n \"Rohg\", \"Samr\", \"Sarb\", \"Sogd\", \"Sogo\", \"Syrc\", \"Yezi\"\n])\nexport const inferDirection = (locale: InputLocale) => {\n const parsed = parseLocale(locale)\n if (!parsed)\n return parsed\n\n const textInfo: { direction: \"ltr\" | \"rtl\" } | undefined = (parsed as any).getTextInfo?.() ?? (parsed as any).textInfo\n if (textInfo?.direction)\n return textInfo.direction\n\n const { script } = parsed.maximize()\n if (script)\n return rtlScripts.has(script)\n ? \"rtl\"\n : \"ltr\"\n}\n\nexport const languageDisplayName = (displayNames: Intl.DisplayNames, language: InputLocale) => {\n const parsed = parseLocale(language)\n if (!parsed)\n return language + \"\"\n\n for (const code of [parsed + \"\", parsed.baseName, parsed.language]) {\n const display = attempt(() => displayNames.of(code))\n if (display && display !== code)\n return display\n }\n\n return parsed + \"\"\n}\n\n// Returns an array of progressively generalized locales\n// Based on https://tc39.es/ecma402/#sec-bestavailablelocale (RFC 4647, section 3.4)\nexport const generalizedLocales = (locale: InputLocale) => {\n const result = []\n\n let generalized = locale + \"\"\n do {\n result.push(generalized)\n\n let lastDashIndex = generalized.lastIndexOf(\"-\")\n if (lastDashIndex === -1)\n break\n\n if (lastDashIndex >= 2 && generalized[lastDashIndex - 2] === \"-\")\n lastDashIndex -= 2\n\n generalized = generalized.slice(0, lastDashIndex)\n } while (true)\n\n return parseLocales(result)\n}\n\nexport const bestAvailableLocales = (available: ReadonlyArray<InputLocale>, preferred: ReadonlyArray<InputLocale>) => {\n const canonicalAvailable = parseLocales(available).map(locale => locale + \"\")\n const generalizedAvailable = new Map<string, string>()\n for (const full of canonicalAvailable) {\n const canonicalGeneralized = generalizedLocales(full).map(locale => locale + \"\")\n for (const generalized of canonicalGeneralized) {\n if (!generalizedAvailable.has(generalized) || generalized === full)\n generalizedAvailable.set(generalized, full)\n }\n }\n\n const canonicalPreferred = parseLocales(preferred).map(locale => locale + \"\")\n const generalizedPreferred = new Set<string>()\n for (const full of canonicalPreferred) {\n const canonicalGeneralized = generalizedLocales(full).map(locale => locale + \"\")\n for (const generalized of canonicalGeneralized) {\n // last write wins set\n if (generalizedPreferred.has(generalized))\n generalizedPreferred.delete(generalized)\n\n generalizedPreferred.add(generalized)\n }\n }\n\n const matches = new Set([...generalizedPreferred].map(gp => generalizedAvailable.get(gp)!))\n const alsoAvailable = canonicalAvailable.filter(other => !matches.has(other))\n\n return {\n matches: parseLocales([...matches]),\n alsoAvailable: parseLocales(alsoAvailable)\n }\n}\n\nexport const browserLanguages = r() as SourceNode<ReadonlyArray<Intl.Locale>>\nconst reflectLanguages = () => {\n browserLanguages.value = parseLocales(navigator.languages)\n}\nreflectLanguages()\naddEventListener(\"languagechange\", reflectLanguages)\n\nexport const languagePickerLanguages = r() as SourceNode<ReadonlyArray<Intl.Locale>>\nconst reflectLanguagePickerLanguages = () => {\n languagePickerLanguages.value = parseLocales(\n attempt(() =>\n JSON.parse(\n localStorage.getItem(\"bruh-language-picker-languages\") as any\n )\n )\n )\n}\nreflectLanguagePickerLanguages()\naddEventListener(\"storage\", reflectLanguagePickerLanguages) // only accounts for changes on different windows\n\nconst urlLocales = r([currentUrl], () => parseLocales(currentUrl.value.searchParams.getAll(\"locale\")))\nconst urlLanguages = r([currentUrl], () => parseLocales(currentUrl.value.searchParams.getAll(\"language\")))\nconst urlRegions = r([currentUrl], () => {\n const regions = new Set<string>()\n\n for (const region of currentUrl.value.searchParams.getAll(\"region\")) {\n const parsed = parseRegion(region)\n if (parsed)\n regions.add(parsed)\n }\n\n return [...regions]\n})\n\nexport const userLanguages = r([urlLanguages, urlLocales, languagePickerLanguages, browserLanguages], () => [\n ...urlLanguages.value,\n ...urlLocales.value,\n ...languagePickerLanguages.value,\n ...browserLanguages.value\n] as const)\n\nexport const userRegions = r([currentUrl, urlRegions, urlLocales, urlLanguages], () => {\n const regions = new Set<string>(urlRegions.value)\n const guessedRegions = new Set<string>()\n\n const locales = [\n ...urlLocales.value,\n ...urlLanguages.value,\n ...languagePickerLanguages.value,\n ...browserLanguages.value\n ]\n\n for (const locale of locales) {\n if (locale.region)\n regions.add(locale.region)\n else\n guessedRegions.add(locale.maximize().region!)\n }\n\n return unique([...regions, ...guessedRegions]) as ReadonlyArray<string>\n})\n\n\nconst segment = (content: string, locales: Intl.LocalesArgument, options: Intl.SegmenterOptions) =>\n [...new Intl.Segmenter(locales, options).segment(content)]\n\nexport const segmentTree = (locales: Intl.LocalesArgument, content: string) =>\n segment(content, locales, { granularity: \"sentence\" }).map(sentence =>\n ({\n type: \"sentence\",\n content: segment(sentence.segment, locales, { granularity: \"word\" }).map(word => {\n const graphemes =\n segment(word.segment, locales, { granularity: \"grapheme\" }).map(grapheme =>\n ({\n type: \"grapheme\",\n content: grapheme.segment\n } as const)\n )\n return word.isWordLike\n ? {\n type: \"word\",\n content: graphemes\n } as const\n : graphemes\n })\n } as const)\n )\n"],"names":[],"mappings":";;;;AAMa,MAAA,WAAA,GAAc,CAAC,MAAwB,KAAA;AAClD,EAAI,IAAA,MAAA;AACF,IAAA,OAAO,QAAQ,MAAM,IAAI,IAAK,CAAA,MAAA,CAAO,MAAM,CAAC,CAAA;AAChD;AAEa,MAAA,YAAA,GAAe,CAAC,OAAsD,KAAA;AACjF,EAAI,IAAA,KAAA,CAAM,QAAQ,OAAO,CAAA;AACvB,IAAO,OAAA,MAAA;AAAA,MACL,OAAA,CAAQ,IAAI,WAAW,CAAA,CAAE,OAAO,CAAC,MAAA,KAAkC,CAAC,CAAC,MAAM,CAAA;AAAA,MAC3E,YAAU,MAAS,GAAA;AAAA,KACrB;AAEF,EAAM,MAAA,MAAA,GAAS,YAAY,OAAsB,CAAA;AACjD,EAAI,IAAA,MAAA;AACF,IAAA,OAAO,CAAC,MAAM,CAAA;AAEhB,EAAA,OAAO,EAAC;AACV;AAEa,MAAA,WAAA,GAAc,CAAC,MAA2B,KAAA;AACrD,EAAI,IAAA,MAAA;AACF,IAAO,OAAA,OAAA,CAAQ,MAAM,IAAI,IAAK,CAAA,MAAA,CAAO,MAAM,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAM,CAAA;AACjE;AAEO,MAAM,cAAc,CAAC,MAAA,KAC1B,YAAY,MAAM,CAAA,EAAG,UAAW,CAAA;AAelC,MAAM,UAAA,uBAAiB,GAAI,CAAA;AAAA,EACzB,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAChD,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAChD,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAChD,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAChD,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ;AAClD,CAAC,CAAA;AACY,MAAA,cAAA,GAAiB,CAAC,MAAwB,KAAA;AACrD,EAAM,MAAA,MAAA,GAAS,YAAY,MAAM,CAAA;AACjC,EAAA,IAAI,CAAC,MAAA;AACH,IAAO,OAAA,MAAA;AAET,EAAA,MAAM,QAAsD,GAAA,MAAA,CAAe,WAAc,IAAA,IAAM,MAAe,CAAA,QAAA;AAC9G,EAAA,IAAI,QAAU,EAAA,SAAA;AACZ,IAAA,OAAO,QAAS,CAAA,SAAA;AAElB,EAAA,MAAM,EAAE,MAAA,EAAW,GAAA,MAAA,CAAO,QAAS,EAAA;AACnC,EAAI,IAAA,MAAA;AACF,IAAA,OAAO,UAAW,CAAA,GAAA,CAAI,MAAM,CAAA,GACxB,KACA,GAAA,KAAA;AACR;AAEa,MAAA,mBAAA,GAAsB,CAAC,YAAA,EAAiC,QAA0B,KAAA;AAC7F,EAAM,MAAA,MAAA,GAAS,YAAY,QAAQ,CAAA;AACnC,EAAA,IAAI,CAAC,MAAA;AACH,IAAA,OAAO,QAAW,GAAA,EAAA;AAEpB,EAAW,KAAA,MAAA,IAAA,IAAQ,CAAC,MAAS,GAAA,EAAA,EAAI,OAAO,QAAU,EAAA,MAAA,CAAO,QAAQ,CAAG,EAAA;AAClE,IAAA,MAAM,UAAU,OAAQ,CAAA,MAAM,YAAa,CAAA,EAAA,CAAG,IAAI,CAAC,CAAA;AACnD,IAAA,IAAI,WAAW,OAAY,KAAA,IAAA;AACzB,MAAO,OAAA,OAAA;AAAA;AAGX,EAAA,OAAO,MAAS,GAAA,EAAA;AAClB;AAIa,MAAA,kBAAA,GAAqB,CAAC,MAAwB,KAAA;AACzD,EAAA,MAAM,SAAS,EAAC;AAEhB,EAAA,IAAI,cAAc,MAAS,GAAA,EAAA;AAC3B,EAAG,GAAA;AACD,IAAA,MAAA,CAAO,KAAK,WAAW,CAAA;AAEvB,IAAI,IAAA,aAAA,GAAgB,WAAY,CAAA,WAAA,CAAY,GAAG,CAAA;AAC/C,IAAA,IAAI,aAAkB,KAAA,EAAA;AACpB,MAAA;AAEF,IAAA,IAAI,aAAiB,IAAA,CAAA,IAAK,WAAY,CAAA,aAAA,GAAgB,CAAC,CAAM,KAAA,GAAA;AAC3D,MAAiB,aAAA,IAAA,CAAA;AAEnB,IAAc,WAAA,GAAA,WAAA,CAAY,KAAM,CAAA,CAAA,EAAG,aAAa,CAAA;AAAA,GACzC,QAAA,IAAA;AAET,EAAA,OAAO,aAAa,MAAM,CAAA;AAC5B;AAEa,MAAA,oBAAA,GAAuB,CAAC,SAAA,EAAuC,SAA0C,KAAA;AACpH,EAAA,MAAM,qBAAqB,YAAa,CAAA,SAAS,EAAE,GAAI,CAAA,CAAA,MAAA,KAAU,SAAS,EAAE,CAAA;AAC5E,EAAM,MAAA,oBAAA,uBAA2B,GAAoB,EAAA;AACrD,EAAA,KAAA,MAAW,QAAQ,kBAAoB,EAAA;AACrC,IAAA,MAAM,uBAAuB,kBAAmB,CAAA,IAAI,EAAE,GAAI,CAAA,CAAA,MAAA,KAAU,SAAS,EAAE,CAAA;AAC/E,IAAA,KAAA,MAAW,eAAe,oBAAsB,EAAA;AAC9C,MAAA,IAAI,CAAC,oBAAA,CAAqB,GAAI,CAAA,WAAW,KAAK,WAAgB,KAAA,IAAA;AAC5D,QAAqB,oBAAA,CAAA,GAAA,CAAI,aAAa,IAAI,CAAA;AAAA;AAC9C;AAGF,EAAA,MAAM,qBAAqB,YAAa,CAAA,SAAS,EAAE,GAAI,CAAA,CAAA,MAAA,KAAU,SAAS,EAAE,CAAA;AAC5E,EAAM,MAAA,oBAAA,uBAA2B,GAAY,EAAA;AAC7C,EAAA,KAAA,MAAW,QAAQ,kBAAoB,EAAA;AACrC,IAAA,MAAM,uBAAuB,kBAAmB,CAAA,IAAI,EAAE,GAAI,CAAA,CAAA,MAAA,KAAU,SAAS,EAAE,CAAA;AAC/E,IAAA,KAAA,MAAW,eAAe,oBAAsB,EAAA;AAE9C,MAAI,IAAA,oBAAA,CAAqB,IAAI,WAAW,CAAA;AACtC,QAAA,oBAAA,CAAqB,OAAO,WAAW,CAAA;AAEzC,MAAA,oBAAA,CAAqB,IAAI,WAAW,CAAA;AAAA;AACtC;AAGF,EAAA,MAAM,OAAU,GAAA,IAAI,GAAI,CAAA,CAAC,GAAG,oBAAoB,CAAE,CAAA,GAAA,CAAI,CAAM,EAAA,KAAA,oBAAA,CAAqB,GAAI,CAAA,EAAE,CAAE,CAAC,CAAA;AAC1F,EAAM,MAAA,aAAA,GAAgB,mBAAmB,MAAO,CAAA,CAAA,KAAA,KAAS,CAAC,OAAQ,CAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AAE5E,EAAO,OAAA;AAAA,IACL,OAAS,EAAA,YAAA,CAAa,CAAC,GAAG,OAAO,CAAC,CAAA;AAAA,IAClC,aAAA,EAAe,aAAa,aAAa;AAAA,GAC3C;AACF;AAEO,MAAM,mBAAmB,CAAE;AAClC,MAAM,mBAAmB,MAAM;AAC7B,EAAiB,gBAAA,CAAA,KAAA,GAAQ,YAAa,CAAA,SAAA,CAAU,SAAS,CAAA;AAC3D,CAAA;AACA,gBAAiB,EAAA;AACjB,gBAAA,CAAiB,kBAAkB,gBAAgB,CAAA;AAE5C,MAAM,0BAA0B,CAAE;AACzC,MAAM,iCAAiC,MAAM;AAC3C,EAAA,uBAAA,CAAwB,KAAQ,GAAA,YAAA;AAAA,IAC9B,OAAA;AAAA,MAAQ,MACN,IAAK,CAAA,KAAA;AAAA,QACH,YAAA,CAAa,QAAQ,gCAAgC;AAAA;AACvD;AACF,GACF;AACF,CAAA;AACA,8BAA+B,EAAA;AAC/B,gBAAA,CAAiB,WAAW,8BAA8B,CAAA;AAE1D,MAAM,UAAa,GAAA,CAAA,CAAE,CAAC,UAAU,CAAG,EAAA,MAAM,YAAa,CAAA,UAAA,CAAW,KAAM,CAAA,YAAA,CAAa,MAAO,CAAA,QAAQ,CAAC,CAAC,CAAA;AACrG,MAAM,YAAe,GAAA,CAAA,CAAE,CAAC,UAAU,CAAG,EAAA,MAAM,YAAa,CAAA,UAAA,CAAW,KAAM,CAAA,YAAA,CAAa,MAAO,CAAA,UAAU,CAAC,CAAC,CAAA;AACzG,MAAM,UAAa,GAAA,CAAA,CAAE,CAAC,UAAU,GAAG,MAAM;AACvC,EAAM,MAAA,OAAA,uBAAc,GAAY,EAAA;AAEhC,EAAA,KAAA,MAAW,UAAU,UAAW,CAAA,KAAA,CAAM,YAAa,CAAA,MAAA,CAAO,QAAQ,CAAG,EAAA;AACnE,IAAM,MAAA,MAAA,GAAS,YAAY,MAAM,CAAA;AACjC,IAAI,IAAA,MAAA;AACF,MAAA,OAAA,CAAQ,IAAI,MAAM,CAAA;AAAA;AAGtB,EAAO,OAAA,CAAC,GAAG,OAAO,CAAA;AACpB,CAAC,CAAA;AAEY,MAAA,aAAA,GAAgB,EAAE,CAAC,YAAA,EAAc,YAAY,uBAAyB,EAAA,gBAAgB,GAAG,MAAM;AAAA,EAC1G,GAAG,YAAa,CAAA,KAAA;AAAA,EAChB,GAAG,UAAW,CAAA,KAAA;AAAA,EACd,GAAG,uBAAwB,CAAA,KAAA;AAAA,EAC3B,GAAG,gBAAiB,CAAA;AACtB,CAAU;AAEG,MAAA,WAAA,GAAc,EAAE,CAAC,UAAA,EAAY,YAAY,UAAY,EAAA,YAAY,GAAG,MAAM;AACrF,EAAA,MAAM,OAAU,GAAA,IAAI,GAAY,CAAA,UAAA,CAAW,KAAK,CAAA;AAChD,EAAM,MAAA,cAAA,uBAAqB,GAAY,EAAA;AAEvC,EAAA,MAAM,OAAU,GAAA;AAAA,IACd,GAAG,UAAW,CAAA,KAAA;AAAA,IACd,GAAG,YAAa,CAAA,KAAA;AAAA,IAChB,GAAG,uBAAwB,CAAA,KAAA;AAAA,IAC3B,GAAG,gBAAiB,CAAA;AAAA,GACtB;AAEA,EAAA,KAAA,MAAW,UAAU,OAAS,EAAA;AAC5B,IAAA,IAAI,MAAO,CAAA,MAAA;AACT,MAAQ,OAAA,CAAA,GAAA,CAAI,OAAO,MAAM,CAAA;AAAA;AAEzB,MAAA,cAAA,CAAe,GAAI,CAAA,MAAA,CAAO,QAAS,EAAA,CAAE,MAAO,CAAA;AAAA;AAGhD,EAAA,OAAO,OAAO,CAAC,GAAG,OAAS,EAAA,GAAG,cAAc,CAAC,CAAA;AAC/C,CAAC;AAGD,MAAM,OAAU,GAAA,CAAC,OAAiB,EAAA,OAAA,EAA+B,YAC/D,CAAC,GAAG,IAAI,IAAA,CAAK,UAAU,OAAS,EAAA,OAAO,CAAE,CAAA,OAAA,CAAQ,OAAO,CAAC,CAAA;AAE9C,MAAA,WAAA,GAAc,CAAC,OAAA,EAA+B,OACzD,KAAA,OAAA,CAAQ,OAAS,EAAA,OAAA,EAAS,EAAE,WAAA,EAAa,UAAW,EAAC,CAAE,CAAA,GAAA;AAAA,EAAI,CACxD,QAAA,MAAA;AAAA,IACC,IAAM,EAAA,UAAA;AAAA,IACN,OAAA,EAAS,OAAQ,CAAA,QAAA,CAAS,OAAS,EAAA,OAAA,EAAS,EAAE,WAAA,EAAa,MAAO,EAAC,CAAE,CAAA,GAAA,CAAI,CAAQ,IAAA,KAAA;AAC/E,MAAM,MAAA,SAAA,GACJ,QAAQ,IAAK,CAAA,OAAA,EAAS,SAAS,EAAE,WAAA,EAAa,UAAW,EAAC,CAAE,CAAA,GAAA;AAAA,QAAI,CAC7D,QAAA,MAAA;AAAA,UACC,IAAM,EAAA,UAAA;AAAA,UACN,SAAS,QAAS,CAAA;AAAA,SACpB;AAAA,OACF;AACF,MAAA,OAAO,KAAK,UACN,GAAA;AAAA,QACA,IAAM,EAAA,MAAA;AAAA,QACN,OAAS,EAAA;AAAA,OAET,GAAA,SAAA;AAAA,KACP;AAAA,GACH;AACF;;;;"}
|
|
1
|
+
{"version":3,"file":"utils.mjs","sources":["../../../src/components/intl/utils.mts"],"sourcesContent":["import { r, type SourceNode } from \"../../reactive/index.mts\"\nimport { attempt, unique } from \"../../utils/index.mts\"\nimport { currentUrl } from \"../../utils/browser.mts\"\n\nexport type InputLocale = Intl.UnicodeBCP47LocaleIdentifier | Intl.Locale | null | undefined\n\nexport const parseLocale = (locale: InputLocale) => {\n if (locale)\n return attempt(() => new Intl.Locale(locale))\n}\n\nexport const parseLocales = (locales: ReadonlyArray<InputLocale> | InputLocale) => {\n if (Array.isArray(locales))\n return unique(\n locales.map(parseLocale).filter((locale): locale is Intl.Locale => !!locale),\n locale => locale + \"\"\n )\n\n const parsed = parseLocale(locales as InputLocale)\n if (parsed)\n return [parsed]\n\n return []\n}\n\nexport const parseRegion = (region?: string | null) => {\n if (region)\n return attempt(() => new Intl.Locale(\"xx\", { region }).region)\n}\n\nexport const inferRegion = (locale: InputLocale) =>\n parseLocale(locale)?.maximize().region\n\n// https://raw.githubusercontent.com/unicode-org/cldr/main/common/properties/scriptMetadata.txt\n// document.body.textContent.split(\"\\n\")\n// .map(line => line.trim())\n// .filter(line => line && !line.startsWith(\"#\"))\n// .reduce((scripts, line) => {\n// const columns = line.split(\";\")\n// .map(column => column.trim())\n// const script = columns[0]\n// const rtl = columns[6]\n// if (rtl === \"YES\")\n// scripts.push(script)\n// return scripts\n// }, [])\nconst rtlScripts = new Set([\n \"Arab\", \"Hebr\", \"Thaa\", \"Adlm\", \"Armi\", \"Avst\", \"Chrs\",\n \"Cprt\", \"Elym\", \"Hatr\", \"Hung\", \"Khar\", \"Lydi\", \"Mand\",\n \"Mani\", \"Mend\", \"Merc\", \"Mero\", \"Narb\", \"Nbat\", \"Nkoo\",\n \"Orkh\", \"Ougr\", \"Palm\", \"Phli\", \"Phlp\", \"Phnx\", \"Prti\",\n \"Rohg\", \"Samr\", \"Sarb\", \"Sogd\", \"Sogo\", \"Syrc\", \"Yezi\"\n])\nexport const inferDirection = (locale: InputLocale) => {\n const parsed = parseLocale(locale)\n if (!parsed)\n return parsed\n\n const textInfo: { direction: \"ltr\" | \"rtl\" } | undefined = (parsed as any).getTextInfo?.() ?? (parsed as any).textInfo\n if (textInfo?.direction)\n return textInfo.direction\n\n const { script } = parsed.maximize()\n if (script)\n return rtlScripts.has(script)\n ? \"rtl\"\n : \"ltr\"\n}\n\nexport const languageDisplayName = (displayNames: Intl.DisplayNames, language: InputLocale) => {\n const parsed = parseLocale(language)\n if (!parsed)\n return language + \"\"\n\n for (const code of [parsed + \"\", parsed.baseName, parsed.language]) {\n const display = attempt(() => displayNames.of(code))\n if (display && display !== code)\n return display\n }\n\n return parsed + \"\"\n}\n\n// Returns an array of progressively generalized locales\n// Based on https://tc39.es/ecma402/#sec-bestavailablelocale (RFC 4647, section 3.4)\nexport const generalizedLocales = (locale: InputLocale) => {\n const result = []\n\n let generalized = locale + \"\"\n do {\n result.push(generalized)\n\n let lastDashIndex = generalized.lastIndexOf(\"-\")\n if (lastDashIndex === -1)\n break\n\n if (lastDashIndex >= 2 && generalized[lastDashIndex - 2] === \"-\")\n lastDashIndex -= 2\n\n generalized = generalized.slice(0, lastDashIndex)\n } while (true)\n\n return parseLocales(result)\n}\n\nexport const bestAvailableLocales = (available: ReadonlyArray<InputLocale>, preferred: ReadonlyArray<InputLocale>) => {\n const canonicalAvailable = parseLocales(available).map(locale => locale + \"\")\n const generalizedAvailable = new Map<string, string>()\n for (const full of canonicalAvailable) {\n const canonicalGeneralized = generalizedLocales(full).map(locale => locale + \"\")\n for (const generalized of canonicalGeneralized) {\n if (!generalizedAvailable.has(generalized) || generalized === full)\n generalizedAvailable.set(generalized, full)\n }\n }\n\n const canonicalPreferred = parseLocales(preferred).map(locale => locale + \"\")\n const generalizedPreferred = new Set<string>()\n for (const full of canonicalPreferred) {\n const canonicalGeneralized = generalizedLocales(full).map(locale => locale + \"\")\n for (const generalized of canonicalGeneralized) {\n // last write wins set\n if (generalizedPreferred.has(generalized))\n generalizedPreferred.delete(generalized)\n\n generalizedPreferred.add(generalized)\n }\n }\n\n const matches = new Set([...generalizedPreferred].map(gp => generalizedAvailable.get(gp)!))\n const alsoAvailable = canonicalAvailable.filter(other => !matches.has(other))\n\n return {\n matches: parseLocales([...matches]),\n alsoAvailable: parseLocales(alsoAvailable)\n }\n}\n\nexport const browserLanguages = r() as SourceNode<ReadonlyArray<Intl.Locale>>\nconst reflectLanguages = () => {\n browserLanguages.value = parseLocales(navigator.languages)\n}\nreflectLanguages()\naddEventListener(\"languagechange\", reflectLanguages)\n\nexport const languagePickerLanguages = r() as SourceNode<ReadonlyArray<Intl.Locale>>\nconst reflectLanguagePickerLanguages = () => {\n languagePickerLanguages.value = parseLocales(\n attempt(() =>\n JSON.parse(\n localStorage.getItem(\"bruh-language-picker-languages\") as any\n )\n )\n )\n}\nreflectLanguagePickerLanguages()\naddEventListener(\"storage\", reflectLanguagePickerLanguages) // only accounts for changes on different windows\n\nconst urlLocales = r(() => parseLocales(currentUrl.value.searchParams.getAll(\"locale\")))\nconst urlLanguages = r(() => parseLocales(currentUrl.value.searchParams.getAll(\"language\")))\nconst urlRegions = r(() => {\n const regions = new Set<string>()\n\n for (const region of currentUrl.value.searchParams.getAll(\"region\")) {\n const parsed = parseRegion(region)\n if (parsed)\n regions.add(parsed)\n }\n\n return [...regions]\n})\n\nexport const userLanguages = r(() => [\n ...urlLanguages.value,\n ...urlLocales.value,\n ...languagePickerLanguages.value,\n ...browserLanguages.value\n] as const)\n\nexport const userRegions = r(() => {\n const regions = new Set<string>(urlRegions.value)\n const guessedRegions = new Set<string>()\n\n const locales = [\n ...urlLocales.value,\n ...urlLanguages.value,\n ...languagePickerLanguages.value,\n ...browserLanguages.value\n ]\n\n for (const locale of locales) {\n if (locale.region)\n regions.add(locale.region)\n else\n guessedRegions.add(locale.maximize().region!)\n }\n\n return unique([...regions, ...guessedRegions]) as ReadonlyArray<string>\n})\n\n\nconst segment = (content: string, locales: Intl.LocalesArgument, options: Intl.SegmenterOptions) =>\n [...new Intl.Segmenter(locales, options).segment(content)]\n\nexport const segmentTree = (locales: Intl.LocalesArgument, content: string) =>\n segment(content, locales, { granularity: \"sentence\" }).map(sentence =>\n ({\n type: \"sentence\",\n content: segment(sentence.segment, locales, { granularity: \"word\" }).map(word => {\n const graphemes =\n segment(word.segment, locales, { granularity: \"grapheme\" }).map(grapheme =>\n ({\n type: \"grapheme\",\n content: grapheme.segment\n } as const)\n )\n return word.isWordLike\n ? {\n type: \"word\",\n content: graphemes\n } as const\n : graphemes\n })\n } as const)\n )\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { r, getValue } from '../reactive.mjs';
|
|
2
|
+
import { memo } from '../utils.mjs';
|
|
3
|
+
|
|
4
|
+
const MemoMap = ({
|
|
5
|
+
items,
|
|
6
|
+
scope = [items],
|
|
7
|
+
getKey,
|
|
8
|
+
children: f
|
|
9
|
+
}) => {
|
|
10
|
+
const memoF = memo(f, {
|
|
11
|
+
scope: [MemoMap, ...scope],
|
|
12
|
+
getKey
|
|
13
|
+
});
|
|
14
|
+
return r(() => Array.from(getValue(items), memoF));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { MemoMap };
|
|
18
|
+
//# sourceMappingURL=misc.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"misc.mjs","sources":["../../src/components/misc.mts"],"sourcesContent":["import { r, type MaybeReactive, getValue } from \"../reactive/index.mts\"\nimport { memo } from \"../utils/index.mts\"\n\n/**\n * Prefer this over `{items.map()}`; it handles reactive and nonreactive iterables with arbitrary memo keys.\n * Memoization is scoped by [MemoMap, ...scope], so different MemoMaps won't collide even with the same items.\n *\n * ```tsx\n * <MemoMap\n * items={maybeReactiveItems}\n * scope={[maybeReactiveItems]} // Optional: defaults to [items]\n * getKey={item => item} // Optional: defaults to the item itself\n * >\n * {item =>\n * <Item>{item}</Item> // Results are memoized within the scope by the key\n * }\n * </MemoMap>\n * ```\n *\n * If rendering the same items in multiple different views, provide distinct scopes:\n * ```tsx\n * <MemoMap items={users} scope={[UserCard, users]}>{...}</MemoMap>\n * <MemoMap items={users} scope={[UserRow, users]}>{...}</MemoMap>\n * ```\n */\nexport const MemoMap = <\n In extends unknown,\n Out extends unknown\n>({\n items,\n scope = [items],\n getKey,\n children: f\n}: {\n items: MaybeReactive<Iterable<In>>,\n /**\n * Defaults to [items]\n */\n scope?: ReadonlyArray<unknown>,\n /**\n * Defaults to the item itself\n */\n getKey?: (x: In) => unknown,\n children: (x: In) => Out\n}) => {\n const memoF = memo(f, {\n scope: [MemoMap, ...scope],\n getKey\n })\n return r(() => Array.from(getValue(items), memoF))\n}\n"],"names":[],"mappings":";;;AAyBO,MAAM,UAAU,CAGrB;AAAA,EACA,KAAA;AAAA,EACA,KAAA,GAAQ,CAAC,KAAK,CAAA;AAAA,EACd,MAAA;AAAA,EACA,QAAU,EAAA;AACZ,CAWM,KAAA;AACJ,EAAM,MAAA,KAAA,GAAQ,KAAK,CAAG,EAAA;AAAA,IACpB,KAAO,EAAA,CAAC,OAAS,EAAA,GAAG,KAAK,CAAA;AAAA,IACzB;AAAA,GACD,CAAA;AACD,EAAO,OAAA,CAAA,CAAE,MAAM,KAAM,CAAA,IAAA,CAAK,SAAS,KAAK,CAAA,EAAG,KAAK,CAAC,CAAA;AACnD;;;;"}
|