godown 3.2.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 (93) hide show
  1. package/build/godown+lit.iife.js +12 -12
  2. package/build/godown+lit.iife.js.map +1 -1
  3. package/build/godown+lit.js +12 -12
  4. package/build/godown+lit.js.map +1 -1
  5. package/build/godown+lit.umd.js +12 -12
  6. package/build/godown+lit.umd.js.map +1 -1
  7. package/build/godown.iife.js +10 -10
  8. package/build/godown.js +10 -10
  9. package/build/godown.js.map +1 -1
  10. package/build/godown.umd.js +10 -10
  11. package/build/godown.umd.js.map +1 -1
  12. package/components/alert.d.ts +1 -3
  13. package/components/alert.d.ts.map +1 -1
  14. package/components/alert.js +1 -1
  15. package/components/alert.js.map +1 -1
  16. package/components/button.d.ts +1 -1
  17. package/components/button.d.ts.map +1 -1
  18. package/components/button.js.map +1 -1
  19. package/components/carousel.d.ts +5 -11
  20. package/components/carousel.d.ts.map +1 -1
  21. package/components/carousel.js +1 -1
  22. package/components/carousel.js.map +1 -1
  23. package/components/input.js +1 -1
  24. package/components/input.js.map +1 -1
  25. package/components/range.d.ts +7 -12
  26. package/components/range.d.ts.map +1 -1
  27. package/components/range.js +1 -1
  28. package/components/range.js.map +1 -1
  29. package/components/router.d.ts.map +1 -1
  30. package/components/router.js +1 -1
  31. package/components/router.js.map +1 -1
  32. package/components/split.js +1 -1
  33. package/components/split.js.map +1 -1
  34. package/components/text.js +1 -1
  35. package/components/text.js.map +1 -1
  36. package/components/time.d.ts +0 -3
  37. package/components/time.d.ts.map +1 -1
  38. package/components/time.js +1 -1
  39. package/components/time.js.map +1 -1
  40. package/components/typewriter.d.ts.map +1 -1
  41. package/components/typewriter.js +1 -1
  42. package/components/typewriter.js.map +1 -1
  43. package/core/global-style.d.ts +1 -0
  44. package/core/global-style.d.ts.map +1 -1
  45. package/core/global-style.js +1 -1
  46. package/core/global-style.js.map +1 -1
  47. package/custom-elements.json +1 -1
  48. package/dev/components/alert.d.ts +1 -3
  49. package/dev/components/alert.d.ts.map +1 -1
  50. package/dev/components/alert.js +32 -56
  51. package/dev/components/alert.js.map +1 -1
  52. package/dev/components/button.d.ts +1 -1
  53. package/dev/components/button.d.ts.map +1 -1
  54. package/dev/components/button.js.map +1 -1
  55. package/dev/components/carousel.d.ts +5 -11
  56. package/dev/components/carousel.d.ts.map +1 -1
  57. package/dev/components/carousel.js +38 -37
  58. package/dev/components/carousel.js.map +1 -1
  59. package/dev/components/input.js +2 -2
  60. package/dev/components/range.d.ts +7 -12
  61. package/dev/components/range.d.ts.map +1 -1
  62. package/dev/components/range.js +39 -53
  63. package/dev/components/range.js.map +1 -1
  64. package/dev/components/router.d.ts.map +1 -1
  65. package/dev/components/router.js +2 -3
  66. package/dev/components/router.js.map +1 -1
  67. package/dev/components/split.js +2 -2
  68. package/dev/components/text.js +2 -2
  69. package/dev/components/time.d.ts +0 -3
  70. package/dev/components/time.d.ts.map +1 -1
  71. package/dev/components/time.js +6 -20
  72. package/dev/components/time.js.map +1 -1
  73. package/dev/components/typewriter.d.ts.map +1 -1
  74. package/dev/components/typewriter.js +2 -2
  75. package/dev/components/typewriter.js.map +1 -1
  76. package/dev/core/global-style.d.ts +1 -0
  77. package/dev/core/global-style.d.ts.map +1 -1
  78. package/dev/core/global-style.js +13 -9
  79. package/dev/core/global-style.js.map +1 -1
  80. package/package.json +3 -3
  81. package/src/components/alert.ts +33 -64
  82. package/src/components/button.ts +1 -1
  83. package/src/components/carousel.ts +43 -42
  84. package/src/components/input.ts +2 -2
  85. package/src/components/range.ts +47 -61
  86. package/src/components/router.ts +2 -3
  87. package/src/components/split.ts +2 -2
  88. package/src/components/text.ts +2 -2
  89. package/src/components/time.ts +8 -23
  90. package/src/components/typewriter.ts +9 -7
  91. package/src/core/global-style.ts +13 -9
  92. package/vscode.html-custom-data.json +1 -1
  93. package/web-types.json +1 -1
