@stanko/ctrls 0.4.3 → 0.4.5
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/README.md +4 -3
- package/dist/ctrls/ctrl-boolean.d.ts +1 -1
- package/dist/ctrls/ctrl-boolean.js +18 -19
- package/dist/ctrls/ctrl-dual-range.d.ts +1 -1
- package/dist/ctrls/ctrl-dual-range.js +33 -34
- package/dist/ctrls/ctrl-easing.d.ts +1 -1
- package/dist/ctrls/ctrl-easing.js +57 -65
- package/dist/ctrls/ctrl-file.js +35 -32
- package/dist/ctrls/ctrl-html.js +10 -10
- package/dist/ctrls/ctrl-radio.js +26 -25
- package/dist/ctrls/ctrl-range.js +20 -22
- package/dist/ctrls/ctrl-seed.js +20 -21
- package/dist/ctrls/index.d.ts +0 -1
- package/dist/ctrls/index.js +30 -42
- package/dist/ctrls.css +43 -24
- package/dist/ctrls.css.map +1 -1
- package/dist/utils/dom.d.ts +28 -0
- package/dist/utils/dom.js +61 -0
- package/dist/utils/get-drawer.d.ts +1 -0
- package/dist/utils/get-drawer.js +22 -0
- package/dist/utils/icons.d.ts +1 -1
- package/dist/utils/icons.js +1 -1
- package/package.json +3 -2
- package/dist/ctrls/dom.d.ts +0 -12
- package/dist/ctrls/dom.js +0 -16
package/README.md
CHANGED
|
@@ -313,7 +313,7 @@ Grid of radio buttons. Can be set to have between one and five columns.
|
|
|
313
313
|
```ts
|
|
314
314
|
{
|
|
315
315
|
// Mandatory
|
|
316
|
-
items: Record<string, string>; // Map of radio items (key, value)
|
|
316
|
+
items: Record<string, string>; // Map of radio items (key -> value, value -> label)
|
|
317
317
|
|
|
318
318
|
// Optional
|
|
319
319
|
columns?: number; // default: 3
|
|
@@ -481,11 +481,12 @@ Thank you for stopping by! If you end up using Ctrls, please let me know, I woul
|
|
|
481
481
|
## TODO
|
|
482
482
|
|
|
483
483
|
* [ ] Add `add/removeEventListener` instead of direct update of `onInput` and `onChange`
|
|
484
|
+
* [ ] Check if `onInput` is triggered when it should
|
|
484
485
|
* [ ] Allow users to pass a custom PRNG lib
|
|
485
486
|
* [ ] Hash storage - check if there is an instance using hash storage already
|
|
486
487
|
* [ ] Storage - local storage
|
|
487
|
-
* [
|
|
488
|
-
* [
|
|
488
|
+
* [*] Collapsing animation for the main element and groups
|
|
489
|
+
* [x] Use dom helpers everywhere
|
|
489
490
|
* [x] `toHtmlId(this.name)` => `toHtmlId(this.id)`
|
|
490
491
|
* [x] Add `name` and `id` to inputs
|
|
491
492
|
* [x] TypeDef bug - easing presets should be optional
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dom } from "../utils/dom";
|
|
1
2
|
import { checkIcon } from "../utils/icons";
|
|
2
3
|
import { toHtmlId } from "../utils/string-utils";
|
|
3
4
|
export class BooleanCtrl {
|
|
@@ -17,11 +18,11 @@ export class BooleanCtrl {
|
|
|
17
18
|
};
|
|
18
19
|
this.buildUI = () => {
|
|
19
20
|
const id = toHtmlId(this.id);
|
|
20
|
-
const input =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const input = dom.input("ctrls__boolean-input", {
|
|
22
|
+
type: "checkbox",
|
|
23
|
+
id,
|
|
24
|
+
name: id,
|
|
25
|
+
});
|
|
25
26
|
input.checked = this.value;
|
|
26
27
|
input.addEventListener("change", () => {
|
|
27
28
|
this.value = input.checked;
|
|
@@ -31,20 +32,18 @@ export class BooleanCtrl {
|
|
|
31
32
|
this.value = input.checked;
|
|
32
33
|
this.onInput(this);
|
|
33
34
|
});
|
|
34
|
-
const checkmark =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const right =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
label
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
element.appendChild(label);
|
|
47
|
-
element.appendChild(right);
|
|
35
|
+
const checkmark = dom.span("ctrls__boolean-checkmark", {
|
|
36
|
+
innerHTML: checkIcon,
|
|
37
|
+
});
|
|
38
|
+
const right = dom.div("ctrls__control-right", {
|
|
39
|
+
children: [input, checkmark],
|
|
40
|
+
});
|
|
41
|
+
const label = dom.span("ctrls__control-label", {
|
|
42
|
+
children: [this.label],
|
|
43
|
+
});
|
|
44
|
+
const element = dom.label("ctrls__control ctrls__control--boolean", {
|
|
45
|
+
children: [label, right],
|
|
46
|
+
});
|
|
48
47
|
return {
|
|
49
48
|
element,
|
|
50
49
|
input,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import DualRangeInput from "@stanko/dual-range-input";
|
|
2
|
-
import type { Ctrl, CtrlChangeHandler, CtrlItemType
|
|
2
|
+
import type { ConfigFor, Ctrl, CtrlChangeHandler, CtrlItemType } from "./types";
|
|
3
3
|
export type DualRangeControlOptions = {
|
|
4
4
|
min: number;
|
|
5
5
|
max: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import random from "../utils/random";
|
|
2
1
|
import DualRangeInput from "@stanko/dual-range-input";
|
|
2
|
+
import { dom } from "../utils/dom";
|
|
3
|
+
import random from "../utils/random";
|
|
3
4
|
import { roundToStep } from "../utils/round-to-step";
|
|
4
5
|
import { toHtmlId } from "../utils/string-utils";
|
|
5
6
|
export class DualRangeCtrl {
|
|
@@ -46,43 +47,41 @@ export class DualRangeCtrl {
|
|
|
46
47
|
this.update(this.value);
|
|
47
48
|
this.onInput(this);
|
|
48
49
|
};
|
|
49
|
-
const minInput =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
const minInput = dom.input("", {
|
|
51
|
+
type: "range",
|
|
52
|
+
name: `${id}-min`,
|
|
53
|
+
id: `${id}-min`,
|
|
54
|
+
min: min,
|
|
55
|
+
max: max,
|
|
56
|
+
step: step,
|
|
57
|
+
value: value.min,
|
|
58
|
+
});
|
|
57
59
|
minInput.addEventListener("input", inputHandler);
|
|
58
60
|
minInput.addEventListener("change", changeHandler);
|
|
59
|
-
const maxInput =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
const maxInput = dom.input("", {
|
|
62
|
+
type: "range",
|
|
63
|
+
name: `${id}-max`,
|
|
64
|
+
id: `${id}-max`,
|
|
65
|
+
min: min,
|
|
66
|
+
max: max,
|
|
67
|
+
step: step,
|
|
68
|
+
value: value.min,
|
|
69
|
+
});
|
|
67
70
|
maxInput.addEventListener("input", inputHandler);
|
|
68
71
|
maxInput.addEventListener("change", changeHandler);
|
|
69
|
-
const inputWrapper =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const label =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const element = document.createElement("div");
|
|
83
|
-
element.classList.add("ctrls__control", "ctrls__control--dual-range");
|
|
84
|
-
element.appendChild(label);
|
|
85
|
-
element.appendChild(right);
|
|
72
|
+
const inputWrapper = dom.div("dual-range-input", {
|
|
73
|
+
children: [minInput, maxInput],
|
|
74
|
+
});
|
|
75
|
+
const right = dom.div("ctrls__control-right", {
|
|
76
|
+
children: [inputWrapper],
|
|
77
|
+
});
|
|
78
|
+
const valueSpan = dom.span("ctrls__control-value");
|
|
79
|
+
const label = dom.span("ctrls__control-label", {
|
|
80
|
+
children: [this.label, valueSpan],
|
|
81
|
+
});
|
|
82
|
+
const element = dom.div("ctrls__control ctrls__control--dual-range", {
|
|
83
|
+
children: [label, right],
|
|
84
|
+
});
|
|
86
85
|
return {
|
|
87
86
|
element,
|
|
88
87
|
valueSpan,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Ctrl, CtrlChangeHandler, CtrlItemType
|
|
1
|
+
import type { ConfigFor, Ctrl, CtrlChangeHandler, CtrlItemType } from "./types";
|
|
2
2
|
export type Easing = [number, number, number, number];
|
|
3
3
|
export declare class EasingCtrl implements Ctrl<Easing> {
|
|
4
4
|
type: CtrlItemType;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import random from "../utils/random";
|
|
2
1
|
import BezierEasing from "bezier-easing";
|
|
2
|
+
import { dom } from "../utils/dom";
|
|
3
|
+
import random from "../utils/random";
|
|
3
4
|
import { toHtmlId } from "../utils/string-utils";
|
|
4
5
|
const easings = {
|
|
5
6
|
EASE: [0.25, 0.1, 0.25, 1],
|
|
@@ -53,36 +54,27 @@ export class EasingCtrl {
|
|
|
53
54
|
this.buildUI = () => {
|
|
54
55
|
const { value } = this;
|
|
55
56
|
const id = toHtmlId(this.id);
|
|
56
|
-
const line1 =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const line2 =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const path =
|
|
65
|
-
path
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
handle1.innerHTML = "";
|
|
78
|
-
const handle2 = document.createElement("button");
|
|
79
|
-
handle2.className = "ctrls__easing-handle ctrls__easing-handle--2";
|
|
80
|
-
handle2.innerHTML = "";
|
|
81
|
-
const control = document.createElement("div");
|
|
82
|
-
control.className = "ctrls__easing";
|
|
83
|
-
control.appendChild(svg);
|
|
84
|
-
control.appendChild(handle1);
|
|
85
|
-
control.appendChild(handle2);
|
|
57
|
+
const line1 = dom.line("ctrls__easing-line ctrls__easing-line--1", {
|
|
58
|
+
x1: 0,
|
|
59
|
+
y1: h,
|
|
60
|
+
});
|
|
61
|
+
const line2 = dom.line("ctrls__easing-line ctrls__easing-line--2", {
|
|
62
|
+
x1: w,
|
|
63
|
+
y1: 0,
|
|
64
|
+
});
|
|
65
|
+
const path = dom.path("ctrls__easing-path");
|
|
66
|
+
const borders = dom.path("easing-borders", {
|
|
67
|
+
d: `M 0 0 h ${w} M 0 ${h} h ${w}`,
|
|
68
|
+
});
|
|
69
|
+
const svg = dom.svg("", {
|
|
70
|
+
viewBox: `0 0 ${w} ${h}`,
|
|
71
|
+
children: [borders, path, line1, line2],
|
|
72
|
+
});
|
|
73
|
+
const handle1 = dom.button("ctrls__easing-handle ctrls__easing-handle--1");
|
|
74
|
+
const handle2 = dom.button("ctrls__easing-handle ctrls__easing-handle--2");
|
|
75
|
+
const control = dom.div("ctrls__easing", {
|
|
76
|
+
children: [svg, handle1, handle2],
|
|
77
|
+
});
|
|
86
78
|
const addListeners = (handle, index) => {
|
|
87
79
|
let dragging = false;
|
|
88
80
|
let dragStart = { x: 0, y: 0 };
|
|
@@ -185,51 +177,51 @@ export class EasingCtrl {
|
|
|
185
177
|
// Presets
|
|
186
178
|
let presetButtons = null;
|
|
187
179
|
if (Object.keys(this.presets).length > 0) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
180
|
+
const buttons = Object.keys(this.presets).map((key) => {
|
|
181
|
+
const button = dom.button("", {
|
|
182
|
+
// Remove EASE_ prefix and make it lowercase
|
|
183
|
+
// EASE_IN -> in
|
|
184
|
+
children: [key.toLowerCase().replace("ease_", "")],
|
|
185
|
+
});
|
|
193
186
|
button.addEventListener("click", () => {
|
|
194
187
|
this.value = this.presets[key];
|
|
195
188
|
this.onChange(this);
|
|
196
189
|
this.update();
|
|
197
190
|
});
|
|
198
|
-
|
|
199
|
-
}
|
|
191
|
+
return button;
|
|
192
|
+
});
|
|
193
|
+
presetButtons = dom.div("ctrls__easing-buttons", {
|
|
194
|
+
children: buttons,
|
|
195
|
+
});
|
|
200
196
|
}
|
|
201
|
-
const ticks = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
202
|
-
ticks.classList.add("ctrls__easing-ticks");
|
|
203
|
-
ticks.setAttribute("viewBox", `0 0 ${w} 5`);
|
|
204
|
-
ticks.setAttribute("preserveAspectRatio", "none");
|
|
205
197
|
const tickCount = 30;
|
|
206
198
|
const ticksElements = [];
|
|
207
199
|
for (let i = 0; i < tickCount; i++) {
|
|
208
|
-
const tick =
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
const tick = dom.line("", {
|
|
201
|
+
y1: 0,
|
|
202
|
+
y2: 5,
|
|
203
|
+
});
|
|
211
204
|
ticksElements.push(tick);
|
|
212
|
-
ticks.appendChild(tick);
|
|
213
205
|
}
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
label
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
element.
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
206
|
+
const ticks = dom.svg("ctrls__easing-ticks", {
|
|
207
|
+
viewBox: `0 0 ${w} 5`,
|
|
208
|
+
preserveAspectRatio: "none",
|
|
209
|
+
children: ticksElements,
|
|
210
|
+
});
|
|
211
|
+
const controlWrapper = dom.div("ctrls__easing-wrapper", {
|
|
212
|
+
id,
|
|
213
|
+
children: [ticks, control],
|
|
214
|
+
});
|
|
215
|
+
const right = dom.div("ctrls__control-right", {
|
|
216
|
+
children: [controlWrapper, presetButtons],
|
|
217
|
+
});
|
|
218
|
+
const label = dom.div("ctrls__control-label", {
|
|
219
|
+
children: [this.label],
|
|
220
|
+
});
|
|
221
|
+
const element = dom.div("ctrls__control ctrls__control--easing", {
|
|
222
|
+
"data-value": value.join(","),
|
|
223
|
+
children: [label, right],
|
|
224
|
+
});
|
|
233
225
|
return {
|
|
234
226
|
element,
|
|
235
227
|
ticks: ticksElements,
|
package/dist/ctrls/ctrl-file.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { dom } from "../utils/dom";
|
|
2
|
+
import { deleteIcon } from "../utils/icons";
|
|
1
3
|
import { toHtmlId } from "../utils/string-utils";
|
|
2
|
-
import { dom } from "./dom";
|
|
3
|
-
import { closeIcon } from "../utils/icons";
|
|
4
4
|
const IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp", "svg+xml"];
|
|
5
5
|
export class FileCtrl {
|
|
6
6
|
constructor(config, onChange, onInput) {
|
|
@@ -17,13 +17,18 @@ export class FileCtrl {
|
|
|
17
17
|
this.onChange(this);
|
|
18
18
|
this.onInput(this);
|
|
19
19
|
});
|
|
20
|
-
const fakeInput = dom.label("ctrls__file-fake-input ctrls__btn ctrls__btn--sm", {
|
|
21
|
-
|
|
20
|
+
const fakeInput = dom.label("ctrls__file-fake-input ctrls__btn ctrls__btn--sm", {
|
|
21
|
+
for: id,
|
|
22
|
+
children: ["select file"],
|
|
23
|
+
});
|
|
22
24
|
if (this.accept) {
|
|
23
|
-
|
|
25
|
+
const acceptSpan = dom.span("", { children: [this.accept] });
|
|
26
|
+
fakeInput.append(acceptSpan);
|
|
24
27
|
}
|
|
25
|
-
const clearButton = dom.button("ctrls__file-clear ctrls__btn"
|
|
26
|
-
|
|
28
|
+
const clearButton = dom.button("ctrls__file-clear ctrls__btn", {
|
|
29
|
+
innerHTML: deleteIcon,
|
|
30
|
+
"aria-label": "Clear file",
|
|
31
|
+
});
|
|
27
32
|
clearButton.addEventListener("click", () => {
|
|
28
33
|
if (input.files) {
|
|
29
34
|
this.update(null);
|
|
@@ -31,21 +36,20 @@ export class FileCtrl {
|
|
|
31
36
|
this.onInput(this);
|
|
32
37
|
}
|
|
33
38
|
});
|
|
34
|
-
const top = dom.div("ctrls__file-top"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
top.append(clearButton);
|
|
39
|
+
const top = dom.div("ctrls__file-top", {
|
|
40
|
+
children: [input, fakeInput, clearButton],
|
|
41
|
+
});
|
|
38
42
|
const preview = dom.div("ctrls__file-preview");
|
|
39
|
-
const right = dom.div("ctrls__control-right"
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
const right = dom.div("ctrls__control-right", {
|
|
44
|
+
children: [top, preview],
|
|
45
|
+
});
|
|
42
46
|
const label = dom.label("ctrls__control-label", {
|
|
43
47
|
for: id,
|
|
48
|
+
children: [this.label],
|
|
49
|
+
});
|
|
50
|
+
const element = dom.div("ctrls__control ctrls__control--file", {
|
|
51
|
+
children: [label, right],
|
|
44
52
|
});
|
|
45
|
-
label.textContent = this.label;
|
|
46
|
-
const element = dom.div("ctrls__control ctrls__control--file");
|
|
47
|
-
element.appendChild(label);
|
|
48
|
-
element.appendChild(right);
|
|
49
53
|
return {
|
|
50
54
|
element,
|
|
51
55
|
input,
|
|
@@ -55,20 +59,19 @@ export class FileCtrl {
|
|
|
55
59
|
this.update = (file) => {
|
|
56
60
|
this.value = file;
|
|
57
61
|
if (file) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
item.appendChild(label);
|
|
62
|
+
const isImage = IMAGE_EXTENSIONS.includes(file.type.split("/")[1]);
|
|
63
|
+
const img = isImage
|
|
64
|
+
? dom.img("ctrls__file-image", {
|
|
65
|
+
src: URL.createObjectURL(file),
|
|
66
|
+
alt: file.name,
|
|
67
|
+
})
|
|
68
|
+
: "";
|
|
69
|
+
const label = dom.figcaption("ctrls__file-label", {
|
|
70
|
+
children: [file.name],
|
|
71
|
+
});
|
|
72
|
+
const item = dom.figure("ctrls__file-preview-item", {
|
|
73
|
+
children: [img, label],
|
|
74
|
+
});
|
|
72
75
|
this.preview.replaceChildren(item);
|
|
73
76
|
}
|
|
74
77
|
else {
|
package/dist/ctrls/ctrl-html.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { dom } from "../utils/dom";
|
|
1
2
|
export const getHTMLControlElement = (config) => {
|
|
2
|
-
const right =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const label =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const element =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
element.appendChild(right);
|
|
3
|
+
const right = dom.div("ctrls__control-right", {
|
|
4
|
+
children: [config.html],
|
|
5
|
+
});
|
|
6
|
+
const label = dom.label("ctrls__control-label", {
|
|
7
|
+
children: [config.label || config.name],
|
|
8
|
+
});
|
|
9
|
+
const element = dom.div("ctrls__control ctrls__control--seed", {
|
|
10
|
+
children: [label, right],
|
|
11
|
+
});
|
|
12
12
|
return element;
|
|
13
13
|
};
|
package/dist/ctrls/ctrl-radio.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import random from "../utils/random";
|
|
2
2
|
import { toKebabCase } from "../utils/string-utils";
|
|
3
3
|
import { getRandomString } from "../utils/get-random-string";
|
|
4
|
+
import { dom } from "../utils/dom";
|
|
4
5
|
export class RadioCtrl {
|
|
5
6
|
constructor(config, onChange, onInput) {
|
|
6
7
|
this.type = "radio";
|
|
@@ -21,11 +22,12 @@ export class RadioCtrl {
|
|
|
21
22
|
this.buildUI = () => {
|
|
22
23
|
const { items, value } = this;
|
|
23
24
|
const inputs = items.map((item) => {
|
|
24
|
-
const input =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const input = dom.input("", {
|
|
26
|
+
type: "radio",
|
|
27
|
+
name: this.htmlId,
|
|
28
|
+
id: `${this.htmlId}-${toKebabCase(item.value)}`,
|
|
29
|
+
value: item.value,
|
|
30
|
+
});
|
|
29
31
|
input.checked = item.value === value;
|
|
30
32
|
input.addEventListener("change", () => {
|
|
31
33
|
this.value = this.parse(input.value);
|
|
@@ -35,25 +37,24 @@ export class RadioCtrl {
|
|
|
35
37
|
this.value = this.parse(input.value);
|
|
36
38
|
this.onInput(this);
|
|
37
39
|
});
|
|
38
|
-
const label =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
option.
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
const label = dom.span("", {
|
|
41
|
+
children: [item.label],
|
|
42
|
+
});
|
|
43
|
+
const option = dom.label("ctrls__radio-label", {
|
|
44
|
+
children: [input, label],
|
|
45
|
+
});
|
|
44
46
|
return option;
|
|
45
47
|
});
|
|
46
|
-
const right =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const label =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const element =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
element.appendChild(right);
|
|
48
|
+
const right = dom.div("ctrls__control-right", {
|
|
49
|
+
children: inputs,
|
|
50
|
+
style: `grid-template-columns: repeat(${this.columns}, 1fr);`,
|
|
51
|
+
});
|
|
52
|
+
const label = dom.span("ctrls__control-label", {
|
|
53
|
+
children: [this.label],
|
|
54
|
+
});
|
|
55
|
+
const element = dom.div("ctrls__control ctrls__control--radio", {
|
|
56
|
+
children: [label, right],
|
|
57
|
+
});
|
|
57
58
|
return element;
|
|
58
59
|
};
|
|
59
60
|
this.update = (value) => {
|
|
@@ -69,10 +70,10 @@ export class RadioCtrl {
|
|
|
69
70
|
next.checked = true;
|
|
70
71
|
};
|
|
71
72
|
this.items = [];
|
|
72
|
-
Object.
|
|
73
|
+
Object.entries(config.items).forEach(([label, value]) => {
|
|
73
74
|
this.items.push({
|
|
74
|
-
label
|
|
75
|
-
value
|
|
75
|
+
label,
|
|
76
|
+
value,
|
|
76
77
|
});
|
|
77
78
|
});
|
|
78
79
|
this.columns = config.columns || 3;
|
package/dist/ctrls/ctrl-range.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import random from "../utils/random";
|
|
2
2
|
import { roundToStep } from "../utils/round-to-step";
|
|
3
3
|
import { toHtmlId } from "../utils/string-utils";
|
|
4
|
+
import { dom } from "../utils/dom";
|
|
4
5
|
export class RangeCtrl {
|
|
5
6
|
constructor(config, onChange, onInput) {
|
|
6
7
|
this.type = "range";
|
|
@@ -21,15 +22,15 @@ export class RangeCtrl {
|
|
|
21
22
|
this.buildUI = () => {
|
|
22
23
|
const { min, max, step, value } = this;
|
|
23
24
|
const id = toHtmlId(this.id);
|
|
24
|
-
const input =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
const input = dom.input("ctrls__range-input", {
|
|
26
|
+
type: "range",
|
|
27
|
+
id,
|
|
28
|
+
name: id,
|
|
29
|
+
min,
|
|
30
|
+
max,
|
|
31
|
+
step,
|
|
32
|
+
value,
|
|
33
|
+
});
|
|
33
34
|
input.addEventListener("input", () => {
|
|
34
35
|
this.value = this.parse(input.value);
|
|
35
36
|
this.update(this.value);
|
|
@@ -45,19 +46,16 @@ export class RangeCtrl {
|
|
|
45
46
|
const percentage = ((value - min) / (max - min)) * 100;
|
|
46
47
|
this.element.style.setProperty("--gradient-position", `${percentage.toFixed(2)}%`);
|
|
47
48
|
});
|
|
48
|
-
const right =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
label
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
element.classList.add("ctrls__control", "ctrls__control--range");
|
|
59
|
-
element.appendChild(label);
|
|
60
|
-
element.appendChild(right);
|
|
49
|
+
const right = dom.div("ctrls__control-right", {
|
|
50
|
+
children: [input],
|
|
51
|
+
});
|
|
52
|
+
const valueSpan = dom.span("ctrls__control-value");
|
|
53
|
+
const label = dom.span("ctrls__control-label", {
|
|
54
|
+
children: [this.label, valueSpan],
|
|
55
|
+
});
|
|
56
|
+
const element = dom.label("ctrls__control ctrls__control--range", {
|
|
57
|
+
children: [label, right],
|
|
58
|
+
});
|
|
61
59
|
return {
|
|
62
60
|
element,
|
|
63
61
|
input,
|
package/dist/ctrls/ctrl-seed.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import generateSeed from "../utils/generate-seed";
|
|
2
2
|
import { refreshIcon } from "../utils/icons";
|
|
3
3
|
import { toHtmlId } from "../utils/string-utils";
|
|
4
|
+
import { dom } from "../utils/dom";
|
|
4
5
|
export class SeedCtrl {
|
|
5
6
|
constructor(config, onChange, onInput) {
|
|
6
7
|
this.type = "seed";
|
|
@@ -22,12 +23,12 @@ export class SeedCtrl {
|
|
|
22
23
|
this.buildUI = () => {
|
|
23
24
|
const { value } = this;
|
|
24
25
|
const id = toHtmlId(this.id);
|
|
25
|
-
const input =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const input = dom.input("ctrls__seed-input", {
|
|
27
|
+
type: "text",
|
|
28
|
+
value,
|
|
29
|
+
id,
|
|
30
|
+
name: id,
|
|
31
|
+
});
|
|
31
32
|
input.addEventListener("change", () => {
|
|
32
33
|
this.value = this.parse(input.value);
|
|
33
34
|
this.onChange(this);
|
|
@@ -36,26 +37,24 @@ export class SeedCtrl {
|
|
|
36
37
|
this.value = this.parse(input.value);
|
|
37
38
|
this.onInput(this);
|
|
38
39
|
});
|
|
39
|
-
const reload =
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const reload = dom.button("ctrls__seed-new-button ctrls__btn", {
|
|
41
|
+
innerHTML: refreshIcon,
|
|
42
|
+
});
|
|
42
43
|
reload.addEventListener("click", () => {
|
|
43
44
|
this.value = this.getRandomValue();
|
|
44
45
|
this.update();
|
|
45
46
|
this.onChange(this);
|
|
46
47
|
});
|
|
47
|
-
const right =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
element.appendChild(label);
|
|
58
|
-
element.appendChild(right);
|
|
48
|
+
const right = dom.div("ctrls__control-right", {
|
|
49
|
+
children: [input, reload],
|
|
50
|
+
});
|
|
51
|
+
const label = dom.label("ctrls__control-label", {
|
|
52
|
+
for: id,
|
|
53
|
+
children: [this.label],
|
|
54
|
+
});
|
|
55
|
+
const element = dom.div("ctrls__control ctrls__control--seed", {
|
|
56
|
+
children: [label, right],
|
|
57
|
+
});
|
|
59
58
|
return {
|
|
60
59
|
element,
|
|
61
60
|
input,
|
package/dist/ctrls/index.d.ts
CHANGED
|
@@ -10,7 +10,6 @@ export declare class Ctrls<Configs extends readonly ConfigItem[]> {
|
|
|
10
10
|
constructor(configs: Configs, options?: ControlsOptions);
|
|
11
11
|
processControls: (configs: Configs) => HTMLElement[];
|
|
12
12
|
registerControl: (config: TypedControlConfig, onChangeControlHandler: (control: CtrlComponent) => void, onInputControlHandler: (control: CtrlComponent) => void, group?: string) => CtrlComponent;
|
|
13
|
-
toggleVisibility: () => void;
|
|
14
13
|
addHashListeners: () => void;
|
|
15
14
|
getHash: () => string;
|
|
16
15
|
setHash: () => void;
|
package/dist/ctrls/index.js
CHANGED
|
@@ -11,6 +11,8 @@ import { FileCtrl } from "./ctrl-file";
|
|
|
11
11
|
import Alea from "../utils/alea";
|
|
12
12
|
import { chevronUpIcon, diceIcon } from "../utils/icons";
|
|
13
13
|
import { getHTMLControlElement } from "./ctrl-html";
|
|
14
|
+
import { dom } from "../utils/dom";
|
|
15
|
+
import { getDrawer } from "../utils/get-drawer";
|
|
14
16
|
const controlMap = {
|
|
15
17
|
boolean: BooleanCtrl,
|
|
16
18
|
range: RangeCtrl,
|
|
@@ -41,25 +43,18 @@ export class Ctrls {
|
|
|
41
43
|
// Processing configs and creating component instances and HTML elements
|
|
42
44
|
configs.map((config) => {
|
|
43
45
|
if (config.type === "group") {
|
|
44
|
-
//
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
if (config.isCollapsed) {
|
|
48
|
-
groupElement.classList.add("ctrls__group--hidden");
|
|
49
|
-
}
|
|
50
|
-
const groupTitle = document.createElement("button");
|
|
51
|
-
groupTitle.classList.add("ctrls__group-title");
|
|
52
|
-
groupTitle.innerHTML =
|
|
53
|
-
(config.label || toSpaceCase(config.name)) + chevronUpIcon;
|
|
54
|
-
groupTitle.addEventListener("click", () => {
|
|
55
|
-
groupTitle.parentElement?.classList.toggle("ctrls__group--hidden");
|
|
46
|
+
// Group title
|
|
47
|
+
const groupTitle = dom.button("ctrls__group-title", {
|
|
48
|
+
innerHTML: (config.label || toSpaceCase(config.name)) + chevronUpIcon,
|
|
56
49
|
});
|
|
57
|
-
|
|
58
|
-
groupElement.append(groupTitle);
|
|
59
|
-
config.controls.forEach((itemConfig) => {
|
|
50
|
+
const controlsElements = config.controls.map((itemConfig) => {
|
|
60
51
|
const control = this.registerControl(itemConfig, onChangeControlHandler, onInputControlHandler, toCamelCase(config.name));
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
return control.element;
|
|
53
|
+
});
|
|
54
|
+
const groupControls = getDrawer("ctrls__group-controls", controlsElements, groupTitle, config.isCollapsed);
|
|
55
|
+
// Create group element
|
|
56
|
+
const groupElement = dom.div("ctrls__group", {
|
|
57
|
+
children: [groupTitle, groupControls],
|
|
63
58
|
});
|
|
64
59
|
// Add the group element
|
|
65
60
|
elements.push(groupElement);
|
|
@@ -95,9 +90,6 @@ export class Ctrls {
|
|
|
95
90
|
this.controls.push(control);
|
|
96
91
|
return control;
|
|
97
92
|
};
|
|
98
|
-
this.toggleVisibility = () => {
|
|
99
|
-
this.element.classList.toggle("ctrls--hidden");
|
|
100
|
-
};
|
|
101
93
|
this.addHashListeners = () => {
|
|
102
94
|
window.addEventListener("hashchange", this.updateFromHash);
|
|
103
95
|
// Update all inputs using initial values from the hash
|
|
@@ -172,33 +164,29 @@ export class Ctrls {
|
|
|
172
164
|
theme: "system",
|
|
173
165
|
...options,
|
|
174
166
|
};
|
|
175
|
-
// Main element
|
|
176
|
-
this.element = document.createElement("div");
|
|
177
|
-
this.element.classList.add("ctrls");
|
|
178
|
-
this.element.classList.add(`ctrls--${this.options.theme}-theme`);
|
|
179
167
|
// Title
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this.element.appendChild(titleButton);
|
|
186
|
-
}
|
|
187
|
-
// Controls wrapper
|
|
188
|
-
const controlsContainer = document.createElement("div");
|
|
189
|
-
controlsContainer.classList.add("ctrls__controls");
|
|
190
|
-
this.element.appendChild(controlsContainer);
|
|
191
|
-
// Controls
|
|
192
|
-
const controlElements = this.processControls(configs);
|
|
193
|
-
controlsContainer.append(...controlElements);
|
|
168
|
+
let titleButton = this.options.title
|
|
169
|
+
? dom.button("ctrls__title", {
|
|
170
|
+
innerHTML: this.options.title + chevronUpIcon,
|
|
171
|
+
})
|
|
172
|
+
: null;
|
|
194
173
|
// Randomize button
|
|
174
|
+
let randomizeRow = null;
|
|
195
175
|
if (this.options.showRandomizeButton) {
|
|
196
|
-
const randomizeButton =
|
|
197
|
-
randomizeButton.classList.add("ctrls__randomize", "ctrls__btn", "ctrls__btn--lg");
|
|
198
|
-
randomizeButton.innerHTML = `Randomize ${diceIcon}`;
|
|
176
|
+
const randomizeButton = dom.button("ctrls__randomize ctrls__btn ctrls__btn--lg", { innerHTML: `Randomize ${diceIcon}` });
|
|
199
177
|
randomizeButton.addEventListener("click", this.randomize);
|
|
200
|
-
|
|
178
|
+
randomizeRow = dom.div("ctrls__control-no-label", {
|
|
179
|
+
children: [randomizeButton],
|
|
180
|
+
});
|
|
201
181
|
}
|
|
182
|
+
// Control elements
|
|
183
|
+
const controlElements = this.processControls(configs);
|
|
184
|
+
// Controls wrapper
|
|
185
|
+
const controlsContainer = getDrawer("ctrls__controls", [...controlElements, randomizeRow], titleButton);
|
|
186
|
+
// Main element
|
|
187
|
+
this.element = dom.div(`ctrls ctrls--${this.options.theme}-theme`, {
|
|
188
|
+
children: [titleButton, controlsContainer],
|
|
189
|
+
});
|
|
202
190
|
// Append the Ctrls element to the provided parent element
|
|
203
191
|
if (this.options.parent) {
|
|
204
192
|
this.options.parent.appendChild(this.element);
|
package/dist/ctrls.css
CHANGED
|
@@ -346,25 +346,43 @@
|
|
|
346
346
|
width: 1rem;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
-
.
|
|
350
|
-
|
|
349
|
+
.ctrls__controls-inner {
|
|
350
|
+
overflow: auto;
|
|
351
|
+
scrollbar-width: thin;
|
|
352
|
+
scrollbar-color: var(--ctrls-scrollbar-thumb-bg) transparent;
|
|
353
|
+
}
|
|
354
|
+
.ctrls__controls-inner > *:last-child:not(:first-child) {
|
|
355
|
+
margin-bottom: 0.25rem;
|
|
351
356
|
}
|
|
352
357
|
|
|
353
|
-
.
|
|
354
|
-
|
|
355
|
-
|
|
358
|
+
.ctrls__drawer {
|
|
359
|
+
display: none;
|
|
360
|
+
align-items: flex-start;
|
|
361
|
+
grid-template-rows: 0fr;
|
|
362
|
+
transition: grid-template-rows 500ms, opacity 500ms, display 500ms;
|
|
363
|
+
transition-behavior: allow-discrete;
|
|
364
|
+
overflow: hidden;
|
|
365
|
+
opacity: 0;
|
|
356
366
|
}
|
|
357
367
|
|
|
358
|
-
.
|
|
359
|
-
overflow: auto;
|
|
368
|
+
.ctrls__drawer--expanded {
|
|
360
369
|
display: grid;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
scrollbar-color: var(--ctrls-scrollbar-thumb-bg) transparent;
|
|
370
|
+
grid-template-rows: 1fr;
|
|
371
|
+
opacity: 1;
|
|
364
372
|
}
|
|
365
373
|
|
|
366
|
-
|
|
367
|
-
|
|
374
|
+
@starting-style {
|
|
375
|
+
.ctrls__drawer--ready.ctrls__drawer--expanded {
|
|
376
|
+
grid-template-rows: 0fr;
|
|
377
|
+
opacity: 0;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
.ctrls__drawer-inner {
|
|
381
|
+
overflow: hidden;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.ctrls__drawer-toggle--collapsed svg {
|
|
385
|
+
transform: rotate(180deg);
|
|
368
386
|
}
|
|
369
387
|
|
|
370
388
|
.ctrls__group {
|
|
@@ -373,19 +391,14 @@
|
|
|
373
391
|
border-radius: var(--ctrls-radius);
|
|
374
392
|
overflow: hidden;
|
|
375
393
|
}
|
|
394
|
+
.ctrls__group:only-child {
|
|
395
|
+
margin-block: 0.5rem;
|
|
396
|
+
}
|
|
376
397
|
|
|
377
398
|
.ctrls__group .ctrls__control {
|
|
378
399
|
grid-template-columns: calc(var(--ctrls-label-width) - 0.5rem) minmax(0, 1fr);
|
|
379
400
|
}
|
|
380
401
|
|
|
381
|
-
.ctrls__group--hidden {
|
|
382
|
-
padding-block-end: 0;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
.ctrls__group--hidden .ctrls__control {
|
|
386
|
-
display: none;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
402
|
.ctrls__control {
|
|
390
403
|
padding: 0.25rem 0.5rem;
|
|
391
404
|
display: grid;
|
|
@@ -398,6 +411,13 @@
|
|
|
398
411
|
.ctrls__control:hover .ctrls__control-label {
|
|
399
412
|
color: var(--ctrls-theme);
|
|
400
413
|
}
|
|
414
|
+
.ctrls__control:only-child {
|
|
415
|
+
padding-block: 0.5rem;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.ctrls__control-no-label {
|
|
419
|
+
padding: 0.25rem 0.5rem 0.25rem calc(var(--ctrls-label-width) + 0.5rem);
|
|
420
|
+
}
|
|
401
421
|
|
|
402
422
|
.ctrls__control-label {
|
|
403
423
|
color: var(--ctrls-text-muted);
|
|
@@ -446,8 +466,7 @@
|
|
|
446
466
|
}
|
|
447
467
|
|
|
448
468
|
.ctrls__btn--lg {
|
|
449
|
-
|
|
450
|
-
margin-inline-end: 0.5rem;
|
|
469
|
+
width: 100%;
|
|
451
470
|
padding: 0.5rem 1rem;
|
|
452
471
|
background: var(--ctrls-btn-bg);
|
|
453
472
|
border: 1px solid var(--ctrls-input-border);
|
|
@@ -460,7 +479,7 @@
|
|
|
460
479
|
}
|
|
461
480
|
|
|
462
481
|
.ctrls__randomize {
|
|
463
|
-
|
|
482
|
+
grid-column: 2;
|
|
464
483
|
}
|
|
465
484
|
.ctrls__randomize:focus-visible svg, .ctrls__randomize:hover svg {
|
|
466
485
|
transform: rotate(0.5turn);
|
|
@@ -776,7 +795,6 @@ label:hover .ctrls__boolean-input:not(:checked) + .ctrls__boolean-checkmark {
|
|
|
776
795
|
border: 1px solid var(--ctrls-input-border);
|
|
777
796
|
background: var(--ctrls-input-wrapper-bg);
|
|
778
797
|
border-radius: min(var(--ctrls-radius), 12px);
|
|
779
|
-
margin-bottom: 0.25rem;
|
|
780
798
|
}
|
|
781
799
|
|
|
782
800
|
.ctrls__easing {
|
|
@@ -820,6 +838,7 @@ label:hover .ctrls__boolean-input:not(:checked) + .ctrls__boolean-checkmark {
|
|
|
820
838
|
display: grid;
|
|
821
839
|
grid-template-columns: 1fr 1fr 1fr;
|
|
822
840
|
gap: 0.25rem;
|
|
841
|
+
margin-top: 0.25rem;
|
|
823
842
|
}
|
|
824
843
|
|
|
825
844
|
.ctrls__easing-buttons button {
|
package/dist/ctrls.css.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../node_modules/@stanko/dual-range-input/dist/index.css","../src/scss/_ctrls.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;;AC3IF;EACE;AAAA;AAAA;EAGA;EACA;EACA;EACA;EACA;EAGA;EACA;EAEA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EAGA;EAGA;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAGA;EAEA;EACA;EAEA;EACA;EAGA;EAGA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EAGA;EACA;EAEA;EAEA;EACA;EAEA;EAGA;EAEA;EACA;;;AAgDF;EACE;IA5CA;IAEA;IACA;IAGA;IACA;IACA;IACA;IACA;IACA;IAGA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IAGA;IAGA;IACA;IAEA;IAGA;IAGA;;;AASF;EAjDE;EAEA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EAGA;EAGA;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAGA;EACA;EAEA;EAGA;EAGA;;;AAeF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;EAGE;EACA;EACA;;AAGF;AAAA;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAKF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAGF;AAAA;AAAA;EAEE;EACA;;AAKF;AAAA;EACE;EACA;EACA;;AAGF;AAAA;EACE;EACA;;;
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../node_modules/@stanko/dual-range-input/dist/index.css","../src/scss/_ctrls.scss"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;;;;AC3IF;EACE;AAAA;AAAA;EAGA;EACA;EACA;EACA;EACA;EAGA;EACA;EAEA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EAGA;EAGA;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAGA;EAEA;EACA;EAEA;EACA;EAGA;EAGA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EAGA;EACA;EAEA;EAEA;EACA;EAEA;EAGA;EAEA;EACA;;;AAgDF;EACE;IA5CA;IAEA;IACA;IAGA;IACA;IACA;IACA;IACA;IACA;IAGA;IAGA;IACA;IACA;IACA;IAGA;IACA;IACA;IAGA;IAGA;IACA;IAEA;IAGA;IAGA;;;AASF;EAjDE;EAEA;EACA;EAGA;EACA;EACA;EACA;EACA;EACA;EAGA;EAGA;EACA;EACA;EACA;EAGA;EACA;EACA;EAGA;EAGA;EACA;EAEA;EAGA;EAGA;;;AAeF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;EAGE;EACA;EACA;;AAGF;AAAA;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAKF;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAGF;AAAA;AAAA;EAEE;EACA;;AAKF;AAAA;EACE;EACA;EACA;;AAGF;AAAA;EACE;EACA;;;AAMJ;EACE;EACA;EACA;;AAIA;EACE;;;AAMJ;EACE;EACA;EACA;EACA,YACE;EAGF;EACA;EAEA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;IACE;IACA;;;AAIJ;EACE;;;AAIA;EACE;;;AAMJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAKF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAIJ;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAIF;EAEE;;AAGF;EACE;EACA;EACA,YACE;;AAIJ;EACE;;;AAKJ;EACE;EACA;EACA;;AAEA;EAEE;EACA;EACA;;;AAKJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;;;AAIJ;EACE;;AAIE;EACE;;AAGF;AAAA;AAAA;EAEE;;;AAON;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAKJ;EACE;EACA;EACA;;;AAIF;EACE;;;AAIF;EACE;;;AAIF;EACE;EACA;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAmCJ;EA5BE;EACA;EACA;EACA;EACA;EAEA;;;AA0BF;EAhCE;EACA;EACA;EACA;EACA;EAEA;;;AA8BF;EAtBE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAkBA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAKF;EAvDE;EACA;EACA;EACA;EACA;EAEA;;;AAqDF;EA7CE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAwCA;EACA;;;AAGF;EACE;EACA;;;AAKF;EAIE;;AAEA;EACE;;AAPJ;EAUE;EACA;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EAEA;EACA;EACA;;AAEA;EACE;;;AAMJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;EAGF;EACA;EACA;;AAEA;EAEE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAKF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;;AAIE;EACE;;;AAON;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;AAKA;AAAA;AAAA;EAEE;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YACE;;AAIF;EAEE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EAEE;;AAEA;EACE;EACA","file":"ctrls.css"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type Attrs = {
|
|
2
|
+
[key: string]: unknown;
|
|
3
|
+
for?: string;
|
|
4
|
+
children?: (HTMLElement | SVGSVGElement | string | undefined | null)[];
|
|
5
|
+
innerHTML?: string;
|
|
6
|
+
};
|
|
7
|
+
type SVGAttrs = {
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
for?: string;
|
|
10
|
+
children?: (SVGElement | string)[];
|
|
11
|
+
innerHTML?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const dom: {
|
|
14
|
+
div: (className?: string, attrs?: Attrs) => HTMLDivElement;
|
|
15
|
+
span: (className?: string, attrs?: Attrs) => HTMLSpanElement;
|
|
16
|
+
input: (className?: string, attrs?: Attrs) => HTMLInputElement;
|
|
17
|
+
label: (className?: string, attrs?: Attrs) => HTMLLabelElement;
|
|
18
|
+
button: (className?: string, attrs?: Attrs) => HTMLButtonElement;
|
|
19
|
+
img: (className?: string, attrs?: Attrs) => HTMLImageElement;
|
|
20
|
+
figure: (className?: string, attrs?: Attrs) => HTMLElement;
|
|
21
|
+
figcaption: (className?: string, attrs?: Attrs) => HTMLElement;
|
|
22
|
+
svg: (className?: string, attrs?: SVGAttrs) => SVGSVGElement;
|
|
23
|
+
path: (className?: string, attrs?: SVGAttrs) => SVGPathElement;
|
|
24
|
+
line: (className?: string, attrs?: SVGAttrs) => SVGLineElement;
|
|
25
|
+
circle: (className?: string, attrs?: SVGAttrs) => SVGCircleElement;
|
|
26
|
+
rect: (className?: string, attrs?: SVGAttrs) => SVGRectElement;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// ----- DOM ----- //
|
|
2
|
+
const el = (tag, className = "", attrs = {}) => {
|
|
3
|
+
const element = document.createElement(tag);
|
|
4
|
+
element.className = className;
|
|
5
|
+
// Add children and innerHTML and remove them from attrs
|
|
6
|
+
if (attrs.children) {
|
|
7
|
+
attrs.children
|
|
8
|
+
// Remove falsy children
|
|
9
|
+
.filter(Boolean)
|
|
10
|
+
.forEach((child) => {
|
|
11
|
+
element.append(child);
|
|
12
|
+
});
|
|
13
|
+
delete attrs.children;
|
|
14
|
+
}
|
|
15
|
+
else if (attrs.innerHTML) {
|
|
16
|
+
element.innerHTML = attrs.innerHTML;
|
|
17
|
+
delete attrs.innerHTML;
|
|
18
|
+
}
|
|
19
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
20
|
+
element.setAttribute(key, String(value));
|
|
21
|
+
}
|
|
22
|
+
return element;
|
|
23
|
+
};
|
|
24
|
+
// ----- SVG ----- //
|
|
25
|
+
const svgEl = (tag, className = "", attrs = {}) => {
|
|
26
|
+
const element = document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
27
|
+
// className is deprecated for SVG elements
|
|
28
|
+
element.classList.add(...className.split(" ").filter(Boolean));
|
|
29
|
+
// Add children and innerHTML and remove them from attrs
|
|
30
|
+
if (attrs.children) {
|
|
31
|
+
attrs.children.forEach((child) => {
|
|
32
|
+
element.append(child);
|
|
33
|
+
});
|
|
34
|
+
delete attrs.children;
|
|
35
|
+
}
|
|
36
|
+
else if (attrs.innerHTML) {
|
|
37
|
+
element.innerHTML = attrs.innerHTML;
|
|
38
|
+
delete attrs.innerHTML;
|
|
39
|
+
}
|
|
40
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
41
|
+
element.setAttribute(key, String(value));
|
|
42
|
+
}
|
|
43
|
+
return element;
|
|
44
|
+
};
|
|
45
|
+
// ----- API ----- //
|
|
46
|
+
export const dom = {
|
|
47
|
+
div: (className = "", attrs = {}) => el("div", className, attrs),
|
|
48
|
+
span: (className = "", attrs = {}) => el("span", className, attrs),
|
|
49
|
+
input: (className = "", attrs = {}) => el("input", className, attrs),
|
|
50
|
+
label: (className = "", attrs = {}) => el("label", className, attrs),
|
|
51
|
+
button: (className = "", attrs = {}) => el("button", className, attrs),
|
|
52
|
+
img: (className = "", attrs = {}) => el("img", className, attrs),
|
|
53
|
+
figure: (className = "", attrs = {}) => el("figure", className, attrs),
|
|
54
|
+
figcaption: (className = "", attrs = {}) => el("figcaption", className, attrs),
|
|
55
|
+
// SVG elements
|
|
56
|
+
svg: (className = "", attrs = {}) => svgEl("svg", className, attrs),
|
|
57
|
+
path: (className = "", attrs = {}) => svgEl("path", className, attrs),
|
|
58
|
+
line: (className = "", attrs = {}) => svgEl("line", className, attrs),
|
|
59
|
+
circle: (className = "", attrs = {}) => svgEl("circle", className, attrs),
|
|
60
|
+
rect: (className = "", attrs = {}) => svgEl("rect", className, attrs),
|
|
61
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getDrawer: (className?: string, children?: (HTMLElement | null)[], toggleButton?: HTMLButtonElement | null, isCollapsed?: boolean) => HTMLDivElement;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { dom } from "./dom";
|
|
2
|
+
export const getDrawer = (className = "", children = [], toggleButton, isCollapsed = false) => {
|
|
3
|
+
const inner = dom.div(`ctrls__drawer-inner ${className}-inner`, {
|
|
4
|
+
children,
|
|
5
|
+
});
|
|
6
|
+
const outer = dom.div(`ctrls__drawer ${className}`, {
|
|
7
|
+
children: [inner],
|
|
8
|
+
});
|
|
9
|
+
if (isCollapsed) {
|
|
10
|
+
outer.classList.add("ctrls__drawer--collapsed");
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
outer.classList.add("ctrls__drawer--expanded");
|
|
14
|
+
}
|
|
15
|
+
toggleButton?.addEventListener("click", () => {
|
|
16
|
+
outer.classList.add("ctrls__drawer--ready");
|
|
17
|
+
outer.classList.toggle("ctrls__drawer--collapsed");
|
|
18
|
+
outer.classList.toggle("ctrls__drawer--expanded");
|
|
19
|
+
toggleButton?.classList.toggle("ctrls__drawer-toggle--collapsed");
|
|
20
|
+
});
|
|
21
|
+
return outer;
|
|
22
|
+
};
|
package/dist/utils/icons.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const checkIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"/></svg>";
|
|
2
2
|
export declare const refreshIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\"/><path d=\"M21 3v5h-5\"/><path d=\"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\"/><path d=\"M8 16H3v5\"/></svg>";
|
|
3
3
|
export declare const diceIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\" stroke-width=\"2\"/><path d=\"M16 8h.01\"/><path d=\"M8 8h.01\"/><path d=\"M8 16h.01\"/><path d=\"M16 16h.01\"/><path d=\"M12 12h.01\"/></svg>";
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const deleteIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6\"/><path d=\"M3 6h18\"/><path d=\"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>";
|
|
5
5
|
export declare const chevronUpIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m18 15-6-6-6 6\"/></svg>";
|
package/dist/utils/icons.js
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
export const checkIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>`;
|
|
3
3
|
export const refreshIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg>`;
|
|
4
4
|
export const diceIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="18" x="3" y="3" rx="2" ry="2" stroke-width="2"/><path d="M16 8h.01"/><path d="M8 8h.01"/><path d="M8 16h.01"/><path d="M16 16h.01"/><path d="M12 12h.01"/></svg>`;
|
|
5
|
-
export const
|
|
5
|
+
export const deleteIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>`;
|
|
6
6
|
export const chevronUpIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stanko/ctrls",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "vitest",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"build-lib": "rm -rf ./dist && tsc -p ./tsconfig-lib.json && npm run build-css",
|
|
11
11
|
"parse-markdown": "node ./parse-markdown.js",
|
|
12
12
|
"preview": "vite preview",
|
|
13
|
-
"prepare": "cp ./pre-commit ./.git/hooks/pre-commit && chmod +x ./.git/hooks/pre-commit"
|
|
13
|
+
"prepare": "cp ./pre-commit ./.git/hooks/pre-commit && chmod +x ./.git/hooks/pre-commit",
|
|
14
|
+
"prepublish": "npm run build-lib"
|
|
14
15
|
},
|
|
15
16
|
"types": "./dist/ctrls/index.d.ts",
|
|
16
17
|
"main": "./dist/ctrls/index.js",
|
package/dist/ctrls/dom.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
type Attrs = Record<string, string | number> & {
|
|
2
|
-
for?: string;
|
|
3
|
-
};
|
|
4
|
-
export declare const dom: {
|
|
5
|
-
el: <T extends keyof HTMLElementTagNameMap>(tag: T, className?: string, attrs?: Attrs) => HTMLElementTagNameMap[T];
|
|
6
|
-
div: (className?: string, attrs?: Attrs) => HTMLDivElement;
|
|
7
|
-
span: (className?: string, attrs?: Attrs) => HTMLSpanElement;
|
|
8
|
-
input: (className?: string, attrs?: Attrs) => HTMLInputElement;
|
|
9
|
-
label: (className?: string, attrs?: Attrs) => HTMLLabelElement;
|
|
10
|
-
button: (className?: string, attrs?: Attrs) => HTMLButtonElement;
|
|
11
|
-
};
|
|
12
|
-
export {};
|
package/dist/ctrls/dom.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const el = (tag, className = "", attrs = {}) => {
|
|
2
|
-
const element = document.createElement(tag);
|
|
3
|
-
element.className = className;
|
|
4
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
5
|
-
element.setAttribute(key, value.toString());
|
|
6
|
-
}
|
|
7
|
-
return element;
|
|
8
|
-
};
|
|
9
|
-
export const dom = {
|
|
10
|
-
el,
|
|
11
|
-
div: (className = "", attrs = {}) => el("div", className, attrs),
|
|
12
|
-
span: (className = "", attrs = {}) => el("span", className, attrs),
|
|
13
|
-
input: (className = "", attrs = {}) => el("input", className, attrs),
|
|
14
|
-
label: (className = "", attrs = {}) => el("label", className, attrs),
|
|
15
|
-
button: (className = "", attrs = {}) => el("button", className, attrs),
|
|
16
|
-
};
|