@jungherz-de/glasskit-elements 1.19.1 → 1.19.2

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/CHANGELOG.md CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.19.2] – 2026-09-26
11
+
12
+ ### Fixed
13
+
14
+ - **`<glk-date-strip>` and `<glk-calendar>` name days in the page's language, not the browser's.** Without `locale` they went straight to `navigator.language`, so a German page opened on a phone set to English showed "SUN MON TUE" in the strip and started the calendar on Sunday — next to German text everywhere else. They now take the `lang` of the nearest ancestor, usually `<html lang>`, looked up across shadow roots through their hosts, so an element inside another component's shadow tree — a hybrids view, say — reaches the page's language, and a `<section lang="en">` in a German page stays English. Only without any `lang` does the browser language follow, then English; an empty `lang=""` means "unknown" in HTML and falls through to the browser. `locale` still wins over all of it. The page language decides weekday and month names, the chips' and days' `aria-label`s and the calendar's first day of the week. Measured in Chromium and WebKit with an `en-US` browser on `<html lang="de">`: "So Mo Di" and "Sonntag, 27. September 2026" instead of "Sun Mon Tue" and "Sunday, September 27, 2026", the calendar starts on Monday; a page without `lang` looks as before. Compatibility: a page whose `lang` differs from its visitors' browsers now shows its own language in these two elements — set `locale` to keep another. NotionKit Elements falls back to `<html lang>` since 1.17; this looks at the nearest ancestor instead. (EhrenPfoten, Elements finding 10.)
15
+
16
+ ---
17
+
10
18
  ## [1.19.1] – 2026-09-26
11
19
 
12
20
  ### Fixed
@@ -701,6 +709,7 @@ Starting with this release, GlassKit Elements version numbers are aligned with G
701
709
 
702
710
  ---
703
711
 
712
+ [1.19.2]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.19.2
704
713
  [1.19.1]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.19.1
705
714
  [1.19.0]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.19.0
706
715
  [1.18.0]: https://github.com/JUNGHERZ/GlassKit-Elements/releases/tag/v1.18.0
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <a href="#"><img src="https://img.shields.io/badge/vanilla_JS-no_dependencies-44cc11?style=flat-square" alt="Vanilla JS"></a>
6
6
  <a href="#"><img src="https://img.shields.io/badge/components-33-7ec8e3?style=flat-square" alt="33 Components"></a>
7
7
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT License"></a>
8
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.19.1-lightgrey?style=flat-square" alt="Changelog"></a>
8
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-v1.19.2-lightgrey?style=flat-square" alt="Changelog"></a>
9
9
  <a href="https://www.npmjs.com/package/@jungherz-de/glasskit-elements"><img src="https://img.shields.io/badge/npm-%40jungherz--de%2Fglasskit--elements-cb3837?style=flat-square&logo=npm" alt="npm"></a>
10
10
  </p>
11
11
 
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: glasskit-elements
3
- description: GlassKit Elements is a vanilla-JS Web Components library (v1.19.1) wrapping GlassKit CSS v1.19.1. It provides 36 custom elements with the `glk-` prefix, Dark/Light mode with automatic theme sync, Shadow DOM encapsulation, and form-associated custom elements. Use this reference whenever generating HTML that uses `<glk-*>` tags to ensure correct attributes, slots, events, and composition.
3
+ description: GlassKit Elements is a vanilla-JS Web Components library (v1.19.2) wrapping GlassKit CSS v1.19.1. It provides 36 custom elements with the `glk-` prefix, Dark/Light mode with automatic theme sync, Shadow DOM encapsulation, and form-associated custom elements. Use this reference whenever generating HTML that uses `<glk-*>` tags to ensure correct attributes, slots, events, and composition.
4
4
  ---
5
5
 
6
6
  # GlassKit Elements – AI Component Reference
@@ -1097,7 +1097,7 @@ A row of day chips that scrolls sideways (since 1.16.0) — a booking horizon, t
1097
1097
  | `value` | String | Chosen day `YYYY-MM-DD` |
