godown 3.0.0-canary.1 → 3.0.0-canary.10

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 (301) hide show
  1. package/README.md +37 -8
  2. package/components/alert.d.ts +5 -3
  3. package/components/alert.d.ts.map +1 -1
  4. package/components/alert.js +24 -14
  5. package/components/alert.js.map +1 -1
  6. package/components/avatar.d.ts +5 -1
  7. package/components/avatar.d.ts.map +1 -1
  8. package/components/avatar.js +7 -3
  9. package/components/avatar.js.map +1 -1
  10. package/components/breath.d.ts +2 -1
  11. package/components/breath.d.ts.map +1 -1
  12. package/components/breath.js +5 -4
  13. package/components/breath.js.map +1 -1
  14. package/components/button.d.ts +16 -9
  15. package/components/button.d.ts.map +1 -1
  16. package/components/button.js +22 -20
  17. package/components/button.js.map +1 -1
  18. package/components/card.d.ts +1 -2
  19. package/components/card.d.ts.map +1 -1
  20. package/components/card.js +5 -11
  21. package/components/card.js.map +1 -1
  22. package/components/carousel.d.ts +6 -5
  23. package/components/carousel.d.ts.map +1 -1
  24. package/components/carousel.js +3 -2
  25. package/components/carousel.js.map +1 -1
  26. package/components/details.d.ts +5 -2
  27. package/components/details.d.ts.map +1 -1
  28. package/components/details.js +5 -2
  29. package/components/details.js.map +1 -1
  30. package/components/dialog.d.ts +8 -4
  31. package/components/dialog.d.ts.map +1 -1
  32. package/components/dialog.js +17 -12
  33. package/components/dialog.js.map +1 -1
  34. package/components/divider.d.ts +1 -1
  35. package/components/divider.js +1 -1
  36. package/components/divider.js.map +1 -1
  37. package/components/dragbox.d.ts +7 -7
  38. package/components/dragbox.d.ts.map +1 -1
  39. package/components/dragbox.js +1 -1
  40. package/components/dragbox.js.map +1 -1
  41. package/components/flex.d.ts +2 -1
  42. package/components/flex.d.ts.map +1 -1
  43. package/components/flex.js +8 -0
  44. package/components/flex.js.map +1 -1
  45. package/components/form.d.ts +0 -2
  46. package/components/form.d.ts.map +1 -1
  47. package/components/form.js +0 -2
  48. package/components/form.js.map +1 -1
  49. package/components/grid.d.ts +8 -3
  50. package/components/grid.d.ts.map +1 -1
  51. package/components/grid.js +1 -0
  52. package/components/grid.js.map +1 -1
  53. package/components/input.d.ts +2 -3
  54. package/components/input.d.ts.map +1 -1
  55. package/components/input.js +3 -6
  56. package/components/input.js.map +1 -1
  57. package/components/layout.d.ts +3 -6
  58. package/components/layout.d.ts.map +1 -1
  59. package/components/layout.js +21 -10
  60. package/components/layout.js.map +1 -1
  61. package/components/link.d.ts +3 -1
  62. package/components/link.d.ts.map +1 -1
  63. package/components/link.js +3 -1
  64. package/components/link.js.map +1 -1
  65. package/components/progress.d.ts +2 -11
  66. package/components/progress.d.ts.map +1 -1
  67. package/components/progress.js +6 -15
  68. package/components/progress.js.map +1 -1
  69. package/components/range.d.ts +43 -17
  70. package/components/range.d.ts.map +1 -1
  71. package/components/range.js +132 -58
  72. package/components/range.js.map +1 -1
  73. package/components/rotate.d.ts +1 -1
  74. package/components/rotate.d.ts.map +1 -1
  75. package/components/rotate.js +1 -1
  76. package/components/rotate.js.map +1 -1
  77. package/components/router.d.ts +6 -8
  78. package/components/router.d.ts.map +1 -1
  79. package/components/router.js +10 -10
  80. package/components/router.js.map +1 -1
  81. package/components/select.d.ts +4 -8
  82. package/components/select.d.ts.map +1 -1
  83. package/components/select.js +42 -41
  84. package/components/select.js.map +1 -1
  85. package/components/skeleton.d.ts.map +1 -1
  86. package/components/skeleton.js +3 -4
  87. package/components/skeleton.js.map +1 -1
  88. package/components/split.d.ts +18 -1
  89. package/components/split.d.ts.map +1 -1
  90. package/components/split.js +52 -19
  91. package/components/split.js.map +1 -1
  92. package/components/switch.d.ts +4 -4
  93. package/components/switch.d.ts.map +1 -1
  94. package/components/switch.js +6 -6
  95. package/components/switch.js.map +1 -1
  96. package/components/text.js +3 -3
  97. package/components/text.js.map +1 -1
  98. package/components/time.d.ts +4 -20
  99. package/components/time.d.ts.map +1 -1
  100. package/components/time.js +5 -66
  101. package/components/time.js.map +1 -1
  102. package/components/tooltip.d.ts +11 -1
  103. package/components/tooltip.d.ts.map +1 -1
  104. package/components/tooltip.js +23 -5
  105. package/components/tooltip.js.map +1 -1
  106. package/components/typewriter.d.ts +2 -2
  107. package/components/typewriter.d.ts.map +1 -1
  108. package/components/typewriter.js +2 -2
  109. package/components/typewriter.js.map +1 -1
  110. package/core/global-style.d.ts.map +1 -1
  111. package/core/global-style.js +8 -1
  112. package/core/global-style.js.map +1 -1
  113. package/core/super-anchor.js +1 -1
  114. package/core/super-anchor.js.map +1 -1
  115. package/core/super-input.d.ts +2 -3
  116. package/core/super-input.d.ts.map +1 -1
  117. package/core/super-input.js +3 -6
  118. package/core/super-input.js.map +1 -1
  119. package/core/super-openable.js.map +1 -1
  120. package/custom-elements.json +1 -1
  121. package/dev/components/alert.d.ts +5 -3
  122. package/dev/components/alert.d.ts.map +1 -1
  123. package/dev/components/alert.js +35 -24
  124. package/dev/components/alert.js.map +1 -1
  125. package/dev/components/avatar.d.ts +5 -1
  126. package/dev/components/avatar.d.ts.map +1 -1
  127. package/dev/components/avatar.js +7 -6
  128. package/dev/components/avatar.js.map +1 -1
  129. package/dev/components/breath.d.ts +2 -1
  130. package/dev/components/breath.d.ts.map +1 -1
  131. package/dev/components/breath.js +3 -1
  132. package/dev/components/breath.js.map +1 -1
  133. package/dev/components/button.d.ts +16 -9
  134. package/dev/components/button.d.ts.map +1 -1
  135. package/dev/components/button.js +29 -25
  136. package/dev/components/button.js.map +1 -1
  137. package/dev/components/card.d.ts +1 -2
  138. package/dev/components/card.d.ts.map +1 -1
  139. package/dev/components/card.js +21 -29
  140. package/dev/components/card.js.map +1 -1
  141. package/dev/components/carousel.d.ts +6 -5
  142. package/dev/components/carousel.d.ts.map +1 -1
  143. package/dev/components/carousel.js +9 -7
  144. package/dev/components/carousel.js.map +1 -1
  145. package/dev/components/details.d.ts +5 -2
  146. package/dev/components/details.d.ts.map +1 -1
  147. package/dev/components/details.js +4 -1
  148. package/dev/components/details.js.map +1 -1
  149. package/dev/components/dialog.d.ts +8 -4
  150. package/dev/components/dialog.d.ts.map +1 -1
  151. package/dev/components/dialog.js +23 -18
  152. package/dev/components/dialog.js.map +1 -1
  153. package/dev/components/divider.d.ts +1 -1
  154. package/dev/components/divider.js +1 -1
  155. package/dev/components/dragbox.d.ts +7 -7
  156. package/dev/components/dragbox.d.ts.map +1 -1
  157. package/dev/components/dragbox.js.map +1 -1
  158. package/dev/components/flex.d.ts +2 -1
  159. package/dev/components/flex.d.ts.map +1 -1
  160. package/dev/components/flex.js +8 -0
  161. package/dev/components/flex.js.map +1 -1
  162. package/dev/components/form.d.ts +0 -2
  163. package/dev/components/form.d.ts.map +1 -1
  164. package/dev/components/form.js +0 -2
  165. package/dev/components/form.js.map +1 -1
  166. package/dev/components/grid.d.ts +8 -3
  167. package/dev/components/grid.d.ts.map +1 -1
  168. package/dev/components/grid.js +1 -0
  169. package/dev/components/grid.js.map +1 -1
  170. package/dev/components/input.d.ts +2 -3
  171. package/dev/components/input.d.ts.map +1 -1
  172. package/dev/components/input.js +1 -20
  173. package/dev/components/input.js.map +1 -1
  174. package/dev/components/layout.d.ts +3 -6
  175. package/dev/components/layout.d.ts.map +1 -1
  176. package/dev/components/layout.js +23 -10
  177. package/dev/components/layout.js.map +1 -1
  178. package/dev/components/link.d.ts +3 -1
  179. package/dev/components/link.d.ts.map +1 -1
  180. package/dev/components/link.js +3 -1
  181. package/dev/components/link.js.map +1 -1
  182. package/dev/components/progress.d.ts +2 -11
  183. package/dev/components/progress.d.ts.map +1 -1
  184. package/dev/components/progress.js +7 -16
  185. package/dev/components/progress.js.map +1 -1
  186. package/dev/components/range.d.ts +43 -17
  187. package/dev/components/range.d.ts.map +1 -1
  188. package/dev/components/range.js +157 -99
  189. package/dev/components/range.js.map +1 -1
  190. package/dev/components/rotate.d.ts +1 -1
  191. package/dev/components/rotate.d.ts.map +1 -1
  192. package/dev/components/rotate.js +1 -1
  193. package/dev/components/rotate.js.map +1 -1
  194. package/dev/components/router.d.ts +6 -8
  195. package/dev/components/router.d.ts.map +1 -1
  196. package/dev/components/router.js +10 -10
  197. package/dev/components/router.js.map +1 -1
  198. package/dev/components/select.d.ts +4 -8
  199. package/dev/components/select.d.ts.map +1 -1
  200. package/dev/components/select.js +46 -44
  201. package/dev/components/select.js.map +1 -1
  202. package/dev/components/skeleton.d.ts.map +1 -1
  203. package/dev/components/skeleton.js +2 -3
  204. package/dev/components/skeleton.js.map +1 -1
  205. package/dev/components/split.d.ts +18 -1
  206. package/dev/components/split.d.ts.map +1 -1
  207. package/dev/components/split.js +55 -22
  208. package/dev/components/split.js.map +1 -1
  209. package/dev/components/switch.d.ts +4 -4
  210. package/dev/components/switch.d.ts.map +1 -1
  211. package/dev/components/switch.js +12 -13
  212. package/dev/components/switch.js.map +1 -1
  213. package/dev/components/text.js +3 -3
  214. package/dev/components/time.d.ts +4 -20
  215. package/dev/components/time.d.ts.map +1 -1
  216. package/dev/components/time.js +5 -66
  217. package/dev/components/time.js.map +1 -1
  218. package/dev/components/tooltip.d.ts +11 -1
  219. package/dev/components/tooltip.d.ts.map +1 -1
  220. package/dev/components/tooltip.js +39 -16
  221. package/dev/components/tooltip.js.map +1 -1
  222. package/dev/components/typewriter.d.ts +2 -2
  223. package/dev/components/typewriter.d.ts.map +1 -1
  224. package/dev/components/typewriter.js +0 -1
  225. package/dev/components/typewriter.js.map +1 -1
  226. package/dev/core/global-style.d.ts.map +1 -1
  227. package/dev/core/global-style.js +8 -9
  228. package/dev/core/global-style.js.map +1 -1
  229. package/dev/core/super-input.d.ts +2 -3
  230. package/dev/core/super-input.d.ts.map +1 -1
  231. package/dev/core/super-input.js +21 -20
  232. package/dev/core/super-input.js.map +1 -1
  233. package/dev/range.d.ts +1 -1
  234. package/dev/range.d.ts.map +1 -1
  235. package/index.js +13 -13
  236. package/package.json +9 -7
  237. package/range.d.ts +1 -1
  238. package/range.d.ts.map +1 -1
  239. package/src/alert.ts +11 -0
  240. package/src/avatar.ts +11 -0
  241. package/src/breath.ts +13 -0
  242. package/src/button.ts +11 -0
  243. package/src/card.ts +11 -0
  244. package/src/carousel.ts +11 -0
  245. package/src/components/alert.ts +282 -0
  246. package/src/components/avatar.ts +95 -0
  247. package/src/components/breath.ts +153 -0
  248. package/src/components/button.ts +286 -0
  249. package/src/components/card.ts +80 -0
  250. package/src/components/carousel.ts +169 -0
  251. package/src/components/details.ts +116 -0
  252. package/src/components/dialog.ts +165 -0
  253. package/src/components/divider.ts +44 -0
  254. package/src/components/dragbox.ts +127 -0
  255. package/src/components/flex.ts +70 -0
  256. package/src/components/form.ts +82 -0
  257. package/src/components/grid.ts +75 -0
  258. package/src/components/input.ts +72 -0
  259. package/src/components/layout.ts +82 -0
  260. package/src/components/link.ts +38 -0
  261. package/src/components/progress.ts +95 -0
  262. package/src/components/range.ts +404 -0
  263. package/src/components/rotate.ts +92 -0
  264. package/src/components/router.ts +273 -0
  265. package/src/components/select.ts +268 -0
  266. package/src/components/skeleton.ts +118 -0
  267. package/src/components/split.ts +221 -0
  268. package/src/components/switch.ts +180 -0
  269. package/src/components/text.ts +95 -0
  270. package/src/components/time.ts +81 -0
  271. package/src/components/tooltip.ts +138 -0
  272. package/src/components/typewriter.ts +154 -0
  273. package/src/core/global-style.ts +86 -0
  274. package/src/core/super-anchor.ts +52 -0
  275. package/src/core/super-input.ts +230 -0
  276. package/src/core/super-openable.ts +51 -0
  277. package/src/details.ts +11 -0
  278. package/src/dialog.ts +11 -0
  279. package/src/divider.ts +11 -0
  280. package/src/dragbox.ts +11 -0
  281. package/src/flex.ts +11 -0
  282. package/src/form.ts +11 -0
  283. package/src/grid.ts +11 -0
  284. package/src/index.ts +28 -0
  285. package/src/input.ts +13 -0
  286. package/src/layout.ts +12 -0
  287. package/src/link.ts +13 -0
  288. package/src/progress.ts +12 -0
  289. package/src/range.ts +13 -0
  290. package/src/rotate.ts +13 -0
  291. package/src/router.ts +12 -0
  292. package/src/select.ts +13 -0
  293. package/src/skeleton.ts +13 -0
  294. package/src/split.ts +13 -0
  295. package/src/switch.ts +13 -0
  296. package/src/text.ts +13 -0
  297. package/src/time.ts +13 -0
  298. package/src/tooltip.ts +13 -0
  299. package/src/typewriter.ts +11 -0
  300. package/vscode.html-custom-data.json +1 -1
  301. package/web-types.json +1 -1
