@taybart/corvid 0.2.0 → 0.2.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/dist/ls.js CHANGED
@@ -1,11 +1,159 @@
1
- function strings_toKebab(str) {
1
+ function toKebab(str) {
2
2
  return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, ofs)=>(ofs ? '-' : '') + s.toLowerCase());
3
3
  }
4
4
  function render(style) {
5
5
  let s = '';
6
- Object.entries(style).forEach(([k, v])=>s += `${strings_toKebab(k)}:${v};`);
6
+ Object.entries(style).forEach(([k, v])=>s += `${toKebab(k)}:${v};`);
7
7
  return s;
8
8
  }
9
+ function splitSelectors(selector) {
10
+ const out = [];
11
+ let depth = 0;
12
+ let quote = '';
13
+ let current = '';
14
+ for (const ch of selector){
15
+ if (quote) {
16
+ if (ch === quote) quote = '';
17
+ } else if ('"' === ch || "'" === ch) quote = ch;
18
+ else if ('(' === ch || '[' === ch) depth++;
19
+ else if (')' === ch || ']' === ch) depth--;
20
+ else if (',' === ch && 0 === depth) {
21
+ if (current.trim()) out.push(current.trim());
22
+ current = '';
23
+ continue;
24
+ }
25
+ current += ch;
26
+ }
27
+ if (current.trim()) out.push(current.trim());
28
+ return out;
29
+ }
30
+ function hostCompound(selector) {
31
+ if (!selector.startsWith(':host')) return selector;
32
+ let i = 5;
33
+ let inner = '';
34
+ if ('(' === selector[i]) {
35
+ const open = i;
36
+ let depth = 0;
37
+ let quote = '';
38
+ while(i < selector.length){
39
+ const ch = selector[i];
40
+ if (quote) {
41
+ if (ch === quote) quote = '';
42
+ } else if ('"' === ch || "'" === ch) quote = ch;
43
+ else if ('(' === ch) depth++;
44
+ else if (')' === ch) {
45
+ depth--;
46
+ if (0 === depth) {
47
+ i++;
48
+ break;
49
+ }
50
+ }
51
+ i++;
52
+ }
53
+ inner = selector.slice(open + 1, i - 1);
54
+ }
55
+ const start = i;
56
+ let depth = 0;
57
+ let quote = '';
58
+ while(i < selector.length){
59
+ const ch = selector[i];
60
+ if (quote) {
61
+ if (ch === quote) quote = '';
62
+ } else if ('"' === ch || "'" === ch) quote = ch;
63
+ else if (0 === depth && (' ' === ch || '>' === ch || '+' === ch || '~' === ch)) break;
64
+ else if (0 === depth && ':' === ch && ':' === selector[i + 1]) break;
65
+ else if ('(' === ch || '[' === ch) depth++;
66
+ else if (')' === ch || ']' === ch) depth--;
67
+ i++;
68
+ }
69
+ const compound = selector.slice(start, i);
70
+ if (!compound) return selector;
71
+ return `:host(${inner}${compound})${selector.slice(i)}`;
72
+ }
73
+ function resolve(parents, selector) {
74
+ const out = [];
75
+ for (const parent of parents)for (const part of splitSelectors(selector))out.push(hostCompound(part.includes('&') ? part.replaceAll('&', parent) : `${parent} ${part}`));
76
+ return out;
77
+ }
78
+ function compile(parents, decls, indent = '') {
79
+ const blocks = [];
80
+ const props = [];
81
+ const nested = [];
82
+ for (const [k, v] of Object.entries(decls))if (null !== v && 'object' == typeof v) nested.push([
83
+ k,
84
+ v
85
+ ]);
86
+ else props.push(`${indent} ${toKebab(k)}: ${v};`);
87
+ if (props.length) blocks.push(`${indent}${parents.join(', ')} {\n${props.join('\n')}\n${indent}}`);
88
+ for (const [selector, block] of nested){
89
+ if (selector.startsWith('@')) {
90
+ const inner = selector.startsWith('@keyframes') ? Object.entries(block).flatMap(([step, d])=>null !== d && 'object' == typeof d ? compile([
91
+ step
92
+ ], d, `${indent} `) : []) : compile(parents, block, `${indent} `);
93
+ if (inner.length) blocks.push(`${indent}${selector} {\n${inner.join('\n')}\n${indent}}`);
94
+ continue;
95
+ }
96
+ blocks.push(...compile(resolve(parents, selector), block, indent));
97
+ }
98
+ return blocks;
99
+ }
100
+ function css(selector, style) {
101
+ return compile(splitSelectors(selector), style).join('\n');
102
+ }
103
+ function registry() {
104
+ const doc = document;
105
+ if (!doc.__corvidSheets) doc.__corvidSheets = new Map();
106
+ return doc.__corvidSheets;
107
+ }
108
+ function adoptable() {
109
+ return 'undefined' != typeof CSSStyleSheet && 'replaceSync' in CSSStyleSheet.prototype && 'undefined' != typeof Document && 'adoptedStyleSheets' in Document.prototype;
110
+ }
111
+ function styleTag(key) {
112
+ const tagged = Array.from(document.head.querySelectorAll('style[data-corvid]'));
113
+ for (const node of tagged)if (node.dataset.corvid === key) return node;
114
+ const node = document.createElement('style');
115
+ node.dataset.corvid = key;
116
+ document.head.appendChild(node);
117
+ return node;
118
+ }
119
+ function inject(selector, style, { key = selector } = {}) {
120
+ const rules = css(selector, style);
121
+ const sheets = registry();
122
+ const existing = sheets.get(key);
123
+ if (existing) {
124
+ if ('replaceSync' in existing) existing.replaceSync(rules);
125
+ else existing.textContent = rules;
126
+ return rules;
127
+ }
128
+ if (adoptable()) {
129
+ const sheet = new CSSStyleSheet();
130
+ sheet.replaceSync(rules);
131
+ document.adoptedStyleSheets = [
132
+ ...document.adoptedStyleSheets,
133
+ sheet
134
+ ];
135
+ sheets.set(key, sheet);
136
+ return rules;
137
+ }
138
+ const node = styleTag(key);
139
+ node.textContent = rules;
140
+ sheets.set(key, node);
141
+ return rules;
142
+ }
143
+ function shadowSheet(key, style) {
144
+ const rules = css(':host', style);
145
+ if ('undefined' == typeof CSSStyleSheet || !('replaceSync' in CSSStyleSheet.prototype) || 'undefined' == typeof ShadowRoot || !('adoptedStyleSheets' in ShadowRoot.prototype)) return rules;
146
+ const sheets = registry();
147
+ const existing = sheets.get(key);
148
+ if (existing && 'replaceSync' in existing) {
149
+ existing.replaceSync(rules);
150
+ return existing;
151
+ }
152
+ const sheet = new CSSStyleSheet();
153
+ sheet.replaceSync(rules);
154
+ sheets.set(key, sheet);
155
+ return sheet;
156
+ }
9
157
  function _define_property(obj, key, value) {
10
158
  if (key in obj) Object.defineProperty(obj, key, {
11
159
  value: value,
@@ -61,6 +209,37 @@ class utils_logger {
61
209
  });
62
210
  }
63
211
  }
212
+ function _check_private_redeclaration(obj, privateCollection) {
213
+ if (privateCollection.has(obj)) throw new TypeError("Cannot initialize the same private elements twice on an object");
214
+ }
215
+ function _class_apply_descriptor_get(receiver, descriptor) {
216
+ if (descriptor.get) return descriptor.get.call(receiver);
217
+ return descriptor.value;
218
+ }
219
+ function _class_apply_descriptor_set(receiver, descriptor, value) {
220
+ if (descriptor.set) descriptor.set.call(receiver, value);
221
+ else {
222
+ if (!descriptor.writable) throw new TypeError("attempted to set read only private field");
223
+ descriptor.value = value;
224
+ }
225
+ }
226
+ function _class_extract_field_descriptor(receiver, privateMap, action) {
227
+ if (!privateMap.has(receiver)) throw new TypeError("attempted to " + action + " private field on non-instance");
228
+ return privateMap.get(receiver);
229
+ }
230
+ function _class_private_field_get(receiver, privateMap) {
231
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
232
+ return _class_apply_descriptor_get(receiver, descriptor);
233
+ }
234
+ function _class_private_field_init(obj, privateMap, value) {
235
+ _check_private_redeclaration(obj, privateMap);
236
+ privateMap.set(obj, value);
237
+ }
238
+ function _class_private_field_set(receiver, privateMap, value) {
239
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
240
+ _class_apply_descriptor_set(receiver, descriptor, value);
241
+ return value;
242
+ }
64
243
  function dom_define_property(obj, key, value) {
65
244
  if (key in obj) Object.defineProperty(obj, key, {
66
245
  value: value,
@@ -71,6 +250,14 @@ function dom_define_property(obj, key, value) {
71
250
  else obj[key] = value;
72
251
  return obj;
73
252
  }
253
+ function registerElement(name, ctor) {
254
+ const existing = customElements.get(name);
255
+ if (existing) {
256
+ if (existing !== ctor) throw new Error(`custom element ${name} is already registered by ${existing.name}`);
257
+ return;
258
+ }
259
+ customElements.define(name, ctor);
260
+ }
74
261
  class dom_el {
75
262
  static query(query, verbose = false) {
76
263
  return new dom_el(query, verbose);
@@ -128,7 +315,11 @@ class dom_el {
128
315
  }
129
316
  html(content) {
130
317
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
131
- this.el.innerHTML = content;
318
+ if ('string' == typeof content) this.el.innerHTML = content;
319
+ else if (content instanceof dom_el) {
320
+ if (content.el) this.el.replaceChildren(content.el);
321
+ } else this.el.replaceChildren(content);
322
+ return this;
132
323
  }
133
324
  src(url) {
134
325
  if (this.el && 'src' in this.el) this.el.src = url;
@@ -155,7 +346,7 @@ class dom_el {
155
346
  else if ('object' == typeof update) {
156
347
  if (!stringify) {
157
348
  for (const [k, v] of Object.entries(update))this.el.style[k] = v;
158
- return;
349
+ return this;
159
350
  }
160
351
  const s = render(update);
161
352
  this.log.debug(`set style: ${this.el.style} -> ${s}`);
@@ -168,6 +359,12 @@ class dom_el {
168
359
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
169
360
  return this.el.classList.contains(className);
170
361
  }
362
+ toggleClass(className) {
363
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
364
+ if (this.el.classList.contains(className)) this.el.classList.remove(className);
365
+ else this.el.classList.add(className);
366
+ return this;
367
+ }
171
368
  addClass(className) {
172
369
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
173
370
  if ('string' == typeof className) this.el.classList.add(className);
@@ -258,6 +455,74 @@ class dom_el {
258
455
  }
259
456
  }
260
457
  }
458
+ const dom_sheets = new WeakMap();
459
+ var _mounted = /*#__PURE__*/ new WeakMap(), _root = /*#__PURE__*/ new WeakMap(), _pendingAttrs = /*#__PURE__*/ new WeakMap();
460
+ class component extends HTMLElement {
461
+ get root() {
462
+ return _class_private_field_get(this, _root) ?? this;
463
+ }
464
+ static register(tag, verbose = false) {
465
+ const name = tag ?? this.tag;
466
+ if (!name) throw new Error(`${this.name}: nothing to register as, set \`static tag = 'x-...'\``);
467
+ if (!name.includes('-')) throw new Error(`${this.name}: '${name}' is not a valid custom element name, it needs a hyphen`);
468
+ if (this.styles) if (this.shadow) dom_sheets.set(this, shadowSheet(`shadow:${name}`, this.styles));
469
+ else inject(name, this.styles);
470
+ if (verbose) console.log(`registering ${name}`);
471
+ registerElement(name, this);
472
+ }
473
+ mount() {}
474
+ unmount() {}
475
+ onAttr(_name, _value, _prev) {}
476
+ connectedCallback() {
477
+ if (!_class_private_field_get(this, _mounted)) {
478
+ _class_private_field_set(this, _mounted, true);
479
+ this.mount();
480
+ const queued = _class_private_field_get(this, _pendingAttrs);
481
+ _class_private_field_set(this, _pendingAttrs, []);
482
+ for (const [name, value, prev] of queued)this.onAttr(name, value, prev);
483
+ }
484
+ }
485
+ disconnectedCallback() {
486
+ this.unmount();
487
+ }
488
+ attributeChangedCallback(name, prev, value) {
489
+ if (prev === value) return;
490
+ if (!_class_private_field_get(this, _mounted)) return void _class_private_field_get(this, _pendingAttrs).push([
491
+ name,
492
+ value,
493
+ prev
494
+ ]);
495
+ this.onAttr(name, value, prev);
496
+ }
497
+ constructor(){
498
+ super(), _class_private_field_init(this, _mounted, {
499
+ writable: true,
500
+ value: false
501
+ }), _class_private_field_init(this, _root, {
502
+ writable: true,
503
+ value: null
504
+ }), _class_private_field_init(this, _pendingAttrs, {
505
+ writable: true,
506
+ value: []
507
+ });
508
+ const ctor = this.constructor;
509
+ if (!ctor.shadow) return;
510
+ _class_private_field_set(this, _root, this.attachShadow(ctor.shadow));
511
+ const sheet = dom_sheets.get(ctor);
512
+ if (void 0 === sheet) return;
513
+ if ('string' == typeof sheet) {
514
+ const node = document.createElement('style');
515
+ node.textContent = sheet;
516
+ _class_private_field_get(this, _root).append(node);
517
+ } else _class_private_field_get(this, _root).adoptedStyleSheets = [
518
+ ..._class_private_field_get(this, _root).adoptedStyleSheets,
519
+ sheet
520
+ ];
521
+ }
522
+ }
523
+ dom_define_property(component, "tag", '');
524
+ dom_define_property(component, "styles", null);
525
+ dom_define_property(component, "shadow", null);
261
526
  function get(key, _default) {
262
527
  let ret = localStorage.getItem(key);
263
528
  if (null === ret && null != _default) {
package/dist/qr.js CHANGED
@@ -1904,14 +1904,162 @@ const QRErrorCorrectLevel = {
1904
1904
  Q: 3,
1905
1905
  H: 2
1906
1906
  };
1907
- function strings_toKebab(str) {
1907
+ function toKebab(str) {
1908
1908
  return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, (s, ofs)=>(ofs ? '-' : '') + s.toLowerCase());
1909
1909
  }
1910
1910
  function render(style) {
1911
1911
  let s = '';
1912
- Object.entries(style).forEach(([k, v])=>s += `${strings_toKebab(k)}:${v};`);
1912
+ Object.entries(style).forEach(([k, v])=>s += `${toKebab(k)}:${v};`);
1913
1913
  return s;
1914
1914
  }
1915
+ function splitSelectors(selector) {
1916
+ const out = [];
1917
+ let depth = 0;
1918
+ let quote = '';
1919
+ let current = '';
1920
+ for (const ch of selector){
1921
+ if (quote) {
1922
+ if (ch === quote) quote = '';
1923
+ } else if ('"' === ch || "'" === ch) quote = ch;
1924
+ else if ('(' === ch || '[' === ch) depth++;
1925
+ else if (')' === ch || ']' === ch) depth--;
1926
+ else if (',' === ch && 0 === depth) {
1927
+ if (current.trim()) out.push(current.trim());
1928
+ current = '';
1929
+ continue;
1930
+ }
1931
+ current += ch;
1932
+ }
1933
+ if (current.trim()) out.push(current.trim());
1934
+ return out;
1935
+ }
1936
+ function hostCompound(selector) {
1937
+ if (!selector.startsWith(':host')) return selector;
1938
+ let i = 5;
1939
+ let inner = '';
1940
+ if ('(' === selector[i]) {
1941
+ const open = i;
1942
+ let depth = 0;
1943
+ let quote = '';
1944
+ while(i < selector.length){
1945
+ const ch = selector[i];
1946
+ if (quote) {
1947
+ if (ch === quote) quote = '';
1948
+ } else if ('"' === ch || "'" === ch) quote = ch;
1949
+ else if ('(' === ch) depth++;
1950
+ else if (')' === ch) {
1951
+ depth--;
1952
+ if (0 === depth) {
1953
+ i++;
1954
+ break;
1955
+ }
1956
+ }
1957
+ i++;
1958
+ }
1959
+ inner = selector.slice(open + 1, i - 1);
1960
+ }
1961
+ const start = i;
1962
+ let depth = 0;
1963
+ let quote = '';
1964
+ while(i < selector.length){
1965
+ const ch = selector[i];
1966
+ if (quote) {
1967
+ if (ch === quote) quote = '';
1968
+ } else if ('"' === ch || "'" === ch) quote = ch;
1969
+ else if (0 === depth && (' ' === ch || '>' === ch || '+' === ch || '~' === ch)) break;
1970
+ else if (0 === depth && ':' === ch && ':' === selector[i + 1]) break;
1971
+ else if ('(' === ch || '[' === ch) depth++;
1972
+ else if (')' === ch || ']' === ch) depth--;
1973
+ i++;
1974
+ }
1975
+ const compound = selector.slice(start, i);
1976
+ if (!compound) return selector;
1977
+ return `:host(${inner}${compound})${selector.slice(i)}`;
1978
+ }
1979
+ function resolve(parents, selector) {
1980
+ const out = [];
1981
+ for (const parent of parents)for (const part of splitSelectors(selector))out.push(hostCompound(part.includes('&') ? part.replaceAll('&', parent) : `${parent} ${part}`));
1982
+ return out;
1983
+ }
1984
+ function compile(parents, decls, indent = '') {
1985
+ const blocks = [];
1986
+ const props = [];
1987
+ const nested = [];
1988
+ for (const [k, v] of Object.entries(decls))if (null !== v && 'object' == typeof v) nested.push([
1989
+ k,
1990
+ v
1991
+ ]);
1992
+ else props.push(`${indent} ${toKebab(k)}: ${v};`);
1993
+ if (props.length) blocks.push(`${indent}${parents.join(', ')} {\n${props.join('\n')}\n${indent}}`);
1994
+ for (const [selector, block] of nested){
1995
+ if (selector.startsWith('@')) {
1996
+ const inner = selector.startsWith('@keyframes') ? Object.entries(block).flatMap(([step, d])=>null !== d && 'object' == typeof d ? compile([
1997
+ step
1998
+ ], d, `${indent} `) : []) : compile(parents, block, `${indent} `);
1999
+ if (inner.length) blocks.push(`${indent}${selector} {\n${inner.join('\n')}\n${indent}}`);
2000
+ continue;
2001
+ }
2002
+ blocks.push(...compile(resolve(parents, selector), block, indent));
2003
+ }
2004
+ return blocks;
2005
+ }
2006
+ function css(selector, style) {
2007
+ return compile(splitSelectors(selector), style).join('\n');
2008
+ }
2009
+ function registry() {
2010
+ const doc = document;
2011
+ if (!doc.__corvidSheets) doc.__corvidSheets = new Map();
2012
+ return doc.__corvidSheets;
2013
+ }
2014
+ function adoptable() {
2015
+ return 'undefined' != typeof CSSStyleSheet && 'replaceSync' in CSSStyleSheet.prototype && 'undefined' != typeof Document && 'adoptedStyleSheets' in Document.prototype;
2016
+ }
2017
+ function styleTag(key) {
2018
+ const tagged = Array.from(document.head.querySelectorAll('style[data-corvid]'));
2019
+ for (const node of tagged)if (node.dataset.corvid === key) return node;
2020
+ const node = document.createElement('style');
2021
+ node.dataset.corvid = key;
2022
+ document.head.appendChild(node);
2023
+ return node;
2024
+ }
2025
+ function inject(selector, style, { key = selector } = {}) {
2026
+ const rules = css(selector, style);
2027
+ const sheets = registry();
2028
+ const existing = sheets.get(key);
2029
+ if (existing) {
2030
+ if ('replaceSync' in existing) existing.replaceSync(rules);
2031
+ else existing.textContent = rules;
2032
+ return rules;
2033
+ }
2034
+ if (adoptable()) {
2035
+ const sheet = new CSSStyleSheet();
2036
+ sheet.replaceSync(rules);
2037
+ document.adoptedStyleSheets = [
2038
+ ...document.adoptedStyleSheets,
2039
+ sheet
2040
+ ];
2041
+ sheets.set(key, sheet);
2042
+ return rules;
2043
+ }
2044
+ const node = styleTag(key);
2045
+ node.textContent = rules;
2046
+ sheets.set(key, node);
2047
+ return rules;
2048
+ }
2049
+ function shadowSheet(key, style) {
2050
+ const rules = css(':host', style);
2051
+ if ('undefined' == typeof CSSStyleSheet || !('replaceSync' in CSSStyleSheet.prototype) || 'undefined' == typeof ShadowRoot || !('adoptedStyleSheets' in ShadowRoot.prototype)) return rules;
2052
+ const sheets = registry();
2053
+ const existing = sheets.get(key);
2054
+ if (existing && 'replaceSync' in existing) {
2055
+ existing.replaceSync(rules);
2056
+ return existing;
2057
+ }
2058
+ const sheet = new CSSStyleSheet();
2059
+ sheet.replaceSync(rules);
2060
+ sheets.set(key, sheet);
2061
+ return sheet;
2062
+ }
1915
2063
  function utils_define_property(obj, key, value) {
1916
2064
  if (key in obj) Object.defineProperty(obj, key, {
1917
2065
  value: value,
@@ -1967,6 +2115,37 @@ class utils_logger {
1967
2115
  });
1968
2116
  }
1969
2117
  }
2118
+ function _check_private_redeclaration(obj, privateCollection) {
2119
+ if (privateCollection.has(obj)) throw new TypeError("Cannot initialize the same private elements twice on an object");
2120
+ }
2121
+ function _class_apply_descriptor_get(receiver, descriptor) {
2122
+ if (descriptor.get) return descriptor.get.call(receiver);
2123
+ return descriptor.value;
2124
+ }
2125
+ function _class_apply_descriptor_set(receiver, descriptor, value) {
2126
+ if (descriptor.set) descriptor.set.call(receiver, value);
2127
+ else {
2128
+ if (!descriptor.writable) throw new TypeError("attempted to set read only private field");
2129
+ descriptor.value = value;
2130
+ }
2131
+ }
2132
+ function _class_extract_field_descriptor(receiver, privateMap, action) {
2133
+ if (!privateMap.has(receiver)) throw new TypeError("attempted to " + action + " private field on non-instance");
2134
+ return privateMap.get(receiver);
2135
+ }
2136
+ function _class_private_field_get(receiver, privateMap) {
2137
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
2138
+ return _class_apply_descriptor_get(receiver, descriptor);
2139
+ }
2140
+ function _class_private_field_init(obj, privateMap, value) {
2141
+ _check_private_redeclaration(obj, privateMap);
2142
+ privateMap.set(obj, value);
2143
+ }
2144
+ function _class_private_field_set(receiver, privateMap, value) {
2145
+ var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
2146
+ _class_apply_descriptor_set(receiver, descriptor, value);
2147
+ return value;
2148
+ }
1970
2149
  function dom_define_property(obj, key, value) {
1971
2150
  if (key in obj) Object.defineProperty(obj, key, {
1972
2151
  value: value,
@@ -1977,6 +2156,14 @@ function dom_define_property(obj, key, value) {
1977
2156
  else obj[key] = value;
1978
2157
  return obj;
1979
2158
  }
2159
+ function registerElement(name, ctor) {
2160
+ const existing = customElements.get(name);
2161
+ if (existing) {
2162
+ if (existing !== ctor) throw new Error(`custom element ${name} is already registered by ${existing.name}`);
2163
+ return;
2164
+ }
2165
+ customElements.define(name, ctor);
2166
+ }
1980
2167
  class dom_el {
1981
2168
  static query(query, verbose = false) {
1982
2169
  return new dom_el(query, verbose);
@@ -2034,7 +2221,11 @@ class dom_el {
2034
2221
  }
2035
2222
  html(content) {
2036
2223
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
2037
- this.el.innerHTML = content;
2224
+ if ('string' == typeof content) this.el.innerHTML = content;
2225
+ else if (content instanceof dom_el) {
2226
+ if (content.el) this.el.replaceChildren(content.el);
2227
+ } else this.el.replaceChildren(content);
2228
+ return this;
2038
2229
  }
2039
2230
  src(url) {
2040
2231
  if (this.el && 'src' in this.el) this.el.src = url;
@@ -2061,7 +2252,7 @@ class dom_el {
2061
2252
  else if ('object' == typeof update) {
2062
2253
  if (!stringify) {
2063
2254
  for (const [k, v] of Object.entries(update))this.el.style[k] = v;
2064
- return;
2255
+ return this;
2065
2256
  }
2066
2257
  const s = render(update);
2067
2258
  this.log.debug(`set style: ${this.el.style} -> ${s}`);
@@ -2074,6 +2265,12 @@ class dom_el {
2074
2265
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
2075
2266
  return this.el.classList.contains(className);
2076
2267
  }
2268
+ toggleClass(className) {
2269
+ if (!this.el) throw new Error(`no element from query: ${this.query}`);
2270
+ if (this.el.classList.contains(className)) this.el.classList.remove(className);
2271
+ else this.el.classList.add(className);
2272
+ return this;
2273
+ }
2077
2274
  addClass(className) {
2078
2275
  if (!this.el) throw new Error(`no element from query: ${this.query}`);
2079
2276
  if ('string' == typeof className) this.el.classList.add(className);
@@ -2164,6 +2361,74 @@ class dom_el {
2164
2361
  }
2165
2362
  }
2166
2363
  }
2364
+ const dom_sheets = new WeakMap();
2365
+ var _mounted = /*#__PURE__*/ new WeakMap(), _root = /*#__PURE__*/ new WeakMap(), _pendingAttrs = /*#__PURE__*/ new WeakMap();
2366
+ class component extends HTMLElement {
2367
+ get root() {
2368
+ return _class_private_field_get(this, _root) ?? this;
2369
+ }
2370
+ static register(tag, verbose = false) {
2371
+ const name = tag ?? this.tag;
2372
+ if (!name) throw new Error(`${this.name}: nothing to register as, set \`static tag = 'x-...'\``);
2373
+ if (!name.includes('-')) throw new Error(`${this.name}: '${name}' is not a valid custom element name, it needs a hyphen`);
2374
+ if (this.styles) if (this.shadow) dom_sheets.set(this, shadowSheet(`shadow:${name}`, this.styles));
2375
+ else inject(name, this.styles);
2376
+ if (verbose) console.log(`registering ${name}`);
2377
+ registerElement(name, this);
2378
+ }
2379
+ mount() {}
2380
+ unmount() {}
2381
+ onAttr(_name, _value, _prev) {}
2382
+ connectedCallback() {
2383
+ if (!_class_private_field_get(this, _mounted)) {
2384
+ _class_private_field_set(this, _mounted, true);
2385
+ this.mount();
2386
+ const queued = _class_private_field_get(this, _pendingAttrs);
2387
+ _class_private_field_set(this, _pendingAttrs, []);
2388
+ for (const [name, value, prev] of queued)this.onAttr(name, value, prev);
2389
+ }
2390
+ }
2391
+ disconnectedCallback() {
2392
+ this.unmount();
2393
+ }
2394
+ attributeChangedCallback(name, prev, value) {
2395
+ if (prev === value) return;
2396
+ if (!_class_private_field_get(this, _mounted)) return void _class_private_field_get(this, _pendingAttrs).push([
2397
+ name,
2398
+ value,
2399
+ prev
2400
+ ]);
2401
+ this.onAttr(name, value, prev);
2402
+ }
2403
+ constructor(){
2404
+ super(), _class_private_field_init(this, _mounted, {
2405
+ writable: true,
2406
+ value: false
2407
+ }), _class_private_field_init(this, _root, {
2408
+ writable: true,
2409
+ value: null
2410
+ }), _class_private_field_init(this, _pendingAttrs, {
2411
+ writable: true,
2412
+ value: []
2413
+ });
2414
+ const ctor = this.constructor;
2415
+ if (!ctor.shadow) return;
2416
+ _class_private_field_set(this, _root, this.attachShadow(ctor.shadow));
2417
+ const sheet = dom_sheets.get(ctor);
2418
+ if (void 0 === sheet) return;
2419
+ if ('string' == typeof sheet) {
2420
+ const node = document.createElement('style');
2421
+ node.textContent = sheet;
2422
+ _class_private_field_get(this, _root).append(node);
2423
+ } else _class_private_field_get(this, _root).adoptedStyleSheets = [
2424
+ ..._class_private_field_get(this, _root).adoptedStyleSheets,
2425
+ sheet
2426
+ ];
2427
+ }
2428
+ }
2429
+ dom_define_property(component, "tag", '');
2430
+ dom_define_property(component, "styles", null);
2431
+ dom_define_property(component, "shadow", null);
2167
2432
  class QR {
2168
2433
  static render(config, element) {
2169
2434
  const settings = this.getDefaultSettings(config);