godown 3.1.0 → 3.3.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 (117) hide show
  1. package/README.md +2 -2
  2. package/build/godown+lit.iife.js +12 -12
  3. package/build/godown+lit.iife.js.map +1 -1
  4. package/build/godown+lit.js +12 -12
  5. package/build/godown+lit.js.map +1 -1
  6. package/build/godown+lit.umd.js +12 -12
  7. package/build/godown+lit.umd.js.map +1 -1
  8. package/build/godown.iife.js +10 -10
  9. package/build/godown.js +10 -10
  10. package/build/godown.js.map +1 -1
  11. package/build/godown.umd.js +10 -10
  12. package/build/godown.umd.js.map +1 -1
  13. package/components/alert.d.ts +1 -3
  14. package/components/alert.d.ts.map +1 -1
  15. package/components/alert.js +1 -1
  16. package/components/alert.js.map +1 -1
  17. package/components/button.d.ts +1 -1
  18. package/components/button.d.ts.map +1 -1
  19. package/components/button.js.map +1 -1
  20. package/components/carousel.d.ts +5 -11
  21. package/components/carousel.d.ts.map +1 -1
  22. package/components/carousel.js +1 -1
  23. package/components/carousel.js.map +1 -1
  24. package/components/input.js +1 -1
  25. package/components/input.js.map +1 -1
  26. package/components/link.d.ts +34 -7
  27. package/components/link.d.ts.map +1 -1
  28. package/components/link.js +1 -1
  29. package/components/link.js.map +1 -1
  30. package/components/range.d.ts +7 -12
  31. package/components/range.d.ts.map +1 -1
  32. package/components/range.js +1 -1
  33. package/components/range.js.map +1 -1
  34. package/components/router.d.ts +9 -1
  35. package/components/router.d.ts.map +1 -1
  36. package/components/router.js +1 -1
  37. package/components/router.js.map +1 -1
  38. package/components/split.d.ts.map +1 -1
  39. package/components/split.js +1 -1
  40. package/components/split.js.map +1 -1
  41. package/components/text.js +1 -1
  42. package/components/text.js.map +1 -1
  43. package/components/time.d.ts +0 -3
  44. package/components/time.d.ts.map +1 -1
  45. package/components/time.js +1 -1
  46. package/components/time.js.map +1 -1
  47. package/components/typewriter.d.ts.map +1 -1
  48. package/components/typewriter.js +1 -1
  49. package/components/typewriter.js.map +1 -1
  50. package/core/global-style.d.ts +1 -0
  51. package/core/global-style.d.ts.map +1 -1
  52. package/core/global-style.js +1 -1
  53. package/core/global-style.js.map +1 -1
  54. package/core/super-anchor.d.ts +1 -0
  55. package/core/super-anchor.d.ts.map +1 -1
  56. package/core/super-anchor.js +1 -1
  57. package/core/super-anchor.js.map +1 -1
  58. package/custom-elements.json +1 -1
  59. package/dev/components/alert.d.ts +1 -3
  60. package/dev/components/alert.d.ts.map +1 -1
  61. package/dev/components/alert.js +32 -56
  62. package/dev/components/alert.js.map +1 -1
  63. package/dev/components/button.d.ts +1 -1
  64. package/dev/components/button.d.ts.map +1 -1
  65. package/dev/components/button.js.map +1 -1
  66. package/dev/components/carousel.d.ts +5 -11
  67. package/dev/components/carousel.d.ts.map +1 -1
  68. package/dev/components/carousel.js +38 -37
  69. package/dev/components/carousel.js.map +1 -1
  70. package/dev/components/input.js +2 -2
  71. package/dev/components/link.d.ts +34 -7
  72. package/dev/components/link.d.ts.map +1 -1
  73. package/dev/components/link.js +70 -12
  74. package/dev/components/link.js.map +1 -1
  75. package/dev/components/range.d.ts +7 -12
  76. package/dev/components/range.d.ts.map +1 -1
  77. package/dev/components/range.js +40 -54
  78. package/dev/components/range.js.map +1 -1
  79. package/dev/components/router.d.ts +9 -1
  80. package/dev/components/router.d.ts.map +1 -1
  81. package/dev/components/router.js +28 -21
  82. package/dev/components/router.js.map +1 -1
  83. package/dev/components/split.d.ts.map +1 -1
  84. package/dev/components/split.js +2 -9
  85. package/dev/components/split.js.map +1 -1
  86. package/dev/components/text.js +2 -2
  87. package/dev/components/time.d.ts +0 -3
  88. package/dev/components/time.d.ts.map +1 -1
  89. package/dev/components/time.js +6 -20
  90. package/dev/components/time.js.map +1 -1
  91. package/dev/components/typewriter.d.ts.map +1 -1
  92. package/dev/components/typewriter.js +2 -2
  93. package/dev/components/typewriter.js.map +1 -1
  94. package/dev/core/global-style.d.ts +1 -0
  95. package/dev/core/global-style.d.ts.map +1 -1
  96. package/dev/core/global-style.js +13 -9
  97. package/dev/core/global-style.js.map +1 -1
  98. package/dev/core/super-anchor.d.ts +1 -0
  99. package/dev/core/super-anchor.d.ts.map +1 -1
  100. package/dev/core/super-anchor.js +3 -4
  101. package/dev/core/super-anchor.js.map +1 -1
  102. package/package.json +3 -3
  103. package/src/components/alert.ts +33 -64
  104. package/src/components/button.ts +1 -1
  105. package/src/components/carousel.ts +43 -42
  106. package/src/components/input.ts +2 -2
  107. package/src/components/link.ts +75 -12
  108. package/src/components/range.ts +48 -62
  109. package/src/components/router.ts +32 -21
  110. package/src/components/split.ts +2 -10
  111. package/src/components/text.ts +2 -2
  112. package/src/components/time.ts +8 -23
  113. package/src/components/typewriter.ts +9 -7
  114. package/src/core/global-style.ts +13 -9
  115. package/src/core/super-anchor.ts +5 -1
  116. package/vscode.html-custom-data.json +1 -1
  117. package/web-types.json +1 -1