@@ -0,0 +1,72 @@
1
+ import { godown } from "@godown/element/decorators/godown.js";
2
+ import { part } from "@godown/element/decorators/part.js";
3
+ import { styles } from "@godown/element/decorators/styles.js";
4
+ import { classList } from "@godown/element/directives/class-list.js";
5
+ import { css, html, nothing } from "lit";
6
+ import { property } from "lit/decorators.js";
7
+
8
+ import { cssGlobalVars } from "../core/global-style.js";
9
+ import SuperInput from "../core/super-input.js";
10
+
11
+ const protoName = "input";
12
+
13
+ /**
14
+ * {@linkcode Input} renders a text input.
15
+ *
16
+ * @category input
17
+ */
18
+ @godown(protoName)
19
+ @styles(
20
+ css`
21
+ :host {
22
+ width: var(${cssGlobalVars.input}-width);
23
+ height: var(${cssGlobalVars.input}-height);
24
+ color: var(${cssGlobalVars.foreground});
25
+ background: var(${cssGlobalVars.input}-background);
26
+ border-radius: var(${cssGlobalVars.input}-radius);
27
+ display: block;
28
+ }
29
+ `,
30
+ )
31
+ class Input extends SuperInput {
32
+ type: "text" | "search" | "tel" | "url" | "email" | "password" = "text";
33
+
34
+ value: string;
35
+
36
+ /**
37
+ * If outline, the outline is always present.
38
+ */
39
+ @property()
40
+ variant: "default" | "outline" = "default";
41
+
42
+ @part("input")
43
+ protected _input: HTMLInputElement;
44
+
45
+ protected render() {
46
+ return html`<div part="root" class="${classList("input-field", this.variant)}">
47
+ ${[
48
+ this._renderPrefix(),
49
+ html`<input
50
+ part="input"
51
+ type="${this.type}"
52
+ id="${this.makeId}"
53
+ .value="${this.value}"
54
+ placeholder="${this.placeholder || nothing}"
55
+ ?autofocus="${this.autofocus}"
56
+ autocapitalize="${this.autocapitalize || nothing}"
57
+ autocomplete="${this.autocomplete || nothing}"
58
+ ?disabled="${this.disabled}"
59
+ @input="${this._handleInput}"
60
+ >`,
61
+ this._renderSuffix(),
62
+ ]}
63
+ </div>`;
64
+ }
65
+
66
+ reset() {
67
+ this._input.value = this.default;
68
+ this.value = this.default;
69
+ }
70
+ }
71
+
72
+ export default Input;
@@ -0,0 +1,82 @@
1
+ import { godown } from "@godown/element/decorators/godown.js";
2
+ import { styles } from "@godown/element/decorators/styles.js";
3
+ import { classList } from "@godown/element/directives/class-list.js";
4
+ import { htmlSlot } from "@godown/element/directives/html-slot.js";
5
+ import { css, html } from "lit";
6
+ import { property } from "lit/decorators.js";
7
+
8
+ import { GlobalStyle } from "../core/global-style.js";
9
+
10
+ const protoName = "layout";
11
+
12
+ /**
13
+ * {@linkcode NavLayout} renders slot and optional top header, bottom footer.
14
+ *
15
+ * @slot - The main content of the layout.
16
+ * @slot header - The header of the layout.
17
+ * @slot footer - The footer of the layout.
18
+ * @category layout
19
+ */
20
+ @godown(protoName)
21
+ @styles(
22
+ css`
23
+ :host {
24
+ min-height: 100%;
25
+ display: flex;
26
+ flex-direction: column;
27
+ }
28
+
29
+ .sticky {
30
+ position: sticky;
31
+ top: 0;
32
+ z-index: 1;
33
+ }
34
+
35
+ [part=main] {
36
+ position: relative;
37
+ flex: 1;
38
+ width: 100%;
39
+ }
40
+
41
+ header,
42
+ main,
43
+ footer {
44
+ width: 100%;
45
+ }
46
+ `,
47
+ )
48
+ class NavLayout extends GlobalStyle {
49
+ /**
50
+ * If true, remove the header slot.
51
+ */
52
+ @property({ type: Boolean })
53
+ noHeader = false;
54
+
55
+ /**
56
+ * If true, remove the footer slot.
57
+ */
58
+ @property({ type: Boolean })
59
+ noFooter = false;
60
+
61
+ /**
62
+ * If true, header will sticky.
63
+ */
64
+ @property({ type: Boolean })
65
+ sticky = false;
66
+
67
+ protected render() {
68
+ return html`${
69
+ !this.noHeader
70
+ ? html`<header part="header" class="${classList({ sticky: this.sticky })}">${htmlSlot("header")}</header>`
71
+ : ""
72
+ }
73
+ <main part="main">${htmlSlot()}</main>
74
+ ${
75
+ !this.noFooter
76
+ ? html`<footer part="footer">${htmlSlot("footer")}</footer>`
77
+ : ""
78
+ }`;
79
+ }
80
+ }
81
+
82
+ export default NavLayout;
@@ -0,0 +1,38 @@
1
+ import { godown } from "@godown/element/decorators/godown.js";
2
+ import { property } from "lit/decorators.js";
3
+
4
+ import SuperAnchor from "../core/super-anchor.js";
5
+ import Router from "./router.js";
6
+
7
+ const protoName = "link";
8
+
9
+ /**
10
+ * {@linkcode Link} is used for link jumping.
11
+ *
12
+ * Set `type` to `"push" `or `"replace"`,
13
+ * will invoke the history api and trigger the {@linkcode Router.updateAll}.
14
+ *
15
+ * @category navigation
16
+ */
17
+ @godown(protoName)
18
+ class Link extends SuperAnchor {
19
+ /**
20
+ * If "push", call `history.pushState`.
21
+ *
22
+ * If "replace", call `history.replaceState`.
23
+ *
24
+ * If "normal", behave like a normal anchor.
25
+ */
26
+ @property()
27
+ type: "push" | "replace" | "normal" = "normal";
28
+
29
+ protected _handleClick(e: MouseEvent) {
30
+ if (this.type === "push" || this.type === "replace") {
31
+ e.preventDefault();
32
+ (history[`${this.type}State`])(null, "", this.href);
33
+ Router.updateAll();
34
+ }
35
+ }
36
+ }
37
+
38
+ export default Link;
@@ -0,0 +1,95 @@
1
+ import { godown } from "@godown/element/decorators/godown.js";
2
+ import { styles } from "@godown/element/decorators/styles.js";
3
+ import { isNil } from "@godown/element/tools/lib.js";
4
+ import { css, html } from "lit";
5
+ import { property } from "lit/decorators.js";
6
+
7
+ import { cssGlobalVars, GlobalStyle } from "../core/global-style.js";
8
+
9
+ const protoName = "progress";
10
+
11
+ /**
12
+ * {@linkcode Progress} similar to `<progress>`.
13
+ *
14
+ * @category feedback
15
+ */
16
+ @godown(protoName)
17
+ @styles(css`
18
+ :host {
19
+ width: 100%;
20
+ height: 0.5em;
21
+ display: inline-block;
22
+ border-radius: 0.25em;
23
+ background: var(${cssGlobalVars.passive});
24
+ color: var(${cssGlobalVars.active});
25
+ }
26
+
27
+ [part=root] {
28
+ height: inherit;
29
+ z-index: 1;
30
+ position: relative;
31
+ border-radius: inherit;
32
+ }
33
+
34
+ [part=value] {
35
+ position: absolute;
36
+ z-index: 2;
37
+ top: 0;
38
+ left: 0;
39
+ height: 100%;
40
+ border-radius: inherit;
41
+ transition: all 0.3s;
42
+ animation: progress 1.8s ease-in-out infinite alternate;
43
+ background: currentColor;
44
+ }
45
+
46
+ @keyframes progress {
47
+ from {
48
+ left: 0;
49
+ }
50
+ to {
51
+ left: 80%;
52
+ }
53
+ }
54
+
55
+ .static [part=value] {
56
+ animation: none;
57
+ }
58
+ `)
59
+ class Progress extends GlobalStyle {
60
+ @property({ type: Number })
61
+ max = 1;
62
+
63
+ @property({ type: Number })
64
+ min = 0;
65
+
66
+ @property({ type: Number })
67
+ value: number;
68
+
69
+ protected render() {
70
+ let width = 20;
71
+ let className: string;
72
+ if (!isNil(this.value)) {
73
+ width = this.parsePercent(this.value);
74
+ className = "static";
75
+ }
76
+ return html`<div part="root" class="${className}">
77
+ <i part="value" style="width:${width}%;"></i>
78
+ </div>`;
79
+ }
80
+
81
+ /**
82
+ * Convert s to a percentage without a percent sign.
83
+ *
84
+ * @param s String or number to convert.
85
+ * @returns Percentage without a percent sign.
86
+ */
87
+ parsePercent(s: string | number = "0"): number {
88
+ if (String(s).includes("%")) {
89
+ return parseFloat(String(s));
90
+ }
91
+ return (parseFloat(String(s)) / (this.max - this.min)) * 100;
92
+ }
93
+ }
94
+
95
+ export default Progress;
@@ -0,0 +1,404 @@
1
+ import { godown } from "@godown/element/decorators/godown.js";
2
+ import { part } from "@godown/element/decorators/part.js";
3
+ import { styles } from "@godown/element/decorators/styles.js";
4
+ import { classList } from "@godown/element/directives/class-list.js";
5
+ import { joinProperties } from "@godown/element/tools/css.js";
6
+ import { isNil } from "@godown/element/tools/lib.js";
7
+ import { css, html } from "lit";
8
+ import { property, queryAll, state } from "lit/decorators.js";
9
+
10
+ import { cssGlobalVars, scopePrefix } from "../core/global-style.js";
11
+ import SuperInput from "../core/super-input.js";
12
+
13
+ const protoName = "range";
14
+ const cssScope = scopePrefix(protoName);
15
+
16
+ /**
17
+ * {@linkcode Range} is similar to `<input type="range">`.
18
+ *
19
+ * Value accepts number, or array.
20
+ *
21
+ * Number has 1 handle, the array has the number of its elements and the minimum is 2.
22
+ *
23
+ * @category input
24
+ */
25
+ @godown(protoName)
26
+ @styles(
27
+ css`
28
+ :host {
29
+ ${cssScope}-handle-active: var(${cssGlobalVars._colors.blue[7]});
30
+ ${cssScope}-track-width: .5em;
31
+ background: var(${cssGlobalVars.input}-background);
32
+ width: var(${cssGlobalVars.input}-width);
33
+ display: inline-block;
34
+ margin: 0.25em 0;
35
+ }
36
+
37
+ :host([vertical]) {
38
+ height: var(${cssGlobalVars.input}-width);
39
+ width: fit-content;
40
+ }
41
+
42
+ :host(:not([disabled])) .last-focus {
43
+ z-index: 1;
44
+ ${cssScope}-handle-scale:1.05;
45
+ background: var(${cssScope}-handle-active);
46
+ }
47
+
48
+ [part=root] {
49
+ min-height:inherit;
50
+ position: relative;
51
+ border-radius: inherit;
52
+ width: 100%;
53
+ --from: 0%;
54
+ --to: 50%;
55
+ height: var(${cssScope}-track-width);
56
+ }
57
+
58
+ [part=track] {
59
+ height: 100%;
60
+ min-height:inherit;
61
+ display: flex;
62
+ position: absolute;
63
+ pointer-events: none;
64
+ border-radius: inherit;
65
+ justify-content: space-between;
66
+ left: min(var(--from), var(--to));
67
+ background: var(${cssGlobalVars.active});
68
+ width: max(calc(var(--to) - var(--from)), calc(var(--from) - var(--to)));
69
+ }
70
+
71
+ [part=handle] {
72
+ width: 1em;
73
+ height: 1em;
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ user-select: none;
78
+ position: absolute;
79
+ border: 0.1em solid;
80
+ border-radius: 50%;
81
+ transform-origin: 0% 25%;
82
+ transform: scale(var(${cssScope}-handle-scale, 1)) translate(-50%, -25%);
83
+ background: var(${cssGlobalVars.active});
84
+ border-color: var(${cssGlobalVars.input}-control);
85
+ }
86
+ `,
87
+ css`
88
+ .vertical {
89
+ height: 100%;
90
+ width: var(${cssScope}-track-width);
91
+ }
92
+
93
+ .vertical i {
94
+ transform: translate(-25%, -50%);
95
+ }
96
+
97
+ .vertical [part=track] {
98
+ width: 100%;
99
+ height: max(calc(var(--to) - var(--from)), calc(var(--from) - var(--to)));
100
+ top: min(var(--from), var(--to));
101
+ left: 0;
102
+ }
103
+ `,
104
+ css`
105
+ [part=handle] {
106
+ left: var(--handle);
107
+ top: 0;
108
+ }
109
+
110
+ .vertical [part=handle] {
111
+ top: var(--handle);
112
+ left: 0;
113
+ }
114
+ `,
115
+ )
116
+ class Range extends SuperInput {
117
+ /**
118
+ * Minimum value.
119
+ */
120
+ @property({ type: Number })
121
+ min = 0;
122
+
123
+ /**
124
+ * Maximum value.
125
+ */
126
+ @property({ type: Number })
127
+ max = 100;
128
+
129
+ /**
130
+ * Sliding step length.
131
+ */
132
+ @property({ type: Number })
133
+ step: number;
134
+
135
+ /**
136
+ * Display vertically.
137
+ */
138
+ @property({ type: Boolean, reflect: true })
139
+ vertical: boolean;
140
+
141
+ /**
142
+ * Value, or each of values, will render a handle.
143
+ *
144
+ * Accepts number or array of numbers.
145
+ */
146
+ @property({ type: Array })
147
+ value: number | number[];
148
+
149
+ /**
150
+ * The default of `{@linkcode this.value}`.
151
+ */
152
+ @property({ type: Array })
153
+ default: typeof this.value;
154
+
155
+ @part("root")
156
+ protected _root: HTMLElement;
157
+
158
+ @queryAll("[part=handle]")
159
+ protected _handles: NodeListOf<HTMLElement>;
160
+
161
+ @state()
162
+ lastFocus?: number;
163
+
164
+ /**
165
+ * Returns true when the second number is greater than the first number.
166
+ */
167
+ get reverse() {
168
+ return this.range ? this.value[0] > this.value[1] : false;
169
+ }
170
+
171
+ /**
172
+ * If value is array.
173
+ */
174
+ get range(): boolean {
175
+ return Array.isArray(this.value);
176
+ }
177
+
178
+ /**
179
+ * Return values in the form of an array.
180
+ */
181
+ get rangeValue(): number[] {
182
+ return (this.range ? this.value : [this.value]) as number[];
183
+ }
184
+
185
+ /**
186
+ * @param len Minimum result length.
187
+ * @param value Fill value.
188
+ * @returns Array with length of len.
189
+ */
190
+ padValue(len: number, value = 0): number[] {
191
+ const { rangeValue } = this;
192
+ const miss = len - rangeValue.length;
193
+ if (miss > 0) {
194
+ return new Array(miss).fill(value).concat(rangeValue);
195
+ }
196
+ return rangeValue;
197
+ }
198
+
199
+ protected render() {
200
+ const rangeValue = this.padValue(2);
201
+ const from = Math.min(...rangeValue);
202
+ const to = Math.max(...rangeValue);
203
+ const gap = this.max - this.min;
204
+
205
+ return html`<div
206
+ part="root"
207
+ class="${
208
+ classList({
209
+ vertical: this.vertical,
210
+ range: this.range,
211
+ reverse: this.reverse,
212
+ })
213
+ }"
214
+ @mousedown="${this.disabled ? null : this._handleMousedownRoot}"
215
+ style="${
216
+ joinProperties({
217
+ "--from": `${((from - this.min) / gap) * 100}%`,
218
+ "--to": `${((to - this.min) / gap) * 100}%`,
219
+ ...(this.range
220
+ ? Object.fromEntries(
221
+ rangeValue.map((value, index) => [
222
+ `--handle-${index}`,
223
+ `${((value - this.min) / gap) * 100}%`,
224
+ ]),
225
+ )
226
+ : {}),
227
+ })
228
+ }"><div part="track"></div>
229
+ ${
230
+ this.range
231
+ ? (this.value as number[]).map((_, index) => this.renderHandle(index))
232
+ : this.renderHandle(0)
233
+ }
234
+ </div>`;
235
+ }
236
+
237
+ protected renderHandle(index: number) {
238
+ const { range } = this;
239
+ const end = !range || index === (this.value as number[]).length - 1;
240
+ return html`<i
241
+ tabindex="0"
242
+ part="handle"
243
+ class="${classList({ "last-focus": this.lastFocus === index })}"
244
+ @mousedown="${this.disabled ? null : this.createMouseDown(index)}"
245
+ @focus="${this.disabled ? null : () => this.focusHandle(index)}"
246
+ @blur="${this.disabled ? null : this.blurHandle}"
247
+ style="--handle:var(--${
248
+ /* In single-handle mod or end, it is max value */
249
+ (!range && end) ? `to` : `handle-${index}`})"
250
+ ></i>
251
+ `;
252
+ }
253
+
254
+ private _keydownEvent: EventListenerOrEventListenerObject;
255
+
256
+ focusHandle(index: number) {
257
+ this.lastFocus = index;
258
+ const handleItem = this._handles.item(index);
259
+ handleItem?.focus();
260
+ if (!this._keydownEvent) {
261
+ this._keydownEvent = this.events.add(document, "keydown", this.createKeydownEvent(index));
262
+ }
263
+ }
264
+
265
+ blurHandle() {
266
+ this.lastFocus = undefined;
267
+ this._keydownEvent = this.events.remove(document, "keydown", this._keydownEvent);
268
+ }
269
+
270
+ protected createKeydownEvent(index: number) {
271
+ if (!this.range) {
272
+ index = 0;
273
+ }
274
+ return (e: KeyboardEvent) => {
275
+ if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
276
+ e.preventDefault();
277
+ this.createSetValue(index)(old => old - this.step);
278
+ } else if (e.key === "ArrowRight" || e.key === "ArrowUp") {
279
+ e.preventDefault();
280
+ this.createSetValue(index)(old => old + this.step);
281
+ }
282
+ };
283
+ }
284
+
285
+ createMouseDown(index: number) {
286
+ return (e: MouseEvent) => {
287
+ this.focusHandle(index);
288
+ this.createMousedownListener(this.createSetValue(index))(e);
289
+ };
290
+ }
291
+
292
+ protected _handleMousedownEnd(e: MouseEvent) {
293
+ this.lastFocus = 0;
294
+ this.createMousedownListener(this.setEnd)(e);
295
+ this.focusHandle(0);
296
+ }
297
+
298
+ createSetValue(index: number) {
299
+ return (numberOrModifier: number | ((value: number) => number)) => {
300
+ const number = typeof numberOrModifier === "number"
301
+ ? this.normalizeValue(numberOrModifier)
302
+ : numberOrModifier(this.rangeValue[index]);
303
+ let newValue: any = number;
304
+ if (this.range) {
305
+ newValue = [...this.rangeValue];
306
+ newValue[index] = number;
307
+ }
308
+ this.value = newValue;
309
+ };
310
+ }
311
+
312
+ setEnd(value: number) {
313
+ this.createSetValue((this.value as any)?.length - 1 || 0)(value);
314
+ }
315
+
316
+ /**
317
+ * Compute value from event.
318
+ */
319
+ protected _computeValue(e: MouseEvent) {
320
+ const rect = this._root.getBoundingClientRect();
321
+ const div = this.vertical ? (e.clientY - rect.top) / rect.height : (e.clientX - rect.left) / rect.width;
322
+ const value = Math.round((div * (this.max - this.min)) / this.step) * this.step;
323
+ return this.normalizeValue(value);
324
+ }
325
+
326
+ /**
327
+ * Ensure that the values do not exceed the range of max and min.
328
+ */
329
+ protected normalizeValue(value: number) {
330
+ if (value > this.max) { value -= this.step; }
331
+ else if (value < this.min) { value += this.step; }
332
+ return value;
333
+ }
334
+
335
+ protected _handleMousedownRoot(e: MouseEvent) {
336
+ const value = this._computeValue(e);
337
+ const index = this.range
338
+ ? this.rangeValue.reduce((acc, item, index) => {
339
+ const diff = Math.abs(value - item);
340
+ const prevDiff = Math.abs(value - this.rangeValue[acc]);
341
+ return diff < prevDiff ? index : acc;
342
+ }, 0)
343
+ : 0;
344
+
345
+ const set = this.createSetValue(index);
346
+ set(value);
347
+ this.createMousedownListener(set)(e);
348
+ this.focusHandle(index);
349
+ }
350
+
351
+ protected createMousedownListener(mouseMoveCallback: (arg0: number) => void) {
352
+ return (e: MouseEvent) => {
353
+ e.preventDefault();
354
+ e.stopPropagation();
355
+ const move = this.createMousemoveListener(mouseMoveCallback);
356
+ this.events.add(document, "mousemove", move);
357
+ const stop = () => {
358
+ this.events.remove(document, "mousemove", move);
359
+ this.events.remove(document, "mouseup", stop);
360
+ };
361
+ this.events.add(document, "mouseup", stop);
362
+ };
363
+ }
364
+
365
+ protected createMousemoveListener(callback: (arg0: number) => void) {
366
+ return (e: MouseEvent) => {
367
+ const value = this._computeValue(e);
368
+ if (value > this.max || value < this.min) {
369
+ return;
370
+ }
371
+ callback?.call(this, value);
372
+ };
373
+ }
374
+
375
+ protected _connectedInit() {
376
+ const gap = this.max - this.min;
377
+ this.step ||= gap / 100;
378
+ if (isNil(this.value)) {
379
+ if (!isNil(this.default)) {
380
+ this.value = this.default;
381
+ } else {
382
+ this.value = Math.round(gap / 2 / this.step) * this.step;
383
+ }
384
+ }
385
+ this.default ??= this.value;
386
+ }
387
+
388
+ reset() {
389
+ this.value = this.default;
390
+ }
391
+
392
+ sort() {
393
+ return this.value = this.toSorted();
394
+ }
395
+
396
+ toSorted() {
397
+ if (this.range) {
398
+ return [...this.value as number[]].sort((a, b) => a - b);
399
+ }
400
+ return this.value;
401
+ }
402
+ }
403
+
404
+ export default Range;