@jungherz-de/glasskit-elements 1.22.2 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jungherz-de/glasskit-elements",
3
- "version": "1.22.2",
3
+ "version": "1.23.0",
4
4
  "description": "Vanilla JavaScript Web Components wrapping the GlassKit CSS glassmorphism library",
5
5
  "license": "MIT",
6
6
  "homepage": "https://glasskit-elements.jungherz.com",
@@ -49,10 +49,10 @@
49
49
  "vanilla-js"
50
50
  ],
51
51
  "peerDependencies": {
52
- "@jungherz-de/glasskit": ">=1.22.2"
52
+ "@jungherz-de/glasskit": ">=1.23.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@jungherz-de/glasskit": "^1.22.2",
55
+ "@jungherz-de/glasskit": "^1.23.0",
56
56
  "@rollup/plugin-node-resolve": "^15.0.0",
57
57
  "@rollup/plugin-terser": "^0.4.0",
58
58
  "rollup": "^4.0.0"
package/src/base.js CHANGED
@@ -238,6 +238,7 @@ export class GlkElement extends HTMLElement {
238
238
  this._shadow.appendChild(this._wrapper);
239
239
 
240
240
  this.render();
241
+ if (this.constructor.formAssociated) this._syncDisabled();
241
242
  } else {
242
243
  // Back in the document. While it was out, the observer did not reach
243
244
  // it, so a theme or density switched in the meantime is caught up here
@@ -340,6 +341,28 @@ export class GlkElement extends HTMLElement {
340
341
  */
341
342
  refresh() { this.projectLightDom(); }
342
343
 
344
+ /**
345
+ * Form-associated elements only. Such an element is disabled by its own
346
+ * `disabled` attribute or by a <fieldset disabled> around it: the browser
347
+ * counts both — :disabled, left out of the form data — and calls
348
+ * formDisabledCallback() on every change, also when the element moves into
349
+ * or out of such a fieldset. The native controls sit in the shadow root,
350
+ * out of every fieldset's reach, so the state is handed on to them through
351
+ * applyDisabled(). Until 1.22.2 only the element's own attribute reached
352
+ * them: inside a disabled fieldset every field stayed usable, and a submit
353
+ * button sent the form.
354
+ */
355
+ get _actuallyDisabled() { return this.matches(':disabled'); }
356
+
357
+ formDisabledCallback() {
358
+ if (this._initialized) this._syncDisabled();
359
+ }
360
+
361
+ _syncDisabled() { this.applyDisabled(this._actuallyDisabled); }
362
+
363
+ /** Form-associated subclasses override to disable their native controls. */
364
+ applyDisabled(disabled) {}
365
+
343
366
  // ── Utility Methods ──
344
367
 
345
368
  /**
@@ -417,6 +440,17 @@ export class GlkFormElement extends GlkElement {
417
440
  if (this._initialized) this.syncValidity();
418
441
  }
419
442
 
443
+ // Reflects the attribute, as on a native control: a disabled fieldset
444
+ // around the element disables it without changing this.
445
+ get disabled() { return this.getBoolAttr('disabled'); }
446
+ set disabled(v) { this.setBoolAttr('disabled', v); }
447
+
448
+ _syncDisabled() {
449
+ super._syncDisabled();
450
+ // A disabled field is barred from validation; enabled again, it counts.
451
+ this.syncValidity();
452
+ }
453
+
420
454
  get form() { return this._internals.form; }
421
455
  get validationMessage() { return this._internals.validationMessage; }
422
456
  get validity() { return this._internals.validity; }
@@ -10,12 +10,13 @@ const FORWARDED_ARIA = ['aria-expanded', 'aria-haspopup', 'aria-pressed'];
10
10
 
11
11
  class GlkButton extends GlkElement {
12
12
  static get observedAttributes() {
13
- return ['variant', 'size', 'disabled', 'type', ...FORWARDED_ARIA];
13
+ return ['variant', 'size', 'type', ...FORWARDED_ARIA];
14
14
  }
15
15
 
16
16
  // The native button sits in the shadow root, outside every form. Form
17
17
  // association gives the element its form, so type="submit" and "reset"
18
- // can act on it (see _activateForm).
18
+ // can act on it (see _activateForm), and a disabled fieldset around it
19
+ // disables it (since 1.22.3; before, it still sent the form).
19
20
  static formAssociated = true;
20
21
 
21
22
  constructor() {
@@ -28,9 +29,6 @@ class GlkButton extends GlkElement {
28
29
  type: this.getAttribute('type') || 'button'
29
30
  });
30
31
 
31
- if (this.getBoolAttr('disabled')) {
32
- this._btn.disabled = true;
33
- }
34
32
  for (const attr of FORWARDED_ARIA) this._forward(attr);
35
33
 
36
34
  this._btn.appendChild(document.createElement('slot'));
@@ -39,7 +37,7 @@ class GlkButton extends GlkElement {
39
37
 
40
38
  setupEvents() {
41
39
  this._onClick = (e) => {
42
- if (this.getBoolAttr('disabled')) {
40
+ if (this._actuallyDisabled) {
43
41
  e.preventDefault();
44
42
  e.stopPropagation();
45
43
  return;
@@ -98,9 +96,6 @@ class GlkButton extends GlkElement {
98
96
  case 'size':
99
97
  this._btn.className = this._computeClasses().join(' ');
100
98
  break;
101
- case 'disabled':
102
- this._btn.disabled = this.getBoolAttr('disabled');
103
- break;
104
99
  case 'type':
105
100
  this._btn.setAttribute('type', this.getAttribute('type') || 'button');
106
101
  break;
@@ -109,6 +104,8 @@ class GlkButton extends GlkElement {
109
104
  }
110
105
  }
111
106
 
107
+ applyDisabled(disabled) { this._btn.disabled = disabled; }
108
+
112
109
  _forward(attr) {
113
110
  const value = this.getAttribute(attr);
114
111
  if (value === null) this._btn.removeAttribute(attr);
@@ -10,8 +10,9 @@ import { isoDate, parseIso, addDays, parseJsonObject, resolveLocale, formatters,
10
10
  // the page language, else the browser's), week-start (0 = Sunday … 6 = Saturday;
11
11
  // default from the locale, Monday where the browser cannot say),
12
12
  // label (aria-label of the day group), prev-label / next-label
13
- // (names of the nav buttons, English by default)
14
- // Properties: month, value, marks, locale, label
13
+ // (names of the nav buttons, English by default), disabled
14
+ // (since 1.22.3, as is a disabled fieldset around it)
15
+ // Properties: month, value, marks, locale, label, disabled
15
16
  // Form: associated — a surrounding <form> receives name=value, reset
16
17
  // restores the initial value, like <glk-segmented>
17
18
  // Events: glk-change { value } — on a pick by the user
@@ -103,9 +104,16 @@ class GlkCalendar extends GlkFormElement {
103
104
  day.append(num, dots);
104
105
  this._grid.appendChild(day);
105
106
  }
107
+ this.applyDisabled(this._actuallyDisabled);
106
108
  this._syncValue();
107
109
  }
108
110
 
111
+ // Disabled as a whole: the arrows and every day. The days of another month
112
+ // are built again, so _build() hands the state on to them too.
113
+ applyDisabled(disabled) {
114
+ for (const button of [this._prev, this._next, ...this._days()]) button.disabled = disabled;
115
+ }
116
+
109
117
  _days() { return [...this._grid.querySelectorAll('button[data-value]')]; }
110
118
  _dayFor(iso) { return this._grid.querySelector(`button[data-value="${iso}"]`); }
111
119
 
@@ -4,7 +4,7 @@ const CHECKMARK_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor
4
4
 
5
5
  class GlkCheckbox extends GlkFormElement {
6
6
  static get observedAttributes() {
7
- return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
7
+ return ['checked', 'label', 'name', 'value', 'required'];
8
8
  }
9
9
 
10
10
  static get hostStyles() { return checkControlSheet; }
@@ -30,7 +30,6 @@ class GlkCheckbox extends GlkFormElement {
30
30
  label.appendChild(this._labelEl);
31
31
 
32
32
  if (this.getBoolAttr('checked')) this._input.checked = true;
33
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
34
33
  if (this.getBoolAttr('required')) this._input.required = true;
35
34
 
36
35
  this._defaultChecked = this.getBoolAttr('checked');
@@ -64,9 +63,6 @@ class GlkCheckbox extends GlkFormElement {
64
63
  this._input.checked = this.getBoolAttr('checked');
65
64
  this._syncFormValue();
66
65
  break;
67
- case 'disabled':
68
- this._input.disabled = this.getBoolAttr('disabled');
69
- break;
70
66
  case 'label':
71
67
  this._labelEl.textContent = this.getAttribute('label') || '';
72
68
  break;
@@ -79,6 +75,8 @@ class GlkCheckbox extends GlkFormElement {
79
75
  }
80
76
  }
81
77
 
78
+ applyDisabled(disabled) { this._input.disabled = disabled; }
79
+
82
80
  get _validityField() { return this._input; }
83
81
 
84
82
  _syncFormValue() {
@@ -100,9 +98,6 @@ class GlkCheckbox extends GlkFormElement {
100
98
  if (this._input) this._syncFormValue();
101
99
  }
102
100
 
103
- get disabled() { return this.getBoolAttr('disabled'); }
104
- set disabled(v) { this.setBoolAttr('disabled', v); }
105
-
106
101
  get name() { return this.getAttribute('name'); }
107
102
  set name(v) { this.setAttribute('name', v); }
108
103
 
@@ -32,7 +32,7 @@ affixSheet.replaceSync(`
32
32
 
33
33
  class GlkInput extends GlkFormElement {
34
34
  static get observedAttributes() {
35
- return ['label', 'type', 'placeholder', 'error', 'hint', 'disabled', 'readonly', 'name', 'value', 'required', ...FORWARDED];
35
+ return ['label', 'type', 'placeholder', 'error', 'hint', 'readonly', 'name', 'value', 'required', ...FORWARDED];
36
36
  }
37
37
 
38
38
  static get hostStyles() { return affixSheet; }
@@ -63,7 +63,6 @@ class GlkInput extends GlkFormElement {
63
63
  this._pendingValue = undefined;
64
64
  if (value) this._input.value = value;
65
65
 
66
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
67
66
  if (this.getBoolAttr('readonly')) this._input.readOnly = true;
68
67
  if (this.getBoolAttr('required')) this._input.required = true;
69
68
  for (const attr of FORWARDED) this._forward(attr);
@@ -153,9 +152,6 @@ class GlkInput extends GlkFormElement {
153
152
  }
154
153
  this._applyDescription();
155
154
  break;
156
- case 'disabled':
157
- this._input.disabled = this.getBoolAttr('disabled');
158
- break;
159
155
  case 'readonly':
160
156
  this._input.readOnly = this.getBoolAttr('readonly');
161
157
  break;
@@ -174,6 +170,8 @@ class GlkInput extends GlkFormElement {
174
170
  }
175
171
  }
176
172
 
173
+ applyDisabled(disabled) { this._input.disabled = disabled; }
174
+
177
175
  /** An affix shows, and makes room in the field, only while something is slotted. */
178
176
  _applyAffixes() {
179
177
  for (const affix of [this._prefix, this._suffix]) {
@@ -239,9 +237,6 @@ class GlkInput extends GlkFormElement {
239
237
  this._syncFormValue();
240
238
  }
241
239
 
242
- get disabled() { return this.getBoolAttr('disabled'); }
243
- set disabled(v) { this.setBoolAttr('disabled', v); }
244
-
245
240
  get readOnly() { return this.getBoolAttr('readonly'); }
246
241
  set readOnly(v) { this.setBoolAttr('readonly', v); }
247
242
 
@@ -19,7 +19,7 @@ function ownerForm(el) {
19
19
 
20
20
  /** Only the selected radio is a tab stop; arrow keys move within the group. */
21
21
  function syncGroupTabIndex(group) {
22
- const enabled = group.filter(el => !el.disabled);
22
+ const enabled = group.filter(el => !el._actuallyDisabled);
23
23
  if (!enabled.length) return;
24
24
  const focusable = enabled.find(el => el.checked) || enabled[0];
25
25
  for (const el of group) {
@@ -29,7 +29,7 @@ function syncGroupTabIndex(group) {
29
29
 
30
30
  class GlkRadio extends GlkFormElement {
31
31
  static get observedAttributes() {
32
- return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
32
+ return ['checked', 'label', 'name', 'value', 'required'];
33
33
  }
34
34
 
35
35
  static get hostStyles() { return checkControlSheet; }
@@ -59,7 +59,6 @@ class GlkRadio extends GlkFormElement {
59
59
  label.appendChild(this._labelEl);
60
60
 
61
61
  if (this.getBoolAttr('checked')) this._input.checked = true;
62
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
63
62
 
64
63
  this._defaultChecked = this.getBoolAttr('checked');
65
64
  this._wrapper.appendChild(label);
@@ -77,7 +76,7 @@ class GlkRadio extends GlkFormElement {
77
76
  this._onKeyDown = (e) => {
78
77
  const dir = ARROW_KEYS[e.key];
79
78
  if (!dir || e.ctrlKey || e.metaKey || e.altKey) return;
80
- const group = this._group().filter(el => !el.disabled);
79
+ const group = this._group().filter(el => !el._actuallyDisabled);
81
80
  if (group.length < 2) return;
82
81
  e.preventDefault();
83
82
  const next = group[(group.indexOf(this) + dir + group.length) % group.length];
@@ -159,10 +158,6 @@ class GlkRadio extends GlkFormElement {
159
158
  this._syncFormValue();
160
159
  syncGroupTabIndex(this._group());
161
160
  break;
162
- case 'disabled':
163
- this._input.disabled = this.getBoolAttr('disabled');
164
- syncGroupTabIndex(this._group());
165
- break;
166
161
  case 'label':
167
162
  this._labelEl.textContent = this.getAttribute('label') || '';
168
163
  break;
@@ -177,6 +172,11 @@ class GlkRadio extends GlkFormElement {
177
172
  }
178
173
  }
179
174
 
175
+ applyDisabled(disabled) {
176
+ this._input.disabled = disabled;
177
+ syncGroupTabIndex(this._group());
178
+ }
179
+
180
180
  _syncFormValue() {
181
181
  const val = this.getAttribute('value') || '';
182
182
  this.setFormValue(this._input.checked ? val : null);
@@ -201,9 +201,6 @@ class GlkRadio extends GlkFormElement {
201
201
  syncGroupTabIndex(this._group());
202
202
  }
203
203
 
204
- get disabled() { return this.getBoolAttr('disabled'); }
205
- set disabled(v) { this.setBoolAttr('disabled', v); }
206
-
207
204
  get name() { return this.getAttribute('name'); }
208
205
  set name(v) { this.setAttribute('name', v); }
209
206
 
@@ -2,7 +2,7 @@ import { GlkFormElement } from '../../base.js';
2
2
 
3
3
  class GlkRange extends GlkFormElement {
4
4
  static get observedAttributes() {
5
- return ['label', 'min', 'max', 'value', 'step', 'name', 'disabled'];
5
+ return ['label', 'min', 'max', 'value', 'step', 'name'];
6
6
  }
7
7
 
8
8
  render() {
@@ -33,8 +33,6 @@ class GlkRange extends GlkFormElement {
33
33
  const name = this.getAttribute('name');
34
34
  if (name) this._input.setAttribute('name', name);
35
35
 
36
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
37
-
38
36
  // The reset value is the attribute's; a value set as a property before
39
37
  // render() has waited for it and comes on top.
40
38
  this._defaultValue = this._input.value;
@@ -86,12 +84,11 @@ class GlkRange extends GlkFormElement {
86
84
  case 'name':
87
85
  this._input.setAttribute('name', this.getAttribute('name') || '');
88
86
  break;
89
- case 'disabled':
90
- this._input.disabled = this.getBoolAttr('disabled');
91
- break;
92
87
  }
93
88
  }
94
89
 
90
+ applyDisabled(disabled) { this._input.disabled = disabled; }
91
+
95
92
  _updateValueDisplay() {
96
93
  this._valueEl.textContent = `${this._input.value}%`;
97
94
  }
@@ -4,7 +4,7 @@ const SEARCH_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" s
4
4
 
5
5
  class GlkSearch extends GlkFormElement {
6
6
  static get observedAttributes() {
7
- return ['placeholder', 'name', 'value', 'disabled', 'label'];
7
+ return ['placeholder', 'name', 'value', 'label'];
8
8
  }
9
9
 
10
10
  render() {
@@ -32,8 +32,6 @@ class GlkSearch extends GlkFormElement {
32
32
  this._pendingValue = undefined;
33
33
  if (value) this._input.value = value;
34
34
 
35
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
36
-
37
35
  container.appendChild(icon);
38
36
  container.appendChild(this._input);
39
37
 
@@ -67,15 +65,14 @@ class GlkSearch extends GlkFormElement {
67
65
  this._input.value = this.getAttribute('value') || '';
68
66
  this._syncFormValue();
69
67
  break;
70
- case 'disabled':
71
- this._input.disabled = this.getBoolAttr('disabled');
72
- break;
73
68
  case 'label':
74
69
  this._applyLabel();
75
70
  break;
76
71
  }
77
72
  }
78
73
 
74
+ applyDisabled(disabled) { this._input.disabled = disabled; }
75
+
79
76
  _applyLabel() {
80
77
  const label = this.getAttribute('label');
81
78
  if (label) this._input.setAttribute('aria-label', label);
@@ -7,8 +7,11 @@ import { revealCentered } from '../../reveal.js';
7
7
  // Attributes: options (JSON [{value,label,tone?,disabled?}]), value, full,
8
8
  // overflow ("scroll" | "wrap": what happens when the options
9
9
  // do not fit — without it the row stays one line and runs past
10
- // the edge), label (aria-label of the group), name (form field)
11
- // Properties: value, options (array or JSON text), full, overflow, label
10
+ // the edge), label (aria-label of the group), name (form field),
11
+ // disabled (the whole row; since 1.22.3, as is a disabled
12
+ // fieldset around it)
13
+ // Properties: value, options (array or JSON text), full, overflow, label,
14
+ // disabled
12
15
  // Event: glk-change { value } — only on a change made by the user
13
16
  // Part: group
14
17
  //
@@ -61,13 +64,21 @@ class GlkSegmented extends GlkFormElement {
61
64
  button.classList.add(`glass-segmented__item--${option.tone}`);
62
65
  button.appendChild(this.createElement('span', ['glass-segmented__dot']));
63
66
  }
64
- if (option.disabled) button.disabled = true;
65
67
  button.appendChild(document.createTextNode(option.label ?? value));
66
68
  this._group.appendChild(button);
67
69
  }
70
+ this.applyDisabled(this._actuallyDisabled);
68
71
  this._syncValue();
69
72
  }
70
73
 
74
+ /** The whole row is disabled, or an option by its own `disabled`. */
75
+ applyDisabled(disabled) {
76
+ const options = this.options;
77
+ this._group.querySelectorAll('button[data-value]').forEach((button, i) => {
78
+ button.disabled = disabled || Boolean(options[i]?.disabled);
79
+ });
80
+ }
81
+
71
82
  _syncValue() {
72
83
  const value = this.value;
73
84
  for (const button of this._group.querySelectorAll('button[data-value]')) {
@@ -12,7 +12,7 @@ import { GlkFormElement } from '../../base.js';
12
12
 
13
13
  class GlkSelect extends GlkFormElement {
14
14
  static get observedAttributes() {
15
- return ['label', 'disabled', 'name', 'value', 'required'];
15
+ return ['label', 'name', 'value', 'required'];
16
16
  }
17
17
 
18
18
  static get observesLightDom() { return true; }
@@ -31,7 +31,6 @@ class GlkSelect extends GlkFormElement {
31
31
  const name = this.getAttribute('name');
32
32
  if (name) this._select.setAttribute('name', name);
33
33
 
34
- if (this.getBoolAttr('disabled')) this._select.disabled = true;
35
34
  if (this.getBoolAttr('required')) this._select.required = true;
36
35
 
37
36
  group.appendChild(this._labelEl);
@@ -105,9 +104,6 @@ class GlkSelect extends GlkFormElement {
105
104
  case 'label':
106
105
  this._labelEl.textContent = this.getAttribute('label') || '';
107
106
  break;
108
- case 'disabled':
109
- this._select.disabled = this.getBoolAttr('disabled');
110
- break;
111
107
  case 'name':
112
108
  this._select.setAttribute('name', this.getAttribute('name') || '');
113
109
  break;
@@ -122,6 +118,8 @@ class GlkSelect extends GlkFormElement {
122
118
  }
123
119
  }
124
120
 
121
+ applyDisabled(disabled) { this._select.disabled = disabled; }
122
+
125
123
  get _validityField() { return this._select; }
126
124
 
127
125
  _syncFormValue() {
@@ -147,9 +145,6 @@ class GlkSelect extends GlkFormElement {
147
145
  this._applyValue(this._wanted);
148
146
  this._syncFormValue();
149
147
  }
150
-
151
- get disabled() { return this.getBoolAttr('disabled'); }
152
- set disabled(v) { this.setBoolAttr('disabled', v); }
153
148
  }
154
149
 
155
150
  customElements.define('glk-select', GlkSelect);
@@ -2,7 +2,7 @@ import { GlkFormElement } from '../../base.js';
2
2
 
3
3
  class GlkTextarea extends GlkFormElement {
4
4
  static get observedAttributes() {
5
- return ['label', 'placeholder', 'rows', 'disabled', 'readonly', 'name', 'value', 'required'];
5
+ return ['label', 'placeholder', 'rows', 'readonly', 'name', 'value', 'required'];
6
6
  }
7
7
 
8
8
  render() {
@@ -27,7 +27,6 @@ class GlkTextarea extends GlkFormElement {
27
27
  this._pendingValue = undefined;
28
28
  if (value) this._textarea.value = value;
29
29
 
30
- if (this.getBoolAttr('disabled')) this._textarea.disabled = true;
31
30
  if (this.getBoolAttr('readonly')) this._textarea.readOnly = true;
32
31
  if (this.getBoolAttr('required')) this._textarea.required = true;
33
32
 
@@ -63,9 +62,6 @@ class GlkTextarea extends GlkFormElement {
63
62
  case 'rows':
64
63
  this._textarea.setAttribute('rows', this.getAttribute('rows') || '');
65
64
  break;
66
- case 'disabled':
67
- this._textarea.disabled = this.getBoolAttr('disabled');
68
- break;
69
65
  case 'readonly':
70
66
  this._textarea.readOnly = this.getBoolAttr('readonly');
71
67
  break;
@@ -82,6 +78,8 @@ class GlkTextarea extends GlkFormElement {
82
78
  }
83
79
  }
84
80
 
81
+ applyDisabled(disabled) { this._textarea.disabled = disabled; }
82
+
85
83
  get _validityField() { return this._textarea; }
86
84
 
87
85
  _syncFormValue() {
@@ -103,9 +101,6 @@ class GlkTextarea extends GlkFormElement {
103
101
  this._syncFormValue();
104
102
  }
105
103
 
106
- get disabled() { return this.getBoolAttr('disabled'); }
107
- set disabled(v) { this.setBoolAttr('disabled', v); }
108
-
109
104
  get readOnly() { return this.getBoolAttr('readonly'); }
110
105
  set readOnly(v) { this.setBoolAttr('readonly', v); }
111
106
  }
@@ -2,7 +2,7 @@ import { GlkFormElement, checkControlSheet, forwardHostClicks } from '../../base
2
2
 
3
3
  class GlkToggle extends GlkFormElement {
4
4
  static get observedAttributes() {
5
- return ['checked', 'disabled', 'label', 'name', 'value', 'required'];
5
+ return ['checked', 'label', 'name', 'value', 'required'];
6
6
  }
7
7
 
8
8
  static get hostStyles() { return checkControlSheet; }
@@ -34,7 +34,6 @@ class GlkToggle extends GlkFormElement {
34
34
  label.appendChild(this._labelEl);
35
35
 
36
36
  if (this.getBoolAttr('checked')) this._input.checked = true;
37
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
38
37
  if (this.getBoolAttr('required')) this._input.required = true;
39
38
 
40
39
  this._defaultChecked = this.getBoolAttr('checked');
@@ -69,9 +68,6 @@ class GlkToggle extends GlkFormElement {
69
68
  this._input.checked = this.getBoolAttr('checked');
70
69
  this._syncFormValue();
71
70
  break;
72
- case 'disabled':
73
- this._input.disabled = this.getBoolAttr('disabled');
74
- break;
75
71
  case 'label':
76
72
  this._labelEl.textContent = this.getAttribute('label') || '';
77
73
  break;
@@ -84,6 +80,8 @@ class GlkToggle extends GlkFormElement {
84
80
  }
85
81
  }
86
82
 
83
+ applyDisabled(disabled) { this._input.disabled = disabled; }
84
+
87
85
  get _validityField() { return this._input; }
88
86
 
89
87
  _syncFormValue() {
@@ -112,9 +110,6 @@ class GlkToggle extends GlkFormElement {
112
110
  if (this._input) this._syncFormValue();
113
111
  }
114
112
 
115
- get disabled() { return this.getBoolAttr('disabled'); }
116
- set disabled(v) { this.setBoolAttr('disabled', v); }
117
-
118
113
  get name() { return this.getAttribute('name'); }
119
114
  set name(v) { this.setAttribute('name', v); }
120
115