@@ -6,41 +6,104 @@ import Router from "./router.js";
6
6
 
7
7
  const protoName = "link";
8
8
 
9
+ const linkTypes = {
10
+ push: "push",
11
+ replace: "replace",
12
+ normal: "normal",
13
+ auto: "auto",
14
+ } as const;
15
+
16
+ type LinkType = keyof typeof linkTypes;
17
+
9
18
  /**
10
- * {@linkcode Link} is used for link jumping.
19
+ * {@linkcode Link} is used for link jumping, works standalone or in {@linkcode Router}.
20
+ *
21
+ * Set `type` to `"normal"`,
22
+ * behave like a normal anchor.
11
23
  *
12
24
  * Set `type` to `"push" `or `"replace"`,
13
- * will invoke the history api and trigger the {@linkcode Router.updateAll}.
25
+ * update history state by `history.pushState` or `history.replaceState`,
26
+ * update all routers whether current pathname is registered or not.
27
+ *
28
+ * Set `type` to `"auto"`,
29
+ * only update the routers if the current pathname is registered,
30
+ * if not registered, behave like `"normal"`.
14
31
  *
32
+ * `replace` property will enforce `history.replaceState`.
33
+ *
34
+ * @fires navigate - Fires when the link is clicked.
15
35
  * @category navigation
16
36
  */
17
37
  @godown(protoName)
18
38
  class Link extends SuperAnchor {
19
39
  /**
20
- * If "push", call `history.pushState`.
40
+ * If `"normal"`, behave like a normal anchor.
21
41
  *
22
- * If "replace", call `history.replaceState`.
42
+ * If `"auto"` or `"push"`, call `history.pushState` if `replace` is false,
23
43
  *
24
- * If "normal", behave like a normal anchor.
44
+ * If `"replace"`, call `history.replaceState`.
25
45
  */
26
46
  @property()
27
- type: "push" | "replace" | "normal" = "normal";
47
+ type: LinkType = linkTypes.auto;
28
48
 
29
49
  /**
30
- * Suppress the update of the {@linkcode Router}.
50
+ * If `true`, the {@linkcode Router} will not be updated.
31
51
  */
32
52
  @property({ type: Boolean })
33
53
  suppress = false;
34
54
 
55
+ /**
56
+ * Use `replaceState` instead of `pushState`.
57
+ */
58
+ @property({ type: Boolean })
59
+ replace = false;
60
+
61
+ /**
62
+ * Location state object.
63
+ */
64
+ state = {};
65
+
35
66
  protected _handleClick(e: MouseEvent): void {
36
- if (this.type === "push" || this.type === "replace") {
67
+ const { state, type, href, pathname, suppress } = this;
68
+ this.dispatchCustomEvent("navigate", {
69
+ ...this.observedRecord,
70
+ pathname,
71
+ state,
72
+ });
73
+ if (href.startsWith("#") || type === linkTypes.normal) {
74
+ return;
75
+ }
76
+ this.handleState();
77
+ const routers = [...Router.routerInstances];
78
+ if (
79
+ // only runs when suppress is false
80
+ !suppress &&
81
+ (type !== linkTypes.auto ||
82
+ // in auto mode, only update the routers if the current pathname is registered
83
+ routers.some((i) => i.search(location.pathname)))
84
+ ) {
37
85
  e.preventDefault();
38
- history[`${this.type}State`](null, "", this.href);
39
- if (!this.suppress) {
40
- Router.updateAll();
41
- }
86
+ Router.routerInstances.forEach((i) => {
87
+ i.handlePopstate();
88
+ });
42
89
  }
43
90
  }
91
+
92
+ handleState: () => void = () => {
93
+ switch (this.type) {
94
+ case linkTypes.auto:
95
+ // biome-ignore lint: if replace is true, fallthrough to replace case
96
+ case linkTypes.push:
97
+ if (!this.replace) {
98
+ // type is auto or push and replace is false
99
+ history.pushState(this.state, "", this.href);
100
+ break;
101
+ }
102
+ case linkTypes.replace:
103
+ history.replaceState(this.state, "", this.href);
104
+ break;
105
+ }
106
+ };
44
107
  }
45
108
 
46
109
  export default Link;
@@ -1,4 +1,4 @@
1
- import { attr, classList, godown, isNil, joinProperties, part, styles } from "@godown/element";
1
+ import { attr, tokenList, godown, isNil, joinProperties, loop, part, styles, Ranger } from "@godown/element";
2
2
  import { type TemplateResult, css, html } from "lit";
3
3
  import { property, queryAll, state } from "lit/decorators.js";
4
4
 
@@ -164,15 +164,9 @@ class Range extends SuperInput {
164
164
  @state()
165
165
  lastFocus?: number;
166
166
 
167
+ protected _ranger: Ranger;
167
168
  private __focusStack: number[] = [];
168
169
 
169
- /**
170
- * Returns true when the second number is greater than the first number.
171
- */
172
- get reverse(): boolean {
173
- return this.range ? this.value[0] > this.value[1] : false;
174
- }
175
-
176
170
  /**
177
171
  * If value is array.
178
172
  */
@@ -201,48 +195,55 @@ class Range extends SuperInput {
201
195
  return rangeValue;
202
196
  }
203
197
 
198
+ attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
199
+ super.attributeChangedCallback(name, _old, value);
200
+ if (name === "max" || name === "min" || name === "step") {
201
+ this._ranger = new Ranger(this.min, this.max, this.step);
202
+ }
203
+ }
204
+
204
205
  protected render(): TemplateResult<1> {
205
206
  const rangeValue = this.padValue(2);
206
207
  const from = Math.min(...rangeValue);
207
208
  const to = Math.max(...rangeValue);
208
- const gap = this.max - this.min;
209
+ const gap = this._ranger.diff;
209
210
 
210
211
  return html`
211
212
  <div
212
213
  part="root"
213
214
  ${attr(this.observedRecord)}
214
215
  @mousedown="${this.disabled ? null : this._handleMousedownRoot}"
215
- style="${joinProperties({
216
- "--from": `${((from - this.min) / gap) * 100}%`,
217
- "--to": `${((to - this.min) / gap) * 100}%`,
218
- ...(this.range
219
- ? Object.fromEntries(
220
- rangeValue.map((value, index) => [`--handle-${index}`, `${((value - this.min) / gap) * 100}%`]),
221
- )
222
- : {}),
223
- })}"
216
+ style="${joinProperties([
217
+ ["--from", `${((from - this.min) / gap) * 100}%`],
218
+ ["--to", `${((to - this.min) / gap) * 100}%`],
219
+ ...rangeValue.map(
220
+ (value, index) => [`--handle-${index}`, `${((value - this.min) / gap) * 100}%`] as [string, string],
221
+ ),
222
+ ])}"
224
223
  >
225
224
  <div part="track"></div>
226
- ${this.range ? (this.value as number[]).map((_, index) => this._renderHandle(index)) : this._renderHandle(0)}
225
+ ${loop(this.rangeValue.length, (index) => this._renderHandle(index))}
227
226
  </div>
228
227
  `;
229
228
  }
230
229
 
231
230
  protected _renderHandle(index: number): TemplateResult<1> {
232
- const { range } = this;
233
- const end = !range || index === (this.value as number[]).length - 1;
231
+ const { rangeValue, disabled } = this;
232
+
233
+ // in single-handle mod or last handle.
234
+ const end = index === rangeValue.length - 1;
234
235
  return html`
235
236
  <i
236
237
  tabindex="0"
237
238
  part="handle"
238
- class="${classList({ "last-focus": this.lastFocus === index })}"
239
- @mousedown="${this.disabled ? null : this.createMouseDown(index)}"
240
- @focus="${this.disabled ? null : () => this.focusHandle(index)}"
241
- @blur="${this.disabled ? null : this.blurHandle}"
242
- style="z-index:${this.__focusStack.indexOf(index) + 1};--handle:var(--${
243
- /* In single-handle mod or end, it is max value */
244
- !range && end ? "to" : `handle-${index}`
245
- })"
239
+ class="${tokenList({ "last-focus": this.lastFocus === index })}"
240
+ @mousedown="${disabled ? null : this.createMouseDown(index)}"
241
+ @focus="${disabled ? null : () => this.focusHandle(index)}"
242
+ @blur="${disabled ? null : this.blurHandle}"
243
+ style="${joinProperties({
244
+ "z-index": this.__focusStack.indexOf(index) + 1,
245
+ "--handle": `var(--${end ? "to" : `handle-${index}`})`,
246
+ })}"
246
247
  ></i>
247
248
  `;
248
249
  }
@@ -271,37 +272,36 @@ class Range extends SuperInput {
271
272
  }
272
273
 
273
274
  protected createKeydownEvent(index: number) {
274
- if (!this.range) {
275
+ const { rangeValue, step } = this;
276
+ if (rangeValue.length < 2) {
275
277
  index = 0;
276
278
  }
277
279
  return (e: KeyboardEvent): void => {
280
+ const old = rangeValue[index];
278
281
  if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
279
282
  e.preventDefault();
280
- this.createSetValue(index)((old) => old - this.step);
283
+ this.createSetValue(index)(old - step);
281
284
  } else if (e.key === "ArrowRight" || e.key === "ArrowUp") {
282
285
  e.preventDefault();
283
- this.createSetValue(index)((old) => old + this.step);
286
+ this.createSetValue(index)(old + step);
284
287
  }
285
288
  };
286
289
  }
287
290
 
288
- createMouseDown(index: number) {
291
+ protected createMouseDown(index: number) {
289
292
  return (e: MouseEvent): void => {
290
293
  this.focusHandle(index);
291
294
  this.createMousedownListener(this.createSetValue(index))(e);
292
295
  };
293
296
  }
294
297
 
295
- createSetValue(index: number) {
296
- return (numberOrModifier: number | ((value: number) => number)): void => {
297
- const number =
298
- typeof numberOrModifier === "number"
299
- ? this.normalizeValue(numberOrModifier)
300
- : numberOrModifier(this.rangeValue[index]);
301
- let newValue: any = number;
298
+ protected createSetValue(index: number) {
299
+ return (value: number): void => {
300
+ const normalizeValue = this._ranger.normalize(value);
301
+ let newValue: number | number[] = normalizeValue;
302
302
  if (this.range) {
303
- newValue = [...this.rangeValue];
304
- newValue[index] = number;
303
+ newValue = [...(this.value as number[])];
304
+ newValue[index] = normalizeValue;
305
305
  }
306
306
  this.value = newValue;
307
307
  this.dispatchEvent(new CustomEvent("range", { detail: this.value }));
@@ -311,23 +311,9 @@ class Range extends SuperInput {
311
311
  /**
312
312
  * Compute value from event.
313
313
  */
314
- protected _computeValue(e: MouseEvent): number {
315
- const rect = this._root.getBoundingClientRect();
316
- const div = this.vertical ? (e.clientY - rect.top) / rect.height : (e.clientX - rect.left) / rect.width;
317
- const value = Math.round((div * (this.max - this.min)) / this.step) * this.step;
318
- return this.normalizeValue(value);
319
- }
320
-
321
- /**
322
- * Ensure that the values do not exceed the range of max and min.
323
- */
324
- normalizeValue(value: number): number {
325
- if (value > this.max) {
326
- value -= this.step;
327
- } else if (value < this.min) {
328
- value += this.step;
329
- }
330
- return value;
314
+ protected _computeValue({ clientX, clientY }: MouseEvent): number {
315
+ const { top, left, height, width } = this._root.getBoundingClientRect();
316
+ return this._ranger.present(this.vertical ? (clientY - top) / height : (clientX - left) / width);
331
317
  }
332
318
 
333
319
  protected _handleMousedownRoot(e: MouseEvent): void {
@@ -360,10 +346,10 @@ class Range extends SuperInput {
360
346
  };
361
347
  }
362
348
 
363
- protected createMousemoveListener(callback: (arg0: number) => void) {
349
+ protected createMousemoveListener(callback: (newValue: number) => void) {
364
350
  return (e: MouseEvent): void => {
365
351
  const value = this._computeValue(e);
366
- if (value > this.max || value < this.min) {
352
+ if (value !== this._ranger.restrict(value)) {
367
353
  return;
368
354
  }
369
355
  callback?.call(this, value);
@@ -371,7 +357,7 @@ class Range extends SuperInput {
371
357
  }
372
358
 
373
359
  protected _connectedInit(): void {
374
- const gap = this.max - this.min;
360
+ const gap = this._ranger.diff;
375
361
  this.step ||= gap / 100;
376
362
  if (isNil(this.value)) {
377
363
  if (!isNil(this.default)) {
@@ -21,6 +21,14 @@ interface RouteItem {
21
21
  component?: unknown;
22
22
  }
23
23
 
24
+ const routerTypes = {
25
+ field: "field",
26
+ slotted: "slotted",
27
+ united: "united",
28
+ } as const;
29
+
30
+ type RouterType = keyof typeof routerTypes;
31
+
24
32
  const protoName = "router";
25
33
 
26
34
  /**
@@ -101,7 +109,7 @@ class Router extends GlobalStyle {
101
109
  * This property should not be changed after the rendering is complete.
102
110
  */
103
111
  @property()
104
- type: "united" | "slotted" | "field" = "united";
112
+ type: RouterType = routerTypes.united;
105
113
 
106
114
  /**
107
115
  * Cache accessed records.
@@ -126,22 +134,23 @@ class Router extends GlobalStyle {
126
134
  }
127
135
 
128
136
  protected render(): unknown {
129
- if (this.cache) {
130
- const cached = this.__cacheRecord.get(this.pathname);
131
- if (cached) {
132
- Object.assign(this, cached);
133
- return this.component;
134
- }
137
+ let cached: RouteResult | undefined;
138
+ if (this.cache && (cached = this.__cacheRecord.get(this.pathname))) {
139
+ this.component = cached.component;
140
+ this.path = cached.path;
141
+ this.pathname = cached.pathname;
135
142
  }
136
- switch (this.type) {
137
- case "field":
138
- this.component = this.fieldComponent();
139
- break;
140
- case "slotted":
141
- this.component = this.slottedComponent();
142
- break;
143
- default:
144
- this.component = this.fieldComponent() ?? this.slottedComponent();
143
+ if (!cached) {
144
+ switch (this.type) {
145
+ case routerTypes.field:
146
+ this.component = this.fieldComponent();
147
+ break;
148
+ case routerTypes.slotted:
149
+ this.component = this.slottedComponent();
150
+ break;
151
+ default:
152
+ this.component = this.fieldComponent() ?? this.slottedComponent();
153
+ }
145
154
  }
146
155
  return this.component ?? this.default;
147
156
  }
@@ -151,10 +160,9 @@ class Router extends GlobalStyle {
151
160
  Router.routerInstances.add(this);
152
161
 
153
162
  if (this.type !== "field") {
154
- const mutationObserver = new MutationObserver(this.collectSlottedRoutes);
155
- mutationObserver.observe(this, {
156
- attributeFilter: ["slot"],
163
+ this.observers.add(this, MutationObserver, this.collectSlottedRoutes, {
157
164
  attributes: true,
165
+ attributeFilter: ["slot"],
158
166
  subtree: true,
159
167
  });
160
168
  this.collectSlottedRoutes();
@@ -179,8 +187,7 @@ class Router extends GlobalStyle {
179
187
  const shouldDispatch = changedProperties.has("pathname") || changedProperties.has("path");
180
188
  if (shouldDispatch) {
181
189
  const ur = this.useRouter();
182
- const noRecord = !this.__cacheRecord.has(this.pathname);
183
- if (noRecord) {
190
+ if (!this.__cacheRecord.has(this.pathname) && this.path) {
184
191
  this.__cacheRecord.set(this.pathname, ur);
185
192
  }
186
193
  this.dispatchEvent(new CustomEvent("change", { detail: ur }));
@@ -258,6 +265,10 @@ class Router extends GlobalStyle {
258
265
  });
259
266
  }
260
267
 
268
+ search(pathname: string): RouteTree {
269
+ return this.__fieldRouteTree.search(pathname) || this.__slottedRouteTree.search(pathname);
270
+ }
271
+
261
272
  handlePopstate: () => void = this.events.add(window, "popstate", () => {
262
273
  this.pathname = location.pathname;
263
274
  });
@@ -1,4 +1,4 @@
1
- import { type HandlerEvent, attr, classList, godown, styles } from "@godown/element";
1
+ import { type HandlerEvent, attr, tokenList, godown, styles, loop } from "@godown/element";
2
2
  import { type TemplateResult, css, html } from "lit";
3
3
  import { property, state } from "lit/decorators.js";
4
4
 
@@ -8,14 +8,6 @@ import SuperInput from "../core/super-input.js";
8
8
  const protoName = "split";
9
9
  const cssScope = scopePrefix(protoName);
10
10
 
11
- const loop = <T>(len: number, fn: (index?: number) => T) => {
12
- const result: T[] = new Array(len);
13
- for (let index = 0; index < len; index++) {
14
- result[index] = fn(index);
15
- }
16
- return result;
17
- };
18
-
19
11
  /**
20
12
  * {@linkcode Split} renders multiple input boxes.
21
13
  *
@@ -106,7 +98,7 @@ class Split extends SuperInput {
106
98
  (index: number) => html`
107
99
  <span
108
100
  part="input-box"
109
- class="${classList({ focus: this.current === index })}"
101
+ class="${tokenList({ focus: this.current === index })}"
110
102
  @click="${this.disabled ? null : () => this.focusAt(index)}"
111
103
  >
112
104
  ${this.currentValue[index]}
@@ -1,4 +1,4 @@
1
- import { attr, classList, godown, htmlSlot, styles } from "@godown/element";
1
+ import { attr, tokenList, godown, htmlSlot, styles } from "@godown/element";
2
2
  import { type TemplateResult, css, html } from "lit";
3
3
  import { property } from "lit/decorators.js";
4
4
 
@@ -80,7 +80,7 @@ class Text extends GlobalStyle {
80
80
  <span
81
81
  part="root"
82
82
  ${attr(this.observedRecord)}
83
- class="${classList(this.underline)}"
83
+ class="${tokenList(this.underline)}"
84
84
  >
85
85
  ${htmlSlot()}
86
86
  </span>
@@ -63,32 +63,17 @@ class Time extends GlobalStyle {
63
63
  `;
64
64
  }
65
65
 
66
- protected firstUpdated(): void {
67
- if (this.timeout) {
68
- this.timeoutId = this.startTimeout();
69
- }
70
- }
71
-
72
66
  protected updated(changedProperties: PropertyValues): void {
73
- if (changedProperties.has("timeout")) {
74
- if (this.timeout) {
75
- clearInterval(this.timeoutId);
76
- this.timeoutId = this.startTimeout();
77
- }
67
+ if (changedProperties.has("timeout") && this.timeout) {
68
+ this.timeouts.remove(this.timeoutId);
69
+ this.timeoutId = this.timeouts.add(
70
+ setInterval(() => {
71
+ this.dispatchEvent(new CustomEvent("time", { detail: this.time, composed: true }));
72
+ this.time = new Date(this.time.getTime() + (this.gap || this.timeout));
73
+ }, Math.abs(this.timeout)),
74
+ );
78
75
  }
79
76
  }
80
-
81
- disconnectedCallback(): void {
82
- clearInterval(this.timeoutId);
83
- this.timeoutId = undefined;
84
- }
85
-
86
- startTimeout(): number {
87
- return setInterval(() => {
88
- this.dispatchEvent(new CustomEvent("time", { detail: this.time, composed: true }));
89
- this.time = new Date(this.time.getTime() + (this.gap || this.timeout));
90
- }, Math.abs(this.timeout));
91
- }
92
77
  }
93
78
 
94
79
  export default Time;
@@ -125,13 +125,15 @@ class Typewriter extends GlobalStyle {
125
125
  write(at: number = this.index): void {
126
126
  this.contentInternal = this.content.slice(0, at + 1);
127
127
  const timeout = this.delay || random(this.max, this.min);
128
- this.timeoutID = setTimeout(() => {
129
- const nx = at + 1;
130
- if (nx <= this.len) {
131
- this.index = nx;
132
- this.write();
133
- }
134
- }, timeout);
128
+ this.timeoutID = this.timeouts.add(
129
+ setTimeout(() => {
130
+ const nx = at + 1;
131
+ if (nx <= this.len) {
132
+ this.index = nx;
133
+ this.write();
134
+ }
135
+ }, timeout),
136
+ );
135
137
  }
136
138
 
137
139
  stop(): void {
@@ -26,6 +26,7 @@ export const cssGlobalVars: {
26
26
  input: CSSResult;
27
27
  white: CSSResult;
28
28
  black: CSSResult;
29
+ color: CSSResult;
29
30
  } = {
30
31
  foreground: scopePrefix("foreground", 2),
31
32
  background: scopePrefix("background", 2),
@@ -36,6 +37,7 @@ export const cssGlobalVars: {
36
37
  input: scopePrefix("input", 2),
37
38
  white: scopePrefix("color-white", 2),
38
39
  black: scopePrefix("color-black", 2),
40
+ color: scopePrefix("color", 2),
39
41
  };
40
42
 
41
43
  type PresetsGradientsCSSResult = Record<keyof typeof presetsRGB, Gradients<CSSResult>>;
@@ -46,19 +48,21 @@ GlobalStyle.styles = [
46
48
  `${cssGlobalVars.white}:rgb(255 255 255);` +
47
49
  travel((key, gradient, rgb) => {
48
50
  cssGlobalVars._colors[key] ||= [] as any;
49
- cssGlobalVars._colors[key].push(unsafeCSS(scopePrefix("color", 2) + "-" + key + "-" + gradient));
51
+ cssGlobalVars._colors[key].push(unsafeCSS(cssGlobalVars.color + "-" + key + "-" + gradient));
50
52
  const endKey = `-${key}-${gradient}`;
51
- const colorKey = scopePrefix("color", 2) + endKey;
53
+ const colorKey = cssGlobalVars.color + endKey;
52
54
  return `${colorKey}:rgb(${rgb});`;
53
55
  }, presetsRGB).join("") +
54
- joinProperties({
55
- [cssGlobalVars.background + ""]: `var(${cssGlobalVars._colors.darkgray[9]})`,
56
- [cssGlobalVars.foreground + ""]: `var(${cssGlobalVars._colors.lightgray[0]})`,
57
- [cssGlobalVars.active + ""]: `var(${cssGlobalVars._colors.blue[6]})`,
58
- [cssGlobalVars.passive + ""]: `var(${cssGlobalVars._colors.darkgray[6]})`,
59
- [cssGlobalVars.clipBackground + ""]:
56
+ joinProperties([
57
+ [cssGlobalVars.background, `var(${cssGlobalVars._colors.darkgray[9]})`],
58
+ [cssGlobalVars.foreground, `var(${cssGlobalVars._colors.lightgray[0]})`],
59
+ [cssGlobalVars.active, `var(${cssGlobalVars._colors.blue[6]})`],
60
+ [cssGlobalVars.passive, `var(${cssGlobalVars._colors.darkgray[6]})`],
61
+ [
62
+ cssGlobalVars.clipBackground,
60
63
  `linear-gradient(to bottom, var(${cssGlobalVars.foreground}), var(${cssGlobalVars.passive}))`,
61
- }) +
64
+ ],
65
+ ]) +
62
66
  "}",
63
67
  ),
64
68
  css`
@@ -28,13 +28,17 @@ class SuperAnchor extends GlobalStyle {
28
28
  * A element href.
29
29
  */
30
30
  @property()
31
- href: string = undefined;
31
+ href: string;
32
32
  /**
33
33
  * A element target.
34
34
  */
35
35
  @property()
36
36
  target: "_blank" | "_self" | "_parent" | "_top" = "_self";
37
37
 
38
+ get pathname(): string {
39
+ return new URL(this.href, location.href).pathname;
40
+ }
41
+
38
42
  protected render(): TemplateResult<1> {
39
43
  return html`
40
44
  <a