@@ -40,32 +40,6 @@ const darkStyles = constructCSSObject(
40
40
  (prop) => toVar(prop),
41
41
  );
42
42
 
43
- const genLight = (key: string) => {
44
- return [cssGlobalVars._colors[key][6], cssGlobalVars._colors[key][0]];
45
- };
46
-
47
- /**
48
- * @deprecated
49
- */
50
- const lightStyles = constructCSSObject(
51
- vars,
52
- {
53
- green: genLight("green"),
54
- blue: genLight("blue"),
55
- orange: genLight("orange"),
56
- red: genLight("red"),
57
- yellow: genLight("yellow"),
58
- purple: genLight("purple"),
59
- teal: genLight("teal"),
60
- pink: genLight("pink"),
61
- gray: [cssGlobalVars._colors.darkgray[5], cssGlobalVars._colors.lightgray[7]],
62
- white: [cssGlobalVars._colors.lightgray[0], cssGlobalVars._colors.darkgray[0]],
63
- black: [cssGlobalVars._colors.darkgray[7], cssGlobalVars._colors.lightgray[3]],
64
- },
65
- () => ":host",
66
- (prop) => toVar(prop),
67
- );
68
-
69
43
  const calls = {
70
44
  tip: {
71
45
  color: "teal",
@@ -116,67 +90,58 @@ const calls = {
116
90
  @styles(css`
117
91
  :host,
118
92
  :where(:host([contents]) [part="root"]) {
119
- border-radius: var(${cssScope}--border-radius);
120
93
  ${cssScope}--border-radius: .25em;
121
94
  ${cssScope}--border-width: .075em;
122
95
  ${cssScope}--blockquote-width: .2em;
123
- ${cssScope}--padding: .5em;
96
+ ${cssScope}--blockquote-background: transparent;
97
+ ${cssScope}--gap: .5em;
98
+ border-radius: var(${cssScope}--border-radius);
124
99
  display: block;
125
100
  width: 100%;
126
101
  }
127
102
 
128
103
  [part="root"] {
129
- --color: var(${cssScope}--color);
130
- color: var(--color);
131
- width: 100%;
132
- transition: 0.25s;
133
- display: flex;
134
- justify-content: space-between;
135
- padding: var(${cssScope}--padding);
104
+ color: var(${cssScope}--color, currentColor);
105
+ display: grid;
106
+ align-items: center;
107
+ grid-template-columns: auto 1fr auto;
108
+ grid-template-rows: auto 1fr;
109
+ border-color: currentColor;
136
110
  border-radius: inherit;
137
- border: var(${cssScope}--border-width) solid var(--color);
111
+ border-style: solid;
112
+ border-width: var(${cssScope}--border-width);
113
+ padding: var(${cssScope}--gap);
138
114
  background: var(${cssScope}--background);
139
115
  }
140
116
 
141
117
  [variant="blockquote"] {
142
118
  border-radius: 0;
143
- border-left: var(${cssScope}--blockquote-width) solid var(--color);
144
- border-bottom: none;
145
- border-right: none;
146
- border-top: none;
147
- background: transparent;
119
+ border-width: 0;
120
+ border-left-width: var(${cssScope}--blockquote-width);
121
+ background: var(${cssScope}--blockquote-background);
148
122
  }
149
123
 
150
- [part="content"] {
151
- color: var(--color);
152
- }
153
-
154
- [part="root"] {
124
+ [part~="icon"] {
155
125
  display: grid;
156
126
  align-items: center;
157
- grid-template-columns: auto 1fr auto;
158
- grid-template-rows: auto 1fr;
127
+ height: 2em;
159
128
  }
160
129
 
161
- [part="title"] {
162
- line-height: 2em;
130
+ .start svg {
131
+ margin-inline-end: var(${cssScope}--gap);
163
132
  }
164
133
 
165
- [part="icon"] {
166
- display: inline-grid;
167
- align-items: center;
168
- height: 2em;
134
+ .end svg {
135
+ margin-inline-start: var(${cssScope}--gap);
169
136
  }
170
137
 
171
- [part="icon"] svg {
172
- margin-right: 0.5em;
138
+ svg {
173
139
  width: 1.25em;
174
140
  height: 1.25em;
175
141
  }
176
142
 
177
143
  [part="content"] {
178
144
  grid-row: span 2 / span 2;
179
- line-height: 1.5em;
180
145
  }
181
146
  `)
182
147
  class Alert extends GlobalStyle {
@@ -235,11 +200,9 @@ class Alert extends GlobalStyle {
235
200
  * Alert variant, if set to `blockquote`, the alert will be rendered as a blockquote.
236
201
  *
237
202
  * If variant is `"blockquote"`, hide the close button.
238
- *
239
- * ! __"light" will be deprecated__ in the future.
240
203
  */
241
204
  @property()
242
- variant: "blockquote" | "dark" | "light" = "dark";
205
+ variant: "blockquote" | "dark" = "dark";
243
206
 
244
207
  protected render(): TemplateResult<1> {
245
208
  const color = calls[this.call]?.color || this.color;
@@ -249,7 +212,12 @@ class Alert extends GlobalStyle {
249
212
  part="root"
250
213
  ${attr(this.observedRecord)}
251
214
  >
252
- <div part="icon">${icon}</div>
215
+ <div
216
+ part="icon"
217
+ class="start"
218
+ >
219
+ ${icon}
220
+ </div>
253
221
  <div part="content">
254
222
  <strong part="title">${this.title || htmlSlot("title")}</strong>
255
223
  ${this.content || htmlSlot()}
@@ -258,14 +226,15 @@ class Alert extends GlobalStyle {
258
226
  ? ""
259
227
  : html`
260
228
  <div
261
- part="close"
229
+ part="icon close"
230
+ class="end"
262
231
  tabindex="0"
263
232
  @click="${this.close}"
264
233
  >
265
234
  ${iconXmark()}
266
235
  </div>
267
236
  `}
268
- ${htmlStyle(this.variant === "dark" ? darkStyles[color] : lightStyles[color])}
237
+ ${htmlStyle(darkStyles[color])}
269
238
  </div>
270
239
  `;
271
240
  }
@@ -277,7 +246,7 @@ class Alert extends GlobalStyle {
277
246
 
278
247
  protected firstUpdated(): void {
279
248
  if (this.autoclose) {
280
- setTimeout(() => this.close(), this.autoclose);
249
+ this.timeouts.add(setTimeout(() => this.close(), this.autoclose));
281
250
  }
282
251
  }
283
252
 
@@ -249,7 +249,7 @@ class Button extends GlobalStyle {
249
249
  super.blur();
250
250
  }
251
251
 
252
- firstUpdated(): void {
252
+ protected firstUpdated(): void {
253
253
  this.events.add(this, "click", this._handelClick, true);
254
254
  }
255
255
 
@@ -1,4 +1,4 @@
1
- import { attr, godown, htmlSlot, htmlStyle, part, styles } from "@godown/element";
1
+ import { attr, godown, htmlSlot, part, styles } from "@godown/element";
2
2
  import iconChevronLeft from "@godown/f7-icon/icons/chevron-left.js";
3
3
  import iconChevronRight from "@godown/f7-icon/icons/chevron-right.js";
4
4
  import { type TemplateResult, css, html } from "lit";
@@ -8,16 +8,16 @@ import { GlobalStyle } from "../core/global-style.js";
8
8
 
9
9
  const protoName = "carousel";
10
10
 
11
+ function getWidth(e) {
12
+ return e.getBoundingClientRect().width;
13
+ }
14
+
11
15
  /**
12
16
  * {@linkcode Carousel} make the content display as a carousel.
13
17
  *
14
18
  * When this component is `firstUpdated`,
15
19
  * clone the first and last element and make the matching element visible when switching index.
16
20
  *
17
- * Child elements should maintain the same size.
18
- *
19
- * If no width, it will be the width of the first element.
20
- *
21
21
  * @slot - Carousel items, should maintain the same size.
22
22
  * @fires change - Fires when the index changes.
23
23
  * @category display
@@ -80,12 +80,6 @@ class Carousel extends GlobalStyle {
80
80
  @property({ type: Number })
81
81
  autoChange = 0;
82
82
 
83
- /**
84
- * Element width.
85
- */
86
- @property()
87
- width: string;
88
-
89
83
  @part("move-root")
90
84
  protected _moveRoot: HTMLElement;
91
85
 
@@ -95,6 +89,8 @@ class Carousel extends GlobalStyle {
95
89
 
96
90
  private __cloneLast: HTMLElement | undefined;
97
91
 
92
+ protected _offset: number;
93
+
98
94
  protected render(): TemplateResult<1> {
99
95
  return html`
100
96
  <div
@@ -107,47 +103,59 @@ class Carousel extends GlobalStyle {
107
103
  >
108
104
  ${iconChevronLeft()}
109
105
  </i>
110
- <div
111
- part="move-root"
112
- style="transform:${`translateX(-${this.index + 1}00%)`}"
113
- >
114
- ${htmlSlot()}
115
- </div>
106
+ <div part="move-root">${htmlSlot()}</div>
116
107
  <i
117
108
  part="next"
118
109
  @click="${this.next}"
119
110
  >
120
111
  ${iconChevronRight()}
121
112
  </i>
122
- ${htmlStyle(`:host,:host([contents]) [part=root]{width:${this.width};}`)}
123
113
  </div>
124
114
  `;
125
115
  }
126
116
 
127
- protected async firstUpdated(): Promise<void> {
128
- await this.updateComplete;
129
-
117
+ connectedCallback(): void {
118
+ super.connectedCallback();
130
119
  if (this.children.length) {
131
- this.width ||= `${(this.firstElementChild as HTMLElement).offsetWidth}px`;
132
-
133
120
  this.__cloneFirst?.remove();
134
121
  this.__cloneLast?.remove();
135
122
  this.__cloneLast = this.firstElementChild.cloneNode(true) as HTMLElement;
136
123
  this.__cloneFirst = this.lastElementChild.cloneNode(true) as HTMLElement;
137
124
  this.appendChild(this.__cloneLast);
138
125
  this.insertBefore(this.__cloneFirst, this.firstElementChild);
139
- this.show(this.index);
140
126
  }
141
- this.checkInterval();
142
127
  }
143
128
 
144
- disconnectedCallback(): void {
145
- clearInterval(this.intervalID);
129
+ protected async firstUpdated(): Promise<void> {
130
+ await this.updateComplete;
131
+ this.show(this.index, true);
146
132
  }
147
133
 
148
- show(i: number): void {
134
+ attributeChangedCallback(name: string, _old: string | null, value: string | null): void {
135
+ super.attributeChangedCallback(name, _old, value);
136
+ if (name === "index" && this.isConnected) {
137
+ this.show(this.index);
138
+ }
139
+ }
140
+
141
+ show(i: number, n?: boolean): void {
142
+ i = this.normalizeIndex(i);
149
143
  this.index = i;
144
+ this._offset = 0;
145
+ for (let childIndex = 0; childIndex <= i; childIndex++) {
146
+ this._offset -= getWidth(this.children[childIndex]);
147
+ }
148
+ this._offset += (getWidth(this) - getWidth(this.children[i + 1])) / 2;
150
149
  this.dispatchEvent(new CustomEvent("change", { detail: i, composed: true }));
150
+ this._doTranslateX(`${this._offset}px`, n);
151
+ this.timeouts.remove(this.intervalID);
152
+ if (this.autoChange > 0) {
153
+ this.intervalID = this.timeouts.add(
154
+ setInterval(() => {
155
+ this.next();
156
+ }, this.autoChange),
157
+ );
158
+ }
151
159
  }
152
160
 
153
161
  next(): void {
@@ -157,7 +165,6 @@ class Carousel extends GlobalStyle {
157
165
  } else {
158
166
  this.show(this.index + 1);
159
167
  }
160
- this.checkInterval();
161
168
  }
162
169
 
163
170
  prev(): void {
@@ -167,26 +174,20 @@ class Carousel extends GlobalStyle {
167
174
  } else {
168
175
  this.show(this.index - 1);
169
176
  }
170
- this.checkInterval();
171
177
  }
172
178
 
173
179
  protected _doTranslateX(xValue: string, noTransition?: boolean): void {
174
180
  this._moveRoot.style.transform = `translateX(${xValue})`;
175
- if (noTransition) {
176
- this._moveRoot.style.transition = "none";
177
- }
178
- this._moveRoot.getBoundingClientRect();
181
+ this._moveRoot.style.transition = noTransition ? "none" : "";
179
182
  }
180
183
 
181
- checkInterval(): void {
182
- if (this.autoChange) {
183
- if (this.intervalID) {
184
- clearInterval(this.intervalID);
185
- }
186
- this.intervalID = setInterval(() => {
187
- this.next();
188
- }, this.autoChange);
184
+ normalizeIndex(i: number): number {
185
+ if (i < 0) {
186
+ return 0;
187
+ } else if (i > this.children.length - 3) {
188
+ return this.children.length - 3;
189
189
  }
190
+ return i;
190
191
  }
191
192
  }
192
193
 
@@ -1,4 +1,4 @@
1
- import { attr, classList, godown, part, styles } from "@godown/element";
1
+ import { attr, tokenList, godown, part, styles } from "@godown/element";
2
2
  import { type TemplateResult, css, html, nothing } from "lit";
3
3
  import { property } from "lit/decorators.js";
4
4
 
@@ -44,7 +44,7 @@ class Input extends SuperInput {
44
44
  <div
45
45
  part="root"
46
46
  ${attr(this.observedRecord)}
47
- class="${classList("input-field", this.variant)}"
47
+ class="${tokenList("input-field", this.variant)}"
48
48
  >
49
49
  ${[
50
50
  this._renderPrefix(),
@@ -1,4 +1,4 @@
1
- import { attr, classList, godown, isNil, joinProperties, loop, 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,26 +195,31 @@ 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
225
  ${loop(this.rangeValue.length, (index) => this._renderHandle(index))}
@@ -229,20 +228,22 @@ class Range extends SuperInput {
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)) {
@@ -160,10 +160,9 @@ class Router extends GlobalStyle {
160
160
  Router.routerInstances.add(this);
161
161
 
162
162
  if (this.type !== "field") {
163
- const mutationObserver = new MutationObserver(this.collectSlottedRoutes);
164
- mutationObserver.observe(this, {
165
- attributeFilter: ["slot"],
163
+ this.observers.add(this, MutationObserver, this.collectSlottedRoutes, {
166
164
  attributes: true,
165
+ attributeFilter: ["slot"],
167
166
  subtree: true,
168
167
  });
169
168
  this.collectSlottedRoutes();
@@ -1,4 +1,4 @@
1
- import { type HandlerEvent, attr, classList, godown, styles, loop } 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
 
@@ -98,7 +98,7 @@ class Split extends SuperInput {
98
98
  (index: number) => html`
99
99
  <span
100
100
  part="input-box"
101
- class="${classList({ focus: this.current === index })}"
101
+ class="${tokenList({ focus: this.current === index })}"
102
102
  @click="${this.disabled ? null : () => this.focusAt(index)}"
103
103
  >
104
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 {