1098
1098
  | `today` | String | The underlined day; the browser's day when missing |
1099
1099
  | `marks` | JSON | `{ date: tone \| { tone, disabled } }` — tone `primary` / `success` / `warning` / `error`; `disabled` makes the chip unpickable |
1100
- | `locale` | String | BCP 47 tag for the names; the browser language when missing |
1100
+ | `locale` | String | BCP 47 tag for the names; without it the page language — the `lang` of the nearest ancestor, usually `<html lang>`, also across shadow roots — else the browser language (page language since 1.19.2) |
1101
1101
  | `label` | String | `aria-label` of the group |
1102
1102
 
1103
1103
  Event: `glk-change { value }` — only on a change made by the user. Properties: `value`, `marks` (object or JSON text), `locale`, `label`. Part: `strip`.
@@ -1120,7 +1120,7 @@ One month with a day to pick (since 1.16.0). The days are buttons in a `role="gr
1120
1120
  | `today` | String | The day with the warm border; the browser's day when missing |
1121
1121
  | `min`, `max` | String | Days outside cannot be picked |
1122
1122
  | `marks` | JSON | `{ date: tone \| [tone, …] }` — up to three tones per day |
1123
- | `locale` | String | BCP 47 tag for names and week start; the browser language when missing |
1123
+ | `locale` | String | BCP 47 tag for names and week start; without it the page language — the `lang` of the nearest ancestor, usually `<html lang>`, also across shadow roots — else the browser language (page language since 1.19.2) |
1124
1124
  | `week-start` | Number | 0 = Sunday … 6 = Saturday; from the locale when missing |
1125
1125
  | `label` | String | `aria-label` of the day group |
1126
1126
  | `prev-label`, `next-label` | String | Names of the nav buttons ("Previous month" / "Next month") |
@@ -1,5 +1,5 @@
1
1
  import { GlkFormElement } from './base.js';
2
- import { i as isoDate, r as resolveLocale, f as formatters, p as parseIso, a as firstWeekday, b as parseJsonObject, w as weekdayShort, c as addDays, d as isTone } from './shared/dates-CNWaJf09.js';
2
+ import { i as isoDate, r as resolveLocale, f as formatters, p as parseIso, a as firstWeekday, b as parseJsonObject, w as weekdayShort, c as addDays, d as isTone } from './shared/dates-D4JTqoiG.js';
3
3
  import '@jungherz-de/glasskit/glasskit-styles.js';
4
4
 
5
5
  // One month with a day to pick. Came back from EhrenPfoten in 1.16.0.
@@ -8,7 +8,7 @@ import '@jungherz-de/glasskit/glasskit-styles.js';
8
8
  // today), value (YYYY-MM-DD), today (YYYY-MM-DD), min, max
9
9
  // (YYYY-MM-DD; days outside cannot be picked), marks (JSON
10
10
  // {date: tone | [tone, …]}, up to three dots), locale (default
11
- // the browser language), week-start (0 = Sunday … 6 = Saturday;
11
+ // the page language, else the browser's), week-start (0 = Sunday … 6 = Saturday;
12
12
  // default from the locale, Monday where the browser cannot say),
13
13
  // label (aria-label of the day group), prev-label / next-label
14
14
  // (names of the nav buttons, English by default)
@@ -66,7 +66,7 @@ class GlkCalendar extends GlkFormElement {
66
66
  get _todayIso() { return this.getAttribute('today') || isoDate(new Date()); }
67
67
 
68
68
  _build() {
69
- const locale = resolveLocale(this.getAttribute('locale'));
69
+ const locale = resolveLocale(this.getAttribute('locale'), this);
70
70
  const f = formatters(locale);
71
71
  const month = this.month;
72
72
  const first = parseIso(month);
@@ -243,7 +243,7 @@ class GlkCalendar extends GlkFormElement {
243
243
  get marks() { return parseJsonObject(this.getAttribute('marks')); }
244
244
  set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
245
245
 
246
- get locale() { return resolveLocale(this.getAttribute('locale')); }
246
+ get locale() { return resolveLocale(this.getAttribute('locale'), this); }
247
247
  set locale(v) {
248
248
  if (v) this.setAttribute('locale', v);
249
249
  else this.removeAttribute('locale');
@@ -1,5 +1,5 @@
1
1
  import { GlkElement } from './base.js';
2
- import { f as formatters, r as resolveLocale, b as parseJsonObject, p as parseIso, i as isoDate, c as addDays, w as weekdayShort, d as isTone } from './shared/dates-CNWaJf09.js';
2
+ import { f as formatters, r as resolveLocale, b as parseJsonObject, p as parseIso, i as isoDate, c as addDays, w as weekdayShort, d as isTone } from './shared/dates-D4JTqoiG.js';
3
3
  import { r as revealCentered } from './shared/reveal-CjjzoxTa.js';
4
4
  import '@jungherz-de/glasskit/glasskit-styles.js';
5
5
 
@@ -9,7 +9,8 @@ import '@jungherz-de/glasskit/glasskit-styles.js';
9
9
  // Attributes: start (YYYY-MM-DD, default today), days (count, default 7),
10
10
  // value (YYYY-MM-DD), today (YYYY-MM-DD, default the browser's
11
11
  // day), marks (JSON {date: tone | {tone, disabled}}), locale
12
- // (default the browser language), label (aria-label of the group)
12
+ // (default the page language, else the browser's), label
13
+ // (aria-label of the group)
13
14
  // Properties: value, marks (object or JSON text), locale, label
14
15
  // Event: glk-change { value } — only on a change made by the user
15
16
  // Part: strip
@@ -42,7 +43,7 @@ class GlkDateStrip extends GlkElement {
42
43
  }
43
44
 
44
45
  _build() {
45
- const f = formatters(resolveLocale(this.getAttribute('locale')));
46
+ const f = formatters(resolveLocale(this.getAttribute('locale'), this));
46
47
  const marks = parseJsonObject(this.getAttribute('marks'));
47
48
  const start = parseIso(this.getAttribute('start')) ?? new Date();
48
49
  const today = this.getAttribute('today') || isoDate(new Date());
@@ -154,7 +155,7 @@ class GlkDateStrip extends GlkElement {
154
155
  get marks() { return parseJsonObject(this.getAttribute('marks')); }
155
156
  set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
156
157
 
157
- get locale() { return resolveLocale(this.getAttribute('locale')); }
158
+ get locale() { return resolveLocale(this.getAttribute('locale'), this); }
158
159
  set locale(v) {
159
160
  if (v) this.setAttribute('locale', v);
160
161
  else this.removeAttribute('locale');
@@ -1,8 +1,8 @@
1
1
  // Date helpers shared by <glk-date-strip> and <glk-calendar>. Everything
2
2
  // works on local calendar days — a date is "YYYY-MM-DD" in the element API
3
3
  // and a local Date inside — so a day never shifts across midnight the way a
4
- // UTC timestamp would. Names come from Intl, keyed by the element's locale
5
- // attribute or the browser language.
4
+ // UTC timestamp would. Names come from Intl, in the language resolveLocale()
5
+ // finds for the element.
6
6
 
7
7
  const pad = n => String(n).padStart(2, '0');
8
8
 
@@ -30,8 +30,29 @@ function parseJsonObject(text) {
30
30
  }
31
31
  }
32
32
 
33
- function resolveLocale(attr) {
34
- return attr || (typeof navigator !== 'undefined' && navigator.language) || 'en';
33
+ /**
34
+ * The language to name days and months in: the element's locale attribute;
35
+ * else the language of the page around it — the lang of the nearest
36
+ * ancestor, looked up across shadow roots through their hosts, so
37
+ * <html lang="de"> reaches an element inside another component's shadow
38
+ * tree and a <section lang="en"> in a German page stays English; else the
39
+ * browser's; else English. An empty lang means "unknown" in HTML and falls
40
+ * through to the browser's language. (Since 1.19.2 — before, the browser's
41
+ * language came right after the attribute.)
42
+ */
43
+ function resolveLocale(attr, el) {
44
+ if (attr) return attr;
45
+ for (let node = el; node; ) {
46
+ const tagged = node.closest?.('[lang]');
47
+ if (tagged) {
48
+ const lang = tagged.getAttribute('lang').trim();
49
+ if (lang) return lang;
50
+ break;
51
+ }
52
+ const root = node.getRootNode?.();
53
+ node = typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot ? root.host : null;
54
+ }
55
+ return (typeof navigator !== 'undefined' && navigator.language) || 'en';
35
56
  }
36
57
 
37
58
  // Intl formatters are cheap to keep and not to make; one set per locale.
@@ -692,8 +692,8 @@ customElements.define('glk-steps', GlkSteps);
692
692
  // Date helpers shared by <glk-date-strip> and <glk-calendar>. Everything
693
693
  // works on local calendar days — a date is "YYYY-MM-DD" in the element API
694
694
  // and a local Date inside — so a day never shifts across midnight the way a
695
- // UTC timestamp would. Names come from Intl, keyed by the element's locale
696
- // attribute or the browser language.
695
+ // UTC timestamp would. Names come from Intl, in the language resolveLocale()
696
+ // finds for the element.
697
697
 
698
698
  const pad = n => String(n).padStart(2, '0');
699
699
 
@@ -721,8 +721,29 @@ function parseJsonObject(text) {
721
721
  }
722
722
  }
723
723
 
724
- function resolveLocale(attr) {
725
- return attr || (typeof navigator !== 'undefined' && navigator.language) || 'en';
724
+ /**
725
+ * The language to name days and months in: the element's locale attribute;
726
+ * else the language of the page around it — the lang of the nearest
727
+ * ancestor, looked up across shadow roots through their hosts, so
728
+ * <html lang="de"> reaches an element inside another component's shadow
729
+ * tree and a <section lang="en"> in a German page stays English; else the
730
+ * browser's; else English. An empty lang means "unknown" in HTML and falls
731
+ * through to the browser's language. (Since 1.19.2 — before, the browser's
732
+ * language came right after the attribute.)
733
+ */
734
+ function resolveLocale(attr, el) {
735
+ if (attr) return attr;
736
+ for (let node = el; node; ) {
737
+ const tagged = node.closest?.('[lang]');
738
+ if (tagged) {
739
+ const lang = tagged.getAttribute('lang').trim();
740
+ if (lang) return lang;
741
+ break;
742
+ }
743
+ const root = node.getRootNode?.();
744
+ node = typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot ? root.host : null;
745
+ }
746
+ return (typeof navigator !== 'undefined' && navigator.language) || 'en';
726
747
  }
727
748
 
728
749
  // Intl formatters are cheap to keep and not to make; one set per locale.
@@ -790,7 +811,8 @@ function revealCentered(scroller, item, smooth) {
790
811
  // Attributes: start (YYYY-MM-DD, default today), days (count, default 7),
791
812
  // value (YYYY-MM-DD), today (YYYY-MM-DD, default the browser's
792
813
  // day), marks (JSON {date: tone | {tone, disabled}}), locale
793
- // (default the browser language), label (aria-label of the group)
814
+ // (default the page language, else the browser's), label
815
+ // (aria-label of the group)
794
816
  // Properties: value, marks (object or JSON text), locale, label
795
817
  // Event: glk-change { value } — only on a change made by the user
796
818
  // Part: strip
@@ -823,7 +845,7 @@ class GlkDateStrip extends GlkElement {
823
845
  }
824
846
 
825
847
  _build() {
826
- const f = formatters(resolveLocale(this.getAttribute('locale')));
848
+ const f = formatters(resolveLocale(this.getAttribute('locale'), this));
827
849
  const marks = parseJsonObject(this.getAttribute('marks'));
828
850
  const start = parseIso(this.getAttribute('start')) ?? new Date();
829
851
  const today = this.getAttribute('today') || isoDate(new Date());
@@ -935,7 +957,7 @@ class GlkDateStrip extends GlkElement {
935
957
  get marks() { return parseJsonObject(this.getAttribute('marks')); }
936
958
  set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
937
959
 
938
- get locale() { return resolveLocale(this.getAttribute('locale')); }
960
+ get locale() { return resolveLocale(this.getAttribute('locale'), this); }
939
961
  set locale(v) {
940
962
  if (v) this.setAttribute('locale', v);
941
963
  else this.removeAttribute('locale');
@@ -2487,7 +2509,7 @@ customElements.define('glk-segmented', GlkSegmented);
2487
2509
  // today), value (YYYY-MM-DD), today (YYYY-MM-DD), min, max
2488
2510
  // (YYYY-MM-DD; days outside cannot be picked), marks (JSON
2489
2511
  // {date: tone | [tone, …]}, up to three dots), locale (default
2490
- // the browser language), week-start (0 = Sunday … 6 = Saturday;
2512
+ // the page language, else the browser's), week-start (0 = Sunday … 6 = Saturday;
2491
2513
  // default from the locale, Monday where the browser cannot say),
2492
2514
  // label (aria-label of the day group), prev-label / next-label
2493
2515
  // (names of the nav buttons, English by default)
@@ -2545,7 +2567,7 @@ class GlkCalendar extends GlkFormElement {
2545
2567
  get _todayIso() { return this.getAttribute('today') || isoDate(new Date()); }
2546
2568
 
2547
2569
  _build() {
2548
- const locale = resolveLocale(this.getAttribute('locale'));
2570
+ const locale = resolveLocale(this.getAttribute('locale'), this);
2549
2571
  const f = formatters(locale);
2550
2572
  const month = this.month;
2551
2573
  const first = parseIso(month);
@@ -2722,7 +2744,7 @@ class GlkCalendar extends GlkFormElement {
2722
2744
  get marks() { return parseJsonObject(this.getAttribute('marks')); }
2723
2745
  set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
2724
2746
 
2725
- get locale() { return resolveLocale(this.getAttribute('locale')); }
2747
+ get locale() { return resolveLocale(this.getAttribute('locale'), this); }
2726
2748
  set locale(v) {
2727
2749
  if (v) this.setAttribute('locale', v);
2728
2750
  else this.removeAttribute('locale');
@@ -695,8 +695,8 @@ var GlassKitElements = (function (exports) {
695
695
  // Date helpers shared by <glk-date-strip> and <glk-calendar>. Everything
696
696
  // works on local calendar days — a date is "YYYY-MM-DD" in the element API
697
697
  // and a local Date inside — so a day never shifts across midnight the way a
698
- // UTC timestamp would. Names come from Intl, keyed by the element's locale
699
- // attribute or the browser language.
698
+ // UTC timestamp would. Names come from Intl, in the language resolveLocale()
699
+ // finds for the element.
700
700
 
701
701
  const pad = n => String(n).padStart(2, '0');
702
702
 
@@ -724,8 +724,29 @@ var GlassKitElements = (function (exports) {
724
724
  }
725
725
  }
726
726
 
727
- function resolveLocale(attr) {
728
- return attr || (typeof navigator !== 'undefined' && navigator.language) || 'en';
727
+ /**
728
+ * The language to name days and months in: the element's locale attribute;
729
+ * else the language of the page around it — the lang of the nearest
730
+ * ancestor, looked up across shadow roots through their hosts, so
731
+ * <html lang="de"> reaches an element inside another component's shadow
732
+ * tree and a <section lang="en"> in a German page stays English; else the
733
+ * browser's; else English. An empty lang means "unknown" in HTML and falls
734
+ * through to the browser's language. (Since 1.19.2 — before, the browser's
735
+ * language came right after the attribute.)
736
+ */
737
+ function resolveLocale(attr, el) {
738
+ if (attr) return attr;
739
+ for (let node = el; node; ) {
740
+ const tagged = node.closest?.('[lang]');
741
+ if (tagged) {
742
+ const lang = tagged.getAttribute('lang').trim();
743
+ if (lang) return lang;
744
+ break;
745
+ }
746
+ const root = node.getRootNode?.();
747
+ node = typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot ? root.host : null;
748
+ }
749
+ return (typeof navigator !== 'undefined' && navigator.language) || 'en';
729
750
  }
730
751
 
731
752
  // Intl formatters are cheap to keep and not to make; one set per locale.
@@ -793,7 +814,8 @@ var GlassKitElements = (function (exports) {
793
814
  // Attributes: start (YYYY-MM-DD, default today), days (count, default 7),
794
815
  // value (YYYY-MM-DD), today (YYYY-MM-DD, default the browser's
795
816
  // day), marks (JSON {date: tone | {tone, disabled}}), locale
796
- // (default the browser language), label (aria-label of the group)
817
+ // (default the page language, else the browser's), label
818
+ // (aria-label of the group)
797
819
  // Properties: value, marks (object or JSON text), locale, label
798
820
  // Event: glk-change { value } — only on a change made by the user
799
821
  // Part: strip
@@ -826,7 +848,7 @@ var GlassKitElements = (function (exports) {
826
848
  }
827
849
 
828
850
  _build() {
829
- const f = formatters(resolveLocale(this.getAttribute('locale')));
851
+ const f = formatters(resolveLocale(this.getAttribute('locale'), this));
830
852
  const marks = parseJsonObject(this.getAttribute('marks'));
831
853
  const start = parseIso(this.getAttribute('start')) ?? new Date();
832
854
  const today = this.getAttribute('today') || isoDate(new Date());
@@ -938,7 +960,7 @@ var GlassKitElements = (function (exports) {
938
960
  get marks() { return parseJsonObject(this.getAttribute('marks')); }
939
961
  set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
940
962
 
941
- get locale() { return resolveLocale(this.getAttribute('locale')); }
963
+ get locale() { return resolveLocale(this.getAttribute('locale'), this); }
942
964
  set locale(v) {
943
965
  if (v) this.setAttribute('locale', v);
944
966
  else this.removeAttribute('locale');
@@ -2490,7 +2512,7 @@ var GlassKitElements = (function (exports) {
2490
2512
  // today), value (YYYY-MM-DD), today (YYYY-MM-DD), min, max
2491
2513
  // (YYYY-MM-DD; days outside cannot be picked), marks (JSON
2492
2514
  // {date: tone | [tone, …]}, up to three dots), locale (default
2493
- // the browser language), week-start (0 = Sunday … 6 = Saturday;
2515
+ // the page language, else the browser's), week-start (0 = Sunday … 6 = Saturday;
2494
2516
  // default from the locale, Monday where the browser cannot say),
2495
2517
  // label (aria-label of the day group), prev-label / next-label
2496
2518
  // (names of the nav buttons, English by default)
@@ -2548,7 +2570,7 @@ var GlassKitElements = (function (exports) {
2548
2570
  get _todayIso() { return this.getAttribute('today') || isoDate(new Date()); }
2549
2571
 
2550
2572
  _build() {
2551
- const locale = resolveLocale(this.getAttribute('locale'));
2573
+ const locale = resolveLocale(this.getAttribute('locale'), this);
2552
2574
  const f = formatters(locale);
2553
2575
  const month = this.month;
2554
2576
  const first = parseIso(month);
@@ -2725,7 +2747,7 @@ var GlassKitElements = (function (exports) {
2725
2747
  get marks() { return parseJsonObject(this.getAttribute('marks')); }
2726
2748
  set marks(v) { this.setAttribute('marks', typeof v === 'string' ? v : JSON.stringify(v ?? {})); }
2727
2749
 
2728
- get locale() { return resolveLocale(this.getAttribute('locale')); }
2750
+ get locale() { return resolveLocale(this.getAttribute('locale'), this); }
2729
2751
  set locale(v) {
2730
2752
  if (v) this.setAttribute('locale', v);
2731
2753
  else this.removeAttribute('locale');