@jungherz-de/glasskit-elements 0.8.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.
Files changed (32) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +263 -0
  3. package/dist/glasskit-elements.esm.js +1789 -0
  4. package/dist/glasskit-elements.js +1819 -0
  5. package/dist/glasskit-elements.min.js +1 -0
  6. package/package.json +43 -0
  7. package/src/base.js +181 -0
  8. package/src/components/buttons/glk-button.js +80 -0
  9. package/src/components/containers/glk-accordion-item.js +61 -0
  10. package/src/components/containers/glk-accordion.js +12 -0
  11. package/src/components/content/glk-avatar.js +58 -0
  12. package/src/components/content/glk-badge.js +37 -0
  13. package/src/components/content/glk-card.js +33 -0
  14. package/src/components/content/glk-divider.js +11 -0
  15. package/src/components/content/glk-status.js +35 -0
  16. package/src/components/content/glk-title.js +16 -0
  17. package/src/components/feedback/glk-modal.js +98 -0
  18. package/src/components/feedback/glk-progress.js +77 -0
  19. package/src/components/feedback/glk-toast.js +104 -0
  20. package/src/components/forms/glk-checkbox.js +103 -0
  21. package/src/components/forms/glk-input.js +138 -0
  22. package/src/components/forms/glk-radio.js +109 -0
  23. package/src/components/forms/glk-range.js +112 -0
  24. package/src/components/forms/glk-search.js +87 -0
  25. package/src/components/forms/glk-select.js +96 -0
  26. package/src/components/forms/glk-textarea.js +95 -0
  27. package/src/components/forms/glk-toggle.js +121 -0
  28. package/src/components/navigation/glk-nav.js +12 -0
  29. package/src/components/navigation/glk-pill.js +48 -0
  30. package/src/components/navigation/glk-tab-bar.js +31 -0
  31. package/src/components/navigation/glk-tab-item.js +74 -0
  32. package/src/index.js +38 -0
@@ -0,0 +1,33 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ class GlkCard extends GlkElement {
4
+ static get observedAttributes() {
5
+ return ['glow'];
6
+ }
7
+
8
+ render() {
9
+ this._card = this.createElement('div', this._computeClasses());
10
+ this._card.appendChild(document.createElement('slot'));
11
+ this._wrapper.appendChild(this._card);
12
+ }
13
+
14
+ onAttributeChanged(name) {
15
+ if (name === 'glow' && this._card) {
16
+ this._card.className = this._computeClasses().join(' ');
17
+ }
18
+ }
19
+
20
+ _computeClasses() {
21
+ const classes = ['glass-card'];
22
+ if (this.getBoolAttr('glow')) {
23
+ classes.push('glass-card--glow');
24
+ }
25
+ return classes;
26
+ }
27
+
28
+ get glow() { return this.getBoolAttr('glow'); }
29
+ set glow(v) { this.setBoolAttr('glow', v); }
30
+ }
31
+
32
+ customElements.define('glk-card', GlkCard);
33
+ export { GlkCard };
@@ -0,0 +1,11 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ class GlkDivider extends GlkElement {
4
+ render() {
5
+ const hr = this.createElement('div', ['glass-divider']);
6
+ this._wrapper.appendChild(hr);
7
+ }
8
+ }
9
+
10
+ customElements.define('glk-divider', GlkDivider);
11
+ export { GlkDivider };
@@ -0,0 +1,35 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ class GlkStatus extends GlkElement {
4
+ static get observedAttributes() {
5
+ return ['message'];
6
+ }
7
+
8
+ render() {
9
+ this._container = this.createElement('div', ['glass-status']);
10
+
11
+ // Icon via slot
12
+ this._iconSlot = this.createElement('span', []);
13
+ this._iconSlot.appendChild(this.createElement('slot', [], { name: 'icon' }));
14
+
15
+ // Message
16
+ this._messageEl = this.createElement('p', []);
17
+ this._messageEl.textContent = this.getAttribute('message') || '';
18
+
19
+ this._container.appendChild(this._iconSlot);
20
+ this._container.appendChild(this._messageEl);
21
+ this._wrapper.appendChild(this._container);
22
+ }
23
+
24
+ onAttributeChanged(name) {
25
+ if (name === 'message' && this._messageEl) {
26
+ this._messageEl.textContent = this.getAttribute('message') || '';
27
+ }
28
+ }
29
+
30
+ get message() { return this.getAttribute('message'); }
31
+ set message(v) { this.setAttribute('message', v); }
32
+ }
33
+
34
+ customElements.define('glk-status', GlkStatus);
35
+ export { GlkStatus };
@@ -0,0 +1,16 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ class GlkTitle extends GlkElement {
4
+ static get observedAttributes() {
5
+ return [];
6
+ }
7
+
8
+ render() {
9
+ const el = this.createElement('div', ['glass-title']);
10
+ el.appendChild(document.createElement('slot'));
11
+ this._wrapper.appendChild(el);
12
+ }
13
+ }
14
+
15
+ customElements.define('glk-title', GlkTitle);
16
+ export { GlkTitle };
@@ -0,0 +1,98 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ class GlkModal extends GlkElement {
4
+ static get observedAttributes() {
5
+ return ['open', 'title'];
6
+ }
7
+
8
+ render() {
9
+ this._overlay = this.createElement('div', ['glass-modal-overlay']);
10
+
11
+ const modal = this.createElement('div', ['glass-modal']);
12
+
13
+ // Header
14
+ const header = this.createElement('div', ['glass-modal__header']);
15
+ this._titleEl = this.createElement('h2', ['glass-modal__title']);
16
+ this._titleEl.textContent = this.getAttribute('title') || '';
17
+ header.appendChild(this._titleEl);
18
+
19
+ // Body
20
+ const body = this.createElement('div', ['glass-modal__body']);
21
+ body.appendChild(document.createElement('slot'));
22
+
23
+ // Footer — clone action buttons from light DOM into shadow DOM
24
+ this._footer = this.createElement('div', ['glass-modal__footer']);
25
+ this._populateFooter();
26
+
27
+ modal.appendChild(header);
28
+ modal.appendChild(body);
29
+ modal.appendChild(this._footer);
30
+
31
+ this._overlay.appendChild(modal);
32
+ this._wrapper.appendChild(this._overlay);
33
+
34
+ if (this.getBoolAttr('open')) {
35
+ this._overlay.classList.add('is-active');
36
+ }
37
+ }
38
+
39
+ _populateFooter() {
40
+ this._footer.innerHTML = '';
41
+ const actionsSlot = this.querySelector('[slot="actions"]');
42
+ if (actionsSlot) {
43
+ const buttons = actionsSlot.querySelectorAll('button');
44
+ buttons.forEach(btn => {
45
+ const clone = btn.cloneNode(true);
46
+ // Forward click events to the original button
47
+ clone.addEventListener('click', () => btn.click());
48
+ this._footer.appendChild(clone);
49
+ });
50
+ }
51
+ }
52
+
53
+ setupEvents() {
54
+ // Close on overlay click (outside modal)
55
+ this._onOverlayClick = (e) => {
56
+ if (e.target === this._overlay) {
57
+ this.removeAttribute('open');
58
+ this.emit('glk-close');
59
+ }
60
+ };
61
+ this._overlay.addEventListener('click', this._onOverlayClick);
62
+
63
+ // Close on Escape
64
+ this._onKeydown = (e) => {
65
+ if (e.key === 'Escape' && this.getBoolAttr('open')) {
66
+ this.removeAttribute('open');
67
+ this.emit('glk-close');
68
+ }
69
+ };
70
+ document.addEventListener('keydown', this._onKeydown);
71
+ }
72
+
73
+ teardownEvents() {
74
+ this._overlay?.removeEventListener('click', this._onOverlayClick);
75
+ document.removeEventListener('keydown', this._onKeydown);
76
+ }
77
+
78
+ onAttributeChanged(name) {
79
+ if (!this._overlay) return;
80
+ switch (name) {
81
+ case 'open':
82
+ this._overlay.classList.toggle('is-active', this.getBoolAttr('open'));
83
+ break;
84
+ case 'title':
85
+ this._titleEl.textContent = this.getAttribute('title') || '';
86
+ break;
87
+ }
88
+ }
89
+
90
+ show() { this.setAttribute('open', ''); }
91
+ close() { this.removeAttribute('open'); }
92
+
93
+ get open() { return this.getBoolAttr('open'); }
94
+ set open(v) { this.setBoolAttr('open', v); }
95
+ }
96
+
97
+ customElements.define('glk-modal', GlkModal);
98
+ export { GlkModal };
@@ -0,0 +1,77 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ const VARIANTS = ['success', 'error'];
4
+ const SIZES = ['sm', 'lg'];
5
+
6
+ class GlkProgress extends GlkElement {
7
+ static get observedAttributes() {
8
+ return ['value', 'label', 'variant', 'size'];
9
+ }
10
+
11
+ render() {
12
+ this._container = this.createElement('div', this._computeClasses());
13
+
14
+ // Header
15
+ const header = this.createElement('div', ['glass-progress__header']);
16
+ this._labelEl = this.createElement('span', ['glass-progress__label']);
17
+ this._labelEl.textContent = this.getAttribute('label') || '';
18
+ this._valueEl = this.createElement('span', ['glass-progress__value']);
19
+
20
+ header.appendChild(this._labelEl);
21
+ header.appendChild(this._valueEl);
22
+
23
+ // Track
24
+ const track = this.createElement('div', ['glass-progress__track']);
25
+ this._fill = this.createElement('div', ['glass-progress__fill']);
26
+
27
+ track.appendChild(this._fill);
28
+
29
+ this._container.appendChild(header);
30
+ this._container.appendChild(track);
31
+
32
+ this._updateValue();
33
+
34
+ this._wrapper.appendChild(this._container);
35
+ }
36
+
37
+ onAttributeChanged(name) {
38
+ if (!this._container) return;
39
+ switch (name) {
40
+ case 'value':
41
+ this._updateValue();
42
+ break;
43
+ case 'label':
44
+ this._labelEl.textContent = this.getAttribute('label') || '';
45
+ break;
46
+ case 'variant':
47
+ case 'size':
48
+ this._container.className = this._computeClasses().join(' ');
49
+ break;
50
+ }
51
+ }
52
+
53
+ _updateValue() {
54
+ const val = Math.min(100, Math.max(0, parseInt(this.getAttribute('value') || '0', 10)));
55
+ this._fill.style.width = `${val}%`;
56
+ this._valueEl.textContent = `${val}%`;
57
+ }
58
+
59
+ _computeClasses() {
60
+ const classes = ['glass-progress'];
61
+ const variant = this.getAttribute('variant');
62
+ if (variant && VARIANTS.includes(variant)) {
63
+ classes.push(`glass-progress--${variant}`);
64
+ }
65
+ const size = this.getAttribute('size');
66
+ if (size && SIZES.includes(size)) {
67
+ classes.push(`glass-progress--${size}`);
68
+ }
69
+ return classes;
70
+ }
71
+
72
+ get value() { return this.getAttribute('value'); }
73
+ set value(v) { this.setAttribute('value', String(v)); }
74
+ }
75
+
76
+ customElements.define('glk-progress', GlkProgress);
77
+ export { GlkProgress };
@@ -0,0 +1,104 @@
1
+ import { GlkElement } from '../../base.js';
2
+
3
+ const VARIANTS = ['success', 'error', 'warning'];
4
+
5
+ const ICONS = {
6
+ success: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>`,
7
+ error: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>`,
8
+ warning: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>`
9
+ };
10
+
11
+ class GlkToast extends GlkElement {
12
+ static get observedAttributes() {
13
+ return ['message', 'variant', 'duration', 'visible'];
14
+ }
15
+
16
+ render() {
17
+ this._toast = this.createElement('div', this._computeClasses());
18
+
19
+ this._iconEl = this.createElement('span', ['glass-toast__icon']);
20
+ this._textEl = this.createElement('span', ['glass-toast__text']);
21
+ this._textEl.textContent = this.getAttribute('message') || '';
22
+
23
+ this._updateIcon();
24
+
25
+ this._toast.appendChild(this._iconEl);
26
+ this._toast.appendChild(this._textEl);
27
+ this._wrapper.appendChild(this._toast);
28
+
29
+ if (this.getBoolAttr('visible')) {
30
+ this._show();
31
+ }
32
+ }
33
+
34
+ onAttributeChanged(name) {
35
+ if (!this._toast) return;
36
+ switch (name) {
37
+ case 'message':
38
+ this._textEl.textContent = this.getAttribute('message') || '';
39
+ break;
40
+ case 'variant':
41
+ this._toast.className = this._computeClasses().join(' ');
42
+ this._updateIcon();
43
+ break;
44
+ case 'visible':
45
+ if (this.getBoolAttr('visible')) {
46
+ this._show();
47
+ } else {
48
+ this._hide();
49
+ }
50
+ break;
51
+ }
52
+ }
53
+
54
+ _computeClasses() {
55
+ const classes = ['glass-toast'];
56
+ const variant = this.getAttribute('variant');
57
+ if (variant && VARIANTS.includes(variant)) {
58
+ classes.push(`glass-toast--${variant}`);
59
+ }
60
+ return classes;
61
+ }
62
+
63
+ _updateIcon() {
64
+ const variant = this.getAttribute('variant');
65
+ this._iconEl.innerHTML = ICONS[variant] || ICONS.success;
66
+ }
67
+
68
+ _show() {
69
+ this._toast.classList.add('is-visible');
70
+ const duration = parseInt(this.getAttribute('duration') || '3000', 10);
71
+ if (duration > 0) {
72
+ clearTimeout(this._timer);
73
+ this._timer = setTimeout(() => {
74
+ this.removeAttribute('visible');
75
+ this.emit('glk-dismiss');
76
+ }, duration);
77
+ }
78
+ }
79
+
80
+ _hide() {
81
+ this._toast.classList.remove('is-visible');
82
+ clearTimeout(this._timer);
83
+ }
84
+
85
+ /** Programmatic show */
86
+ show(message, variant, duration) {
87
+ if (message) this.setAttribute('message', message);
88
+ if (variant) this.setAttribute('variant', variant);
89
+ if (duration) this.setAttribute('duration', String(duration));
90
+ this.setAttribute('visible', '');
91
+ }
92
+
93
+ dismiss() {
94
+ this.removeAttribute('visible');
95
+ }
96
+
97
+ disconnectedCallback() {
98
+ super.disconnectedCallback();
99
+ clearTimeout(this._timer);
100
+ }
101
+ }
102
+
103
+ customElements.define('glk-toast', GlkToast);
104
+ export { GlkToast };
@@ -0,0 +1,103 @@
1
+ import { GlkFormElement } from '../../base.js';
2
+
3
+ const CHECKMARK_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`;
4
+
5
+ class GlkCheckbox extends GlkFormElement {
6
+ static get observedAttributes() {
7
+ return ['checked', 'disabled', 'label', 'name', 'value'];
8
+ }
9
+
10
+ render() {
11
+ const label = this.createElement('label', ['glass-checkbox']);
12
+
13
+ this._input = this.createElement('input', ['glass-checkbox__input'], {
14
+ type: 'checkbox'
15
+ });
16
+
17
+ const name = this.getAttribute('name');
18
+ if (name) this._input.setAttribute('name', name);
19
+
20
+ const box = this.createElement('span', ['glass-checkbox__box']);
21
+ box.innerHTML = CHECKMARK_SVG;
22
+
23
+ this._labelEl = this.createElement('span', ['glass-checkbox__label']);
24
+ this._labelEl.textContent = this.getAttribute('label') || '';
25
+
26
+ label.appendChild(this._input);
27
+ label.appendChild(box);
28
+ label.appendChild(this._labelEl);
29
+
30
+ if (this.getBoolAttr('checked')) this._input.checked = true;
31
+ if (this.getBoolAttr('disabled')) this._input.disabled = true;
32
+
33
+ this._defaultChecked = this.getBoolAttr('checked');
34
+ this._wrapper.appendChild(label);
35
+ this._syncFormValue();
36
+ }
37
+
38
+ setupEvents() {
39
+ this._onChange = () => {
40
+ this._syncing = true;
41
+ this.setBoolAttr('checked', this._input.checked);
42
+ this._syncing = false;
43
+ this._syncFormValue();
44
+ this.emit('glk-change', { checked: this._input.checked });
45
+ this.dispatchEvent(new Event('change', { bubbles: true }));
46
+ };
47
+ this._input.addEventListener('change', this._onChange);
48
+ }
49
+
50
+ teardownEvents() {
51
+ this._input?.removeEventListener('change', this._onChange);
52
+ }
53
+
54
+ onAttributeChanged(name) {
55
+ if (this._syncing) return;
56
+ if (!this._input) return;
57
+ switch (name) {
58
+ case 'checked':
59
+ this._input.checked = this.getBoolAttr('checked');
60
+ this._syncFormValue();
61
+ break;
62
+ case 'disabled':
63
+ this._input.disabled = this.getBoolAttr('disabled');
64
+ break;
65
+ case 'label':
66
+ this._labelEl.textContent = this.getAttribute('label') || '';
67
+ break;
68
+ case 'name':
69
+ this._input.setAttribute('name', this.getAttribute('name') || '');
70
+ break;
71
+ }
72
+ }
73
+
74
+ _syncFormValue() {
75
+ const val = this.getAttribute('value') || 'on';
76
+ this.setFormValue(this._input.checked ? val : null);
77
+ }
78
+
79
+ resetValue() {
80
+ this._input.checked = this._defaultChecked;
81
+ this.setBoolAttr('checked', this._defaultChecked);
82
+ this._syncFormValue();
83
+ }
84
+
85
+ get checked() { return this._input?.checked ?? false; }
86
+ set checked(v) {
87
+ if (this._input) this._input.checked = v;
88
+ this.setBoolAttr('checked', v);
89
+ this._syncFormValue();
90
+ }
91
+
92
+ get disabled() { return this.getBoolAttr('disabled'); }
93
+ set disabled(v) { this.setBoolAttr('disabled', v); }
94
+
95
+ get name() { return this.getAttribute('name'); }
96
+ set name(v) { this.setAttribute('name', v); }
97
+
98
+ get value() { return this.getAttribute('value') || 'on'; }
99
+ set value(v) { this.setAttribute('value', v); }
100
+ }
101
+
102
+ customElements.define('glk-checkbox', GlkCheckbox);
103
+ export { GlkCheckbox };
@@ -0,0 +1,138 @@
1
+ import { GlkFormElement } from '../../base.js';
2
+
3
+ class GlkInput extends GlkFormElement {
4
+ static get observedAttributes() {
5
+ return ['label', 'type', 'placeholder', 'error', 'hint', 'disabled', 'name', 'value', 'required'];
6
+ }
7
+
8
+ render() {
9
+ const group = this.createElement('div', ['glass-input-group']);
10
+
11
+ // Label
12
+ this._labelEl = this.createElement('label', ['glass-label']);
13
+ this._labelEl.textContent = this.getAttribute('label') || '';
14
+
15
+ // Input
16
+ this._input = this.createElement('input', this._computeInputClasses(), {
17
+ type: this.getAttribute('type') || 'text'
18
+ });
19
+
20
+ const placeholder = this.getAttribute('placeholder');
21
+ if (placeholder) this._input.setAttribute('placeholder', placeholder);
22
+
23
+ const name = this.getAttribute('name');
24
+ if (name) this._input.setAttribute('name', name);
25
+
26
+ const value = this.getAttribute('value');
27
+ if (value) this._input.value = value;
28
+
29
+ if (this.getBoolAttr('disabled')) this._input.disabled = true;
30
+ if (this.getBoolAttr('required')) this._input.required = true;
31
+
32
+ // Hint
33
+ this._hintEl = this.createElement('span', this._computeHintClasses());
34
+ this._hintEl.textContent = this.getAttribute('hint') || '';
35
+
36
+ group.appendChild(this._labelEl);
37
+ group.appendChild(this._input);
38
+ if (this.getAttribute('hint')) group.appendChild(this._hintEl);
39
+
40
+ this._group = group;
41
+ this._wrapper.appendChild(group);
42
+
43
+ this._syncFormValue();
44
+ }
45
+
46
+ setupEvents() {
47
+ this._onInput = () => {
48
+ this._syncFormValue();
49
+ this.emit('glk-input', { value: this._input.value });
50
+ this.dispatchEvent(new Event('input', { bubbles: true }));
51
+ };
52
+ this._onChangeNative = () => {
53
+ this.emit('glk-change', { value: this._input.value });
54
+ this.dispatchEvent(new Event('change', { bubbles: true }));
55
+ };
56
+ this._input.addEventListener('input', this._onInput);
57
+ this._input.addEventListener('change', this._onChangeNative);
58
+ }
59
+
60
+ teardownEvents() {
61
+ this._input?.removeEventListener('input', this._onInput);
62
+ this._input?.removeEventListener('change', this._onChangeNative);
63
+ }
64
+
65
+ onAttributeChanged(name) {
66
+ if (!this._input) return;
67
+ switch (name) {
68
+ case 'label':
69
+ this._labelEl.textContent = this.getAttribute('label') || '';
70
+ break;
71
+ case 'type':
72
+ this._input.setAttribute('type', this.getAttribute('type') || 'text');
73
+ break;
74
+ case 'placeholder':
75
+ this._input.setAttribute('placeholder', this.getAttribute('placeholder') || '');
76
+ break;
77
+ case 'error':
78
+ this._input.className = this._computeInputClasses().join(' ');
79
+ this._hintEl.className = this._computeHintClasses().join(' ');
80
+ break;
81
+ case 'hint':
82
+ this._hintEl.textContent = this.getAttribute('hint') || '';
83
+ if (this.getAttribute('hint') && !this._hintEl.parentNode) {
84
+ this._group.appendChild(this._hintEl);
85
+ }
86
+ break;
87
+ case 'disabled':
88
+ this._input.disabled = this.getBoolAttr('disabled');
89
+ break;
90
+ case 'name':
91
+ this._input.setAttribute('name', this.getAttribute('name') || '');
92
+ break;
93
+ case 'value':
94
+ this._input.value = this.getAttribute('value') || '';
95
+ this._syncFormValue();
96
+ break;
97
+ case 'required':
98
+ this._input.required = this.getBoolAttr('required');
99
+ break;
100
+ }
101
+ }
102
+
103
+ _computeInputClasses() {
104
+ const classes = ['glass-input'];
105
+ if (this.getBoolAttr('error')) classes.push('glass-input--error');
106
+ return classes;
107
+ }
108
+
109
+ _computeHintClasses() {
110
+ const classes = ['glass-hint'];
111
+ if (this.getBoolAttr('error')) classes.push('glass-hint--error');
112
+ return classes;
113
+ }
114
+
115
+ _syncFormValue() {
116
+ this.setFormValue(this._input.value);
117
+ }
118
+
119
+ resetValue() {
120
+ this._input.value = this.getAttribute('value') || '';
121
+ this._syncFormValue();
122
+ }
123
+
124
+ get value() { return this._input?.value ?? ''; }
125
+ set value(v) {
126
+ if (this._input) this._input.value = v;
127
+ this._syncFormValue();
128
+ }
129
+
130
+ get disabled() { return this.getBoolAttr('disabled'); }
131
+ set disabled(v) { this.setBoolAttr('disabled', v); }
132
+
133
+ get name() { return this.getAttribute('name'); }
134
+ set name(v) { this.setAttribute('name', v); }
135
+ }
136
+
137
+ customElements.define('glk-input', GlkInput);
138
+ export { GlkInput };