@jungherz-de/glasskit-elements 1.22.1 → 1.22.3

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.1",
3
+ "version": "1.22.3",
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.1"
52
+ "@jungherz-de/glasskit": ">=1.22.2"
53
53
  },
54
54
  "devDependencies": {
55
- "@jungherz-de/glasskit": "^1.22.1",
55
+ "@jungherz-de/glasskit": "^1.22.2",
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
 
@@ -9,19 +9,30 @@ const FORWARDED = ['min', 'max', 'step', 'minlength', 'maxlength', 'pattern', 'a
9
9
  // Prefix and suffix (since 1.22.0): two slots inside the field's box, on
10
10
  // GlassKit's .glass-input-wrap. An affix shows only while something is
11
11
  // slotted into it, and its width is measured, so the text keeps clear of a
12
- // unit of any length. GlassKit lets clicks through an affix to the field;
13
- // slotted elements take them here instead — a button or a link inside
14
- // works — and a click on slotted text or an icon still lands in the field,
15
- // because the shadow root delegates focus to it.
12
+ // unit of any length. As in GlassKit, a click on text, an icon or a disabled
13
+ // control goes through to the field, and what can be used takes its own: an
14
+ // enabled control (<glk-button>, <glk-select> … are form-associated, so they
15
+ // count), a link, an element with tabindex. GlassKit's own rule cannot reach
16
+ // slotted elements, hence this one. ::slotted() sees the slotted element,
17
+ // not what is inside it: a button wrapped in a slotted <span> needs
18
+ // pointer-events: auto from the page. Until 1.22.1 every slotted element took
19
+ // the pointer — a unit caught the click meant for the field, a disabled
20
+ // button took it and moved the focus into the field, read-only and locked
21
+ // or not. Simple selectors only inside ::slotted(), so that no browser drops
22
+ // the rule.
16
23
  const affixSheet = new CSSStyleSheet();
17
24
  affixSheet.replaceSync(`
18
- .glass-input-wrap__prefix ::slotted(*),
19
- .glass-input-wrap__suffix ::slotted(*) { pointer-events: auto; }
25
+ .glass-input-wrap__prefix ::slotted(:enabled),
26
+ .glass-input-wrap__prefix ::slotted(a[href]),
27
+ .glass-input-wrap__prefix ::slotted([tabindex]:not(:disabled)),
28
+ .glass-input-wrap__suffix ::slotted(:enabled),
29
+ .glass-input-wrap__suffix ::slotted(a[href]),
30
+ .glass-input-wrap__suffix ::slotted([tabindex]:not(:disabled)) { pointer-events: auto; }
20
31
  `);
21
32
 
22
33
  class GlkInput extends GlkFormElement {
23
34
  static get observedAttributes() {
24
- return ['label', 'type', 'placeholder', 'error', 'hint', 'disabled', 'readonly', 'name', 'value', 'required', ...FORWARDED];
35
+ return ['label', 'type', 'placeholder', 'error', 'hint', 'readonly', 'name', 'value', 'required', ...FORWARDED];
25
36
  }
26
37
 
27
38
  static get hostStyles() { return affixSheet; }
@@ -52,7 +63,6 @@ class GlkInput extends GlkFormElement {
52
63
  this._pendingValue = undefined;
53
64
  if (value) this._input.value = value;
54
65
 
55
- if (this.getBoolAttr('disabled')) this._input.disabled = true;
56
66
  if (this.getBoolAttr('readonly')) this._input.readOnly = true;
57
67
  if (this.getBoolAttr('required')) this._input.required = true;
58
68
  for (const attr of FORWARDED) this._forward(attr);
@@ -142,9 +152,6 @@ class GlkInput extends GlkFormElement {
142
152
  }
143
153
  this._applyDescription();
144
154
  break;
145
- case 'disabled':
146
- this._input.disabled = this.getBoolAttr('disabled');
147
- break;
148
155
  case 'readonly':
149
156
  this._input.readOnly = this.getBoolAttr('readonly');
150
157
  break;
@@ -163,6 +170,8 @@ class GlkInput extends GlkFormElement {
163
170
  }
164
171
  }
165
172
 
173
+ applyDisabled(disabled) { this._input.disabled = disabled; }
174
+
166
175
  /** An affix shows, and makes room in the field, only while something is slotted. */
167
176
  _applyAffixes() {
168
177
  for (const affix of [this._prefix, this._suffix]) {
@@ -228,9 +237,6 @@ class GlkInput extends GlkFormElement {
228
237
  this._syncFormValue();
229
238
  }
230
239
 
231
- get disabled() { return this.getBoolAttr('disabled'); }
232
- set disabled(v) { this.setBoolAttr('disabled', v); }
233
-
234
240
  get readOnly() { return this.getBoolAttr('readonly'); }
235
241
  set readOnly(v) { this.setBoolAttr('readonly', v); }
236
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