@lvl99dotcom/paintcanvas 0.4.0 → 0.6.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.
- package/README.md +30 -15
- package/dist/lib/brushes/configRanges/index.d.ts +17 -0
- package/dist/lib/brushes/configRanges/index.js +31 -1
- package/dist/lib/brushes/params/index.d.ts +2 -1
- package/dist/lib/brushes/params/index.js +7 -4
- package/dist/lib/brushes/presets/round/index.d.ts +1 -1
- package/dist/lib/brushes/presets/round/index.js +12 -7
- package/dist/lib/brushes/presets/square/index.d.ts +1 -1
- package/dist/lib/brushes/presets/square/index.js +7 -3
- package/dist/lib/brushes/shapeImage/index.d.ts +7 -3
- package/dist/lib/brushes/shapeImage/index.js +15 -9
- package/dist/lib/brushes/shapes/index.d.ts +18 -0
- package/dist/lib/brushes/shapes/index.js +86 -0
- package/dist/lib/brushes/types/index.d.ts +8 -0
- package/dist/lib/classes/BrushSettings/index.d.ts +29 -2
- package/dist/lib/classes/BrushSettings/index.js +51 -14
- package/dist/lib/classes/KeyboardShortcuts/index.d.ts +31 -2
- package/dist/lib/classes/KeyboardShortcuts/index.js +66 -4
- package/dist/lib/classes/Layer/index.d.ts +10 -0
- package/dist/lib/classes/Layer/index.js +15 -1
- package/dist/lib/classes/LayerAutosave/index.d.ts +9 -15
- package/dist/lib/classes/LayerAutosave/index.js +30 -43
- package/dist/lib/classes/LayerStack/index.d.ts +15 -0
- package/dist/lib/classes/LayerStack/index.js +26 -2
- package/dist/lib/classes/PaintCanvas/index.d.ts +72 -3
- package/dist/lib/classes/PaintCanvas/index.js +106 -12
- package/dist/lib/classes/PngEncoder/index.d.ts +41 -0
- package/dist/lib/classes/PngEncoder/index.js +104 -0
- package/dist/lib/classes/ProfileGraphs/index.d.ts +87 -0
- package/dist/lib/classes/ProfileGraphs/index.js +148 -0
- package/dist/lib/classes/SettingsAutosave/index.d.ts +3 -2
- package/dist/lib/classes/SettingsAutosave/index.js +6 -3
- package/dist/lib/classes/UiSettings/index.d.ts +68 -0
- package/dist/lib/classes/UiSettings/index.js +82 -0
- package/dist/lib/messages/schema.d.ts +720 -0
- package/dist/lib/presets/schema.d.ts +360 -0
- package/dist/lib/presets/schema.js +8 -1
- package/dist/lib/profiles/index.d.ts +61 -0
- package/dist/lib/profiles/index.js +131 -0
- package/dist/lib/profiles/schema.d.ts +73 -0
- package/dist/lib/profiles/schema.js +53 -0
- package/dist/lib/rendering/sample/index.d.ts +11 -0
- package/dist/lib/rendering/sample/index.js +36 -5
- package/dist/lib/settings/index.d.ts +2 -1
- package/dist/lib/settings/index.js +7 -2
- package/dist/lib/settings/schema.d.ts +67 -0
- package/dist/lib/settings/schema.js +20 -0
- package/dist/lib/validation/validators.generated.js +13191 -3655
- package/dist/locales/en-GB.js +39 -2
- package/dist/locales/en-US.js +39 -2
- package/dist/locales/fr.js +39 -2
- package/dist/locales/ja.js +39 -2
- package/dist/locales/ko.js +39 -2
- package/dist/locales/zh-Hans.js +39 -2
- package/dist/locales/zh-Hant.js +39 -2
- package/dist/package.js +1 -1
- package/dist/testing/recordingCanvas.js +2 -1
- package/dist/ui/ask/index.d.ts +48 -0
- package/dist/ui/ask/index.js +67 -0
- package/dist/ui/base/index.d.ts +10 -3
- package/dist/ui/base/index.js +19 -4
- package/dist/ui/dismiss/index.d.ts +21 -0
- package/dist/ui/dismiss/index.js +27 -0
- package/dist/ui/drag/index.d.ts +51 -0
- package/dist/ui/drag/index.js +81 -0
- package/dist/ui/elements/PaintCanvas/index.d.ts +17 -12
- package/dist/ui/elements/PaintCanvas/index.js +36 -17
- package/dist/ui/elements/PaintCanvas/style.js +1 -1
- package/dist/ui/elements/PcAppSettings/index.d.ts +6 -6
- package/dist/ui/elements/PcAppSettings/index.js +21 -65
- package/dist/ui/elements/PcBrushConfig/index.d.ts +34 -16
- package/dist/ui/elements/PcBrushConfig/index.js +263 -153
- package/dist/ui/elements/PcBrushConfig/style.js +1 -1
- package/dist/ui/elements/PcBrushSize/index.d.ts +53 -0
- package/dist/ui/elements/PcBrushSize/index.js +66 -0
- package/dist/ui/elements/PcBrushTest/index.d.ts +26 -0
- package/dist/ui/elements/PcBrushTest/index.js +79 -6
- package/dist/ui/elements/PcBrushTest/style.js +1 -1
- package/dist/ui/elements/PcButton/index.d.ts +12 -3
- package/dist/ui/elements/PcButton/index.js +18 -10
- package/dist/ui/elements/PcCanvas/index.d.ts +27 -2
- package/dist/ui/elements/PcCanvas/index.js +63 -13
- package/dist/ui/elements/PcCanvas/style.js +1 -1
- package/dist/ui/elements/PcCanvasMap/style.js +1 -1
- package/dist/ui/elements/PcClipboardTools/index.d.ts +49 -0
- package/dist/ui/elements/PcClipboardTools/index.js +125 -0
- package/dist/ui/elements/PcContextMenu/index.d.ts +2 -2
- package/dist/ui/elements/PcDialog/index.d.ts +46 -10
- package/dist/ui/elements/PcDialog/index.js +102 -51
- package/dist/ui/elements/PcDialogWindow/index.d.ts +141 -0
- package/dist/ui/elements/PcDialogWindow/index.js +385 -0
- package/dist/ui/elements/PcInputSettings/index.d.ts +13 -0
- package/dist/ui/elements/PcInputSettings/index.js +16 -1
- package/dist/ui/elements/PcMenu/index.d.ts +48 -3
- package/dist/ui/elements/PcMenu/index.js +111 -19
- package/dist/ui/elements/PcNumberSlider/index.d.ts +137 -0
- package/dist/ui/elements/PcNumberSlider/index.js +247 -0
- package/dist/ui/elements/PcPane/index.d.ts +3 -1
- package/dist/ui/elements/PcPane/index.js +44 -7
- package/dist/ui/elements/PcPanel/index.d.ts +2 -2
- package/dist/ui/elements/PcPanel/index.js +8 -8
- package/dist/ui/elements/PcPanelBrushes/index.d.ts +5 -17
- package/dist/ui/elements/PcPanelBrushes/index.js +13 -48
- package/dist/ui/elements/PcPanelBrushes/style.js +1 -1
- package/dist/ui/elements/PcPanelColours/index.js +2 -2
- package/dist/ui/elements/PcPanelColours/style.js +1 -1
- package/dist/ui/elements/PcPanelLayers/index.js +1 -1
- package/dist/ui/elements/PcPanelLayers/style.js +1 -1
- package/dist/ui/elements/PcPopover/index.d.ts +39 -1
- package/dist/ui/elements/PcPopover/index.js +72 -4
- package/dist/ui/elements/PcProfileEditor/index.d.ts +103 -0
- package/dist/ui/elements/PcProfileEditor/index.js +259 -0
- package/dist/ui/elements/PcProfileGraph/index.d.ts +84 -0
- package/dist/ui/elements/PcProfileGraph/index.js +317 -0
- package/dist/ui/elements/PcShortcutSettings/index.js +9 -13
- package/dist/ui/elements/PcSliderRange/index.d.ts +147 -0
- package/dist/ui/elements/PcSliderRange/index.js +307 -0
- package/dist/ui/elements/PcStats/index.d.ts +19 -4
- package/dist/ui/elements/PcStats/index.js +29 -13
- package/dist/ui/elements/PcThemePicker/index.d.ts +17 -15
- package/dist/ui/elements/PcThemePicker/index.js +22 -21
- package/dist/ui/elements/PcToolSettings/index.d.ts +48 -9
- package/dist/ui/elements/PcToolSettings/index.js +382 -318
- package/dist/ui/elements/PcToolSettings/style.js +1 -1
- package/dist/ui/elements/PcToolbar/index.d.ts +15 -0
- package/dist/ui/elements/PcToolbar/index.js +55 -14
- package/dist/ui/elements/PcToolbar/style.js +1 -1
- package/dist/ui/icons/images/icon-brush@2x.js +3 -0
- package/dist/ui/icons/images/icon-circle-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-clipboard@2x.js +3 -0
- package/dist/ui/icons/images/icon-cog@2x.js +3 -0
- package/dist/ui/icons/images/icon-cursor@2x.js +3 -0
- package/dist/ui/icons/images/icon-diagonal-tlbr-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-diagonal-trbl-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-eraser@2x.js +3 -0
- package/dist/ui/icons/images/icon-eyedropper@2x.js +3 -0
- package/dist/ui/icons/images/icon-flip-horizontal@2x.js +3 -0
- package/dist/ui/icons/images/icon-flip-vertical@2x.js +3 -0
- package/dist/ui/icons/images/icon-focus-pen@2x.js +3 -0
- package/dist/ui/icons/images/icon-freehand-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-hidden@2x.js +3 -0
- package/dist/ui/icons/images/icon-horizontal-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-layers@2x.js +3 -0
- package/dist/ui/icons/images/icon-linked@2x.js +3 -0
- package/dist/ui/icons/images/icon-locked@2x.js +3 -0
- package/dist/ui/icons/images/icon-moon@2x.js +3 -0
- package/dist/ui/icons/images/icon-pan@2x.js +3 -0
- package/dist/ui/icons/images/icon-polygon-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-pressure@2x.js +3 -0
- package/dist/ui/icons/images/icon-profile-graph@2x.js +3 -0
- package/dist/ui/icons/images/icon-randomise@2x.js +3 -0
- package/dist/ui/icons/images/icon-rectangle-mask@2x.js +3 -0
- package/dist/ui/icons/images/icon-redo@2x.js +3 -0
- package/dist/ui/icons/images/icon-rotate-90-left@2x.js +3 -0
- package/dist/ui/icons/images/icon-rotate-90-right@2x.js +3 -0
- package/dist/ui/icons/images/icon-rotate@2x.js +3 -0
- package/dist/ui/icons/images/icon-smoothing-bezier-cubic@2x.js +3 -0
- package/dist/ui/icons/images/icon-smoothing-bezier-quad@2x.js +3 -0
- package/dist/ui/icons/images/icon-smoothing-linear@2x.js +3 -0
- package/dist/ui/icons/images/icon-star@2x.js +3 -0
- package/dist/ui/icons/images/icon-sun@2x.js +3 -0
- package/dist/ui/icons/images/icon-tilt@2x.js +3 -0
- package/dist/ui/icons/images/icon-undo@2x.js +3 -0
- package/dist/ui/icons/images/icon-unlinked@2x.js +3 -0
- package/dist/ui/icons/images/icon-unlocked@2x.js +3 -0
- package/dist/ui/icons/images/icon-vertical-size@2x.js +3 -0
- package/dist/ui/icons/images/icon-visible@2x.js +3 -0
- package/dist/ui/icons/images/icon-zoom-in@2x.js +3 -0
- package/dist/ui/icons/images/icon-zoom-out@2x.js +3 -0
- package/dist/ui/icons/images/icon-zoom@2x.js +3 -0
- package/dist/ui/icons/index.d.ts +1 -1
- package/dist/ui/icons/index.js +86 -72
- package/dist/ui/index.d.ts +13 -3
- package/dist/ui/index.js +15 -4
- package/dist/ui/layout/index.d.ts +9 -1
- package/dist/ui/layout/index.js +11 -2
- package/dist/ui/styles/index.d.ts +21 -1
- package/dist/ui/styles/index.js +73 -14
- package/dist/ui/tokens/index.d.ts +5 -4
- package/dist/ui/tokens/index.js +12 -7
- package/locales/en-GB.json +39 -2
- package/locales/en-US.json +39 -2
- package/locales/fr.json +39 -2
- package/locales/ja.json +39 -2
- package/locales/ko.json +39 -2
- package/locales/zh-Hans.json +39 -2
- package/locales/zh-Hant.json +39 -2
- package/package.json +27 -18
- package/dist/ui/icons/images/brush.js +0 -3
- package/dist/ui/icons/images/circle-mask.js +0 -3
- package/dist/ui/icons/images/clipboard.js +0 -3
- package/dist/ui/icons/images/cursor.js +0 -3
- package/dist/ui/icons/images/eraser.js +0 -3
- package/dist/ui/icons/images/eyedropper.js +0 -3
- package/dist/ui/icons/images/flip-horizontal.js +0 -3
- package/dist/ui/icons/images/flip-vertical.js +0 -3
- package/dist/ui/icons/images/focus-pen.js +0 -3
- package/dist/ui/icons/images/freehand-mask.js +0 -3
- package/dist/ui/icons/images/hidden.js +0 -3
- package/dist/ui/icons/images/layers.js +0 -3
- package/dist/ui/icons/images/linked.js +0 -3
- package/dist/ui/icons/images/locked.js +0 -3
- package/dist/ui/icons/images/moon.js +0 -3
- package/dist/ui/icons/images/pan.js +0 -3
- package/dist/ui/icons/images/polygon-mask.js +0 -3
- package/dist/ui/icons/images/pressure.js +0 -3
- package/dist/ui/icons/images/randomise.js +0 -3
- package/dist/ui/icons/images/rectangle-mask.js +0 -3
- package/dist/ui/icons/images/redo.js +0 -3
- package/dist/ui/icons/images/rotate-90-left.js +0 -3
- package/dist/ui/icons/images/rotate-90-right.js +0 -3
- package/dist/ui/icons/images/smoothing-bezier-cubic.js +0 -3
- package/dist/ui/icons/images/smoothing-bezier-quad.js +0 -3
- package/dist/ui/icons/images/smoothing-linear.js +0 -3
- package/dist/ui/icons/images/star.js +0 -3
- package/dist/ui/icons/images/sun.js +0 -3
- package/dist/ui/icons/images/tilt.js +0 -3
- package/dist/ui/icons/images/undo.js +0 -3
- package/dist/ui/icons/images/unlinked.js +0 -3
- package/dist/ui/icons/images/unlocked.js +0 -3
- package/dist/ui/icons/images/visible.js +0 -3
- package/dist/ui/icons/images/zoom-in.js +0 -3
- package/dist/ui/icons/images/zoom-out.js +0 -3
- package/dist/ui/icons/images/zoom.js +0 -3
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
2
|
+
import { fitNumber } from "../PcNumberSlider/index.js";
|
|
3
|
+
import { css, html, nothing } from "lit";
|
|
4
|
+
import { live } from "lit/directives/live.js";
|
|
5
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
6
|
+
// src/ui/elements/PcSliderRange/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* Where a value sits between `min` and `max`, from 0 to 1 (0 when they're the same).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* rangeFraction(25, 0, 100); // 0.25
|
|
12
|
+
*/
|
|
13
|
+
var rangeFraction = (value, min, max) => max > min ? Math.min(1, Math.max(0, (value - min) / (max - min))) : 0;
|
|
14
|
+
/**
|
|
15
|
+
* A slider for a range: one track with two handles, the left for the lowest value (`low`) and the right for the highest
|
|
16
|
+
* (`high`), and a `<pc-number-slider>` for each on either side (dragged, or tapped to type). The two can't cross: the
|
|
17
|
+
* lowest is never above the highest. Values are kept within `min` and `max` and rounded to `step`.
|
|
18
|
+
*
|
|
19
|
+
* Pressing the track moves the nearest handle there and drags it. With keyboard focus on a handle, the arrow keys move
|
|
20
|
+
* it by `step`, Page Up and Page Down by `pageStep`, and Home and End as far as it can go. Touch, mouse and pen all work.
|
|
21
|
+
*
|
|
22
|
+
* With `single`, it's a slider for one value (`value`, from `min`): one handle, and one number slider before the track,
|
|
23
|
+
* or after it with `number-position="end"`. Use it for single values too, so they look and work the same as ranges.
|
|
24
|
+
*
|
|
25
|
+
* Fires `pc-input` (detail: `{ low, high }`) while a handle is dragged, and `pc-change` once it's let go, or when a value
|
|
26
|
+
* is changed with the keyboard or a number slider, after changing `low` and `high` themselves (and `value`, the same as
|
|
27
|
+
* `high`).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* html`<pc-slider-range label="Width" min="1" max="256" .low=${10} .high=${40}
|
|
31
|
+
* @pc-change=${(e) => setWidth(e.detail.low, e.detail.high)}></pc-slider-range>`
|
|
32
|
+
*/
|
|
33
|
+
var PcSliderRange = class extends PcElement {
|
|
34
|
+
static properties = {
|
|
35
|
+
...PcElement.properties,
|
|
36
|
+
low: { type: Number },
|
|
37
|
+
high: { type: Number },
|
|
38
|
+
min: { type: Number },
|
|
39
|
+
max: { type: Number },
|
|
40
|
+
step: { type: Number },
|
|
41
|
+
pageStep: {
|
|
42
|
+
type: Number,
|
|
43
|
+
attribute: "page-step"
|
|
44
|
+
},
|
|
45
|
+
unit: { type: String },
|
|
46
|
+
label: { type: String },
|
|
47
|
+
single: {
|
|
48
|
+
type: Boolean,
|
|
49
|
+
reflect: true
|
|
50
|
+
},
|
|
51
|
+
numberPosition: {
|
|
52
|
+
type: String,
|
|
53
|
+
attribute: "number-position"
|
|
54
|
+
},
|
|
55
|
+
disabled: {
|
|
56
|
+
type: Boolean,
|
|
57
|
+
reflect: true
|
|
58
|
+
},
|
|
59
|
+
dragging: { state: true }
|
|
60
|
+
};
|
|
61
|
+
static styles = [PcElement.styles, css`
|
|
62
|
+
:host {
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: var(--pc-space-2);
|
|
66
|
+
min-width: 0;
|
|
67
|
+
--pc-range-thumb: 16px;
|
|
68
|
+
}
|
|
69
|
+
:host([disabled]) {
|
|
70
|
+
opacity: 0.5;
|
|
71
|
+
}
|
|
72
|
+
pc-number-slider {
|
|
73
|
+
flex: none;
|
|
74
|
+
width: 4.5em;
|
|
75
|
+
}
|
|
76
|
+
/* The handles' centres reach the ends of the track */
|
|
77
|
+
.track {
|
|
78
|
+
position: relative;
|
|
79
|
+
flex: 1;
|
|
80
|
+
min-width: 60px;
|
|
81
|
+
height: 24px;
|
|
82
|
+
margin: 0 calc(var(--pc-range-thumb) / 2);
|
|
83
|
+
touch-action: none;
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
}
|
|
86
|
+
:host([disabled]) .track {
|
|
87
|
+
cursor: default;
|
|
88
|
+
}
|
|
89
|
+
.rail,
|
|
90
|
+
.fill {
|
|
91
|
+
position: absolute;
|
|
92
|
+
top: 50%;
|
|
93
|
+
height: 4px;
|
|
94
|
+
border-radius: var(--pc-radius-pill);
|
|
95
|
+
transform: translateY(-50%);
|
|
96
|
+
}
|
|
97
|
+
.rail {
|
|
98
|
+
left: calc(var(--pc-range-thumb) / -2);
|
|
99
|
+
right: calc(var(--pc-range-thumb) / -2);
|
|
100
|
+
background: var(--pc-border);
|
|
101
|
+
}
|
|
102
|
+
.fill {
|
|
103
|
+
background: var(--pc-accent);
|
|
104
|
+
}
|
|
105
|
+
/* A 24px target around each 16px thumb, for fingers */
|
|
106
|
+
.handle {
|
|
107
|
+
position: absolute;
|
|
108
|
+
top: 0;
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
width: 24px;
|
|
113
|
+
height: 24px;
|
|
114
|
+
margin-left: -12px;
|
|
115
|
+
border-radius: 50%;
|
|
116
|
+
outline: none;
|
|
117
|
+
}
|
|
118
|
+
.handle::before {
|
|
119
|
+
content: "";
|
|
120
|
+
width: var(--pc-range-thumb);
|
|
121
|
+
height: var(--pc-range-thumb);
|
|
122
|
+
box-sizing: border-box;
|
|
123
|
+
border: 2px solid var(--pc-surface-raised);
|
|
124
|
+
border-radius: 50%;
|
|
125
|
+
background: var(--pc-accent);
|
|
126
|
+
box-shadow: var(--pc-shadow);
|
|
127
|
+
}
|
|
128
|
+
.handle:focus-visible::before {
|
|
129
|
+
outline: var(--pc-focus-width) solid var(--pc-focus);
|
|
130
|
+
outline-offset: 2px;
|
|
131
|
+
}
|
|
132
|
+
/* The handle being dragged stays on top, so it can be dragged off the other */
|
|
133
|
+
.handle.active {
|
|
134
|
+
z-index: 1;
|
|
135
|
+
}
|
|
136
|
+
`];
|
|
137
|
+
/** A single slider's value: the same as `high` */
|
|
138
|
+
get value() {
|
|
139
|
+
return this.high;
|
|
140
|
+
}
|
|
141
|
+
set value(value) {
|
|
142
|
+
this.high = value;
|
|
143
|
+
}
|
|
144
|
+
/** What `pc-input` and `pc-change` give */
|
|
145
|
+
get detail() {
|
|
146
|
+
return {
|
|
147
|
+
low: this.low,
|
|
148
|
+
high: this.high,
|
|
149
|
+
value: this.high
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/** How far an end can go: not past the other end (a single slider's value can go down to `min`) */
|
|
153
|
+
limitsOf(end) {
|
|
154
|
+
if (end === "low") return [this.min, this.high];
|
|
155
|
+
return [this.single ? this.min : this.low, this.max];
|
|
156
|
+
}
|
|
157
|
+
/** An end's name for screen readers: a single slider's is its label */
|
|
158
|
+
endLabel(end) {
|
|
159
|
+
return this.single ? this.label : this.t(`paintCanvas.range.${end}`, { label: this.label });
|
|
160
|
+
}
|
|
161
|
+
constructor() {
|
|
162
|
+
super();
|
|
163
|
+
this.low = 0;
|
|
164
|
+
this.high = 100;
|
|
165
|
+
this.min = 0;
|
|
166
|
+
this.max = 100;
|
|
167
|
+
this.step = 1;
|
|
168
|
+
this.unit = "";
|
|
169
|
+
this.label = "";
|
|
170
|
+
this.single = false;
|
|
171
|
+
this.numberPosition = "start";
|
|
172
|
+
this.disabled = false;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Set one end, kept within `min` and `max`, rounded to `step`, and not past the other end, then tell listeners (with
|
|
176
|
+
* `pc-input` while dragging, or `pc-change`) if it changed.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* range.setEnd("high", 40); // high is 40, unless low is above it (then it's low)
|
|
180
|
+
*/
|
|
181
|
+
setEnd(end, value, type = "pc-change") {
|
|
182
|
+
const [lowest, highest] = this.limitsOf(end);
|
|
183
|
+
const next = Math.min(highest, Math.max(lowest, fitNumber(value, this.min, this.max, this.step)));
|
|
184
|
+
if (next === this[end]) return;
|
|
185
|
+
this[end] = next;
|
|
186
|
+
emit(this, type, this.detail);
|
|
187
|
+
}
|
|
188
|
+
/** The value at a pointer's position along the track */
|
|
189
|
+
valueAt(event) {
|
|
190
|
+
const { left, width } = event.currentTarget.getBoundingClientRect();
|
|
191
|
+
const fraction = width > 0 ? (event.clientX - left) / width : 0;
|
|
192
|
+
return this.min + Math.min(1, Math.max(0, fraction)) * (this.max - this.min);
|
|
193
|
+
}
|
|
194
|
+
/** The end nearest a value: the high end when it's above both, or past the middle of two that meet */
|
|
195
|
+
nearestEnd(value) {
|
|
196
|
+
if (this.single) return "high";
|
|
197
|
+
if (value > this.high) return "high";
|
|
198
|
+
if (value < this.low) return "low";
|
|
199
|
+
return value - this.low > this.high - value ? "high" : "low";
|
|
200
|
+
}
|
|
201
|
+
onPointerDown(event) {
|
|
202
|
+
if (this.disabled || event.button > 0) return;
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
const value = this.valueAt(event);
|
|
205
|
+
const end = this.nearestEnd(value);
|
|
206
|
+
this.dragging = end;
|
|
207
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
208
|
+
this.renderRoot.querySelector(`.handle.${end}`).focus();
|
|
209
|
+
this.setEnd(end, value, "pc-input");
|
|
210
|
+
}
|
|
211
|
+
onPointerMove(event) {
|
|
212
|
+
if (this.dragging) this.setEnd(this.dragging, this.valueAt(event), "pc-input");
|
|
213
|
+
}
|
|
214
|
+
onPointerUp() {
|
|
215
|
+
if (!this.dragging) return;
|
|
216
|
+
this.dragging = void 0;
|
|
217
|
+
emit(this, "pc-change", this.detail);
|
|
218
|
+
}
|
|
219
|
+
/** Move a handle with the arrow keys, Page Up and Page Down, Home and End */
|
|
220
|
+
onHandleKeyDown(event, end) {
|
|
221
|
+
if (this.disabled) return;
|
|
222
|
+
const page = this.pageStep ?? this.step * 10;
|
|
223
|
+
const value = this[end];
|
|
224
|
+
const next = {
|
|
225
|
+
ArrowRight: value + this.step,
|
|
226
|
+
ArrowUp: value + this.step,
|
|
227
|
+
ArrowLeft: value - this.step,
|
|
228
|
+
ArrowDown: value - this.step,
|
|
229
|
+
PageUp: value + page,
|
|
230
|
+
PageDown: value - page,
|
|
231
|
+
Home: this.min,
|
|
232
|
+
End: this.max
|
|
233
|
+
}[event.key];
|
|
234
|
+
if (next === void 0) return;
|
|
235
|
+
event.preventDefault();
|
|
236
|
+
this.setEnd(end, next);
|
|
237
|
+
}
|
|
238
|
+
/** One end's handle */
|
|
239
|
+
renderHandle(end) {
|
|
240
|
+
const value = this[end];
|
|
241
|
+
const [lowest, highest] = this.limitsOf(end);
|
|
242
|
+
return html`<div
|
|
243
|
+
class="handle ${end} ${this.dragging === end ? "active" : ""}"
|
|
244
|
+
part="handle"
|
|
245
|
+
role="slider"
|
|
246
|
+
tabindex=${this.disabled ? -1 : 0}
|
|
247
|
+
aria-label=${this.endLabel(end)}
|
|
248
|
+
aria-valuemin=${lowest}
|
|
249
|
+
aria-valuemax=${highest}
|
|
250
|
+
aria-valuenow=${value}
|
|
251
|
+
aria-valuetext=${`${value}${this.unit}`}
|
|
252
|
+
aria-disabled=${this.disabled ? "true" : nothing}
|
|
253
|
+
style=${styleMap({ left: `${rangeFraction(value, this.min, this.max) * 100}%` })}
|
|
254
|
+
@keydown=${(event) => this.onHandleKeyDown(event, end)}
|
|
255
|
+
></div>`;
|
|
256
|
+
}
|
|
257
|
+
/** One end's number slider: it can't go past the other end */
|
|
258
|
+
renderNumber(end) {
|
|
259
|
+
const [lowest, highest] = this.limitsOf(end);
|
|
260
|
+
return html`<pc-number-slider
|
|
261
|
+
class=${end}
|
|
262
|
+
part="number"
|
|
263
|
+
label=${this.endLabel(end)}
|
|
264
|
+
min=${lowest}
|
|
265
|
+
max=${highest}
|
|
266
|
+
step=${this.step}
|
|
267
|
+
page-step=${this.pageStep ?? nothing}
|
|
268
|
+
unit=${this.unit}
|
|
269
|
+
?disabled=${this.disabled}
|
|
270
|
+
.value=${live(this[end])}
|
|
271
|
+
@pc-change=${(event) => {
|
|
272
|
+
event.stopPropagation();
|
|
273
|
+
this.setEnd(end, event.detail.value);
|
|
274
|
+
}}
|
|
275
|
+
></pc-number-slider>`;
|
|
276
|
+
}
|
|
277
|
+
render() {
|
|
278
|
+
const from = this.single ? 0 : rangeFraction(this.low, this.min, this.max) * 100;
|
|
279
|
+
const to = rangeFraction(this.high, this.min, this.max) * 100;
|
|
280
|
+
const before = this.single ? this.numberPosition === "end" ? nothing : this.renderNumber("high") : this.renderNumber("low");
|
|
281
|
+
const after = !this.single || this.numberPosition === "end" ? this.renderNumber("high") : nothing;
|
|
282
|
+
return html`${before}
|
|
283
|
+
<div
|
|
284
|
+
class="track"
|
|
285
|
+
part="track"
|
|
286
|
+
@pointerdown=${this.onPointerDown}
|
|
287
|
+
@pointermove=${this.onPointerMove}
|
|
288
|
+
@pointerup=${this.onPointerUp}
|
|
289
|
+
@pointercancel=${this.onPointerUp}
|
|
290
|
+
>
|
|
291
|
+
<div class="rail"></div>
|
|
292
|
+
<div
|
|
293
|
+
class="fill"
|
|
294
|
+
part="fill"
|
|
295
|
+
style=${styleMap({
|
|
296
|
+
left: `${from}%`,
|
|
297
|
+
right: `${100 - to}%`
|
|
298
|
+
})}
|
|
299
|
+
></div>
|
|
300
|
+
${this.single ? nothing : this.renderHandle("low")}
|
|
301
|
+
${this.renderHandle("high")}
|
|
302
|
+
</div>
|
|
303
|
+
${after}`;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
defineElement("pc-slider-range", PcSliderRange);
|
|
307
|
+
export { PcSliderRange, rangeFraction };
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { nothing, type PropertyValues } from "lit";
|
|
2
2
|
import { PcElement } from "../../base";
|
|
3
3
|
import type PaintCanvas from "../../../lib/classes/PaintCanvas";
|
|
4
|
+
/**
|
|
5
|
+
* The least time between reads of the colour under the pointer, in milliseconds. Each read draws every layer's pixels
|
|
6
|
+
* there, which is slow on phones.
|
|
7
|
+
*/
|
|
8
|
+
export declare const COLOUR_INTERVAL_MS = 100;
|
|
4
9
|
/**
|
|
5
10
|
* A size in bytes in the largest unit it has at least one of, to one decimal place (whole bytes), for a locale.
|
|
6
11
|
*
|
|
@@ -12,8 +17,9 @@ export declare const formatBytes: (bytes: number, locale?: string) => string;
|
|
|
12
17
|
/**
|
|
13
18
|
* A line of small text about the canvas: its size; while the drawing is kept in the browser, how much its layer
|
|
14
19
|
* images take there; the zoom level; and the colour under the pointer (with a swatch; a dash when the pointer isn't
|
|
15
|
-
* over the canvas). The colour follows the pointer at most
|
|
16
|
-
*
|
|
20
|
+
* over the canvas). The colour follows the pointer at most every `COLOUR_INTERVAL_MS`, and isn't read while a stroke is
|
|
21
|
+
* drawn (the next pointer move after it reads it). It's not announced to screen readers as it changes, as it changes
|
|
22
|
+
* with every pointer move.
|
|
17
23
|
*
|
|
18
24
|
* @example
|
|
19
25
|
* html`<pc-stats .app=${app}></pc-stats>`
|
|
@@ -23,6 +29,9 @@ export declare class PcStats extends PcElement {
|
|
|
23
29
|
app: {
|
|
24
30
|
attribute: boolean;
|
|
25
31
|
};
|
|
32
|
+
colour: {
|
|
33
|
+
state: boolean;
|
|
34
|
+
};
|
|
26
35
|
translations: {
|
|
27
36
|
attribute: boolean;
|
|
28
37
|
};
|
|
@@ -38,11 +47,17 @@ export declare class PcStats extends PcElement {
|
|
|
38
47
|
/** The canvas described */
|
|
39
48
|
app?: PaintCanvas;
|
|
40
49
|
private changes;
|
|
50
|
+
/** The colour under the pointer when it was last read, if it's over the canvas */
|
|
51
|
+
colour?: string;
|
|
41
52
|
/** The canvas whose pointer is followed */
|
|
42
53
|
private followed?;
|
|
43
|
-
/** The
|
|
44
|
-
private
|
|
54
|
+
/** The timer the next read of the colour waits for, if any */
|
|
55
|
+
private timer?;
|
|
45
56
|
private readonly onPointer;
|
|
57
|
+
/**
|
|
58
|
+
* Read the colour under the followed canvas's pointer, unless a stroke is being drawn (reading would slow it down).
|
|
59
|
+
*/
|
|
60
|
+
private readColour;
|
|
46
61
|
connectedCallback(): void;
|
|
47
62
|
disconnectedCallback(): void;
|
|
48
63
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
@@ -4,6 +4,11 @@ import { zoomPercent } from "../PcToolSettings/index.js";
|
|
|
4
4
|
import { css, html, nothing } from "lit";
|
|
5
5
|
import { styleMap } from "lit/directives/style-map.js";
|
|
6
6
|
// src/ui/elements/PcStats/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* The least time between reads of the colour under the pointer, in milliseconds. Each read draws every layer's pixels
|
|
9
|
+
* there, which is slow on phones.
|
|
10
|
+
*/
|
|
11
|
+
var COLOUR_INTERVAL_MS = 100;
|
|
7
12
|
/** Units for sizes in bytes, each 1000 times the one before */
|
|
8
13
|
var BYTE_UNITS = [
|
|
9
14
|
"byte",
|
|
@@ -30,8 +35,9 @@ var formatBytes = (bytes, locale) => {
|
|
|
30
35
|
/**
|
|
31
36
|
* A line of small text about the canvas: its size; while the drawing is kept in the browser, how much its layer
|
|
32
37
|
* images take there; the zoom level; and the colour under the pointer (with a swatch; a dash when the pointer isn't
|
|
33
|
-
* over the canvas). The colour follows the pointer at most
|
|
34
|
-
*
|
|
38
|
+
* over the canvas). The colour follows the pointer at most every `COLOUR_INTERVAL_MS`, and isn't read while a stroke is
|
|
39
|
+
* drawn (the next pointer move after it reads it). It's not announced to screen readers as it changes, as it changes
|
|
40
|
+
* with every pointer move.
|
|
35
41
|
*
|
|
36
42
|
* @example
|
|
37
43
|
* html`<pc-stats .app=${app}></pc-stats>`
|
|
@@ -39,7 +45,8 @@ var formatBytes = (bytes, locale) => {
|
|
|
39
45
|
var PcStats = class extends PcElement {
|
|
40
46
|
static properties = {
|
|
41
47
|
...PcElement.properties,
|
|
42
|
-
app: { attribute: false }
|
|
48
|
+
app: { attribute: false },
|
|
49
|
+
colour: { state: true }
|
|
43
50
|
};
|
|
44
51
|
static styles = [PcElement.styles, css`
|
|
45
52
|
:host {
|
|
@@ -79,14 +86,22 @@ var PcStats = class extends PcElement {
|
|
|
79
86
|
]);
|
|
80
87
|
/** The canvas whose pointer is followed */
|
|
81
88
|
followed;
|
|
82
|
-
/** The
|
|
83
|
-
|
|
89
|
+
/** The timer the next read of the colour waits for, if any */
|
|
90
|
+
timer;
|
|
84
91
|
onPointer = () => {
|
|
85
|
-
this.
|
|
86
|
-
this.
|
|
87
|
-
this.
|
|
88
|
-
});
|
|
92
|
+
this.timer ??= setTimeout(() => {
|
|
93
|
+
this.timer = void 0;
|
|
94
|
+
this.readColour();
|
|
95
|
+
}, 100);
|
|
89
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Read the colour under the followed canvas's pointer, unless a stroke is being drawn (reading would slow it down).
|
|
99
|
+
*/
|
|
100
|
+
readColour() {
|
|
101
|
+
const app = this.followed;
|
|
102
|
+
if (!app || app.strokes.drawing) return;
|
|
103
|
+
this.colour = app.pointer && app.sampleColour(app.pointer);
|
|
104
|
+
}
|
|
90
105
|
connectedCallback() {
|
|
91
106
|
super.connectedCallback();
|
|
92
107
|
this.follow(this.app);
|
|
@@ -94,8 +109,6 @@ var PcStats = class extends PcElement {
|
|
|
94
109
|
disconnectedCallback() {
|
|
95
110
|
super.disconnectedCallback();
|
|
96
111
|
this.follow(void 0);
|
|
97
|
-
if (this.frame !== void 0) cancelAnimationFrame(this.frame);
|
|
98
|
-
this.frame = void 0;
|
|
99
112
|
}
|
|
100
113
|
willUpdate(changed) {
|
|
101
114
|
super.willUpdate(changed);
|
|
@@ -106,13 +119,16 @@ var PcStats = class extends PcElement {
|
|
|
106
119
|
*/
|
|
107
120
|
follow(app) {
|
|
108
121
|
this.followed?.removeEventListener("pointer", this.onPointer);
|
|
122
|
+
clearTimeout(this.timer);
|
|
123
|
+
this.timer = void 0;
|
|
124
|
+
this.colour = void 0;
|
|
109
125
|
this.followed = app;
|
|
110
126
|
app?.addEventListener("pointer", this.onPointer);
|
|
111
127
|
}
|
|
112
128
|
render() {
|
|
113
129
|
const app = this.app;
|
|
114
130
|
if (!app) return nothing;
|
|
115
|
-
const colour =
|
|
131
|
+
const colour = this.colour;
|
|
116
132
|
const autosave = app.autosave;
|
|
117
133
|
return html`<ul
|
|
118
134
|
part="stats"
|
|
@@ -141,4 +157,4 @@ var PcStats = class extends PcElement {
|
|
|
141
157
|
}
|
|
142
158
|
};
|
|
143
159
|
defineElement("pc-stats", PcStats);
|
|
144
|
-
export { PcStats, formatBytes };
|
|
160
|
+
export { COLOUR_INTERVAL_MS, PcStats, formatBytes };
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import { PcElement } from "../../base";
|
|
2
2
|
import type { IconName } from "../../icons";
|
|
3
|
+
import { THEMES, isTheme, type Theme, type UiSettingsLike } from "../../../lib/classes/UiSettings";
|
|
3
4
|
import "../PcButtonGroup";
|
|
4
|
-
|
|
5
|
-
export declare const THEMES: readonly ["light", "dark", "auto"];
|
|
6
|
-
export type Theme = (typeof THEMES)[number];
|
|
5
|
+
export { THEMES, isTheme, type Theme };
|
|
7
6
|
/** Each theme's icon */
|
|
8
7
|
export declare const THEME_ICONS: Readonly<Record<Theme, IconName>>;
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* isTheme("dark"); // true
|
|
14
|
-
* isTheme(undefined); // false
|
|
15
|
-
*/
|
|
16
|
-
export declare const isTheme: (value: unknown) => value is Theme;
|
|
17
|
-
/**
|
|
18
|
-
* Picks the light, dark or automatic theme (which follows the device), as a labelled group of three radios joined into
|
|
9
|
+
* Picks the light, dark or system theme (which follows the device's), as a labelled group of three radios joined into
|
|
19
10
|
* one pill (a joined `<pc-button-group>`), each with its icon (sun, moon and star) and name; the picked one is purple.
|
|
20
|
-
* Shows the theme of its `target` (the page's root element by default;
|
|
11
|
+
* Shows the theme of its `target` (the page's root element by default; system unless it has another), and sets the
|
|
21
12
|
* target's `data-pc-theme` when the user picks one, firing `change` (detail: the theme).
|
|
22
13
|
*
|
|
14
|
+
* With `settings` (e.g. the canvas's `ui`), it shows and keeps the theme there instead, and sets the target's theme
|
|
15
|
+
* whenever theirs changes (e.g. when restored), so it's kept with the other app settings.
|
|
16
|
+
*
|
|
23
17
|
* @example
|
|
24
18
|
* html`<pc-theme-picker @change=${(e) => save(e.detail)}></pc-theme-picker>`
|
|
25
19
|
*/
|
|
@@ -29,6 +23,9 @@ export declare class PcThemePicker extends PcElement {
|
|
|
29
23
|
type: StringConstructor;
|
|
30
24
|
reflect: boolean;
|
|
31
25
|
};
|
|
26
|
+
settings: {
|
|
27
|
+
attribute: boolean;
|
|
28
|
+
};
|
|
32
29
|
translations: {
|
|
33
30
|
attribute: boolean;
|
|
34
31
|
};
|
|
@@ -41,15 +38,20 @@ export declare class PcThemePicker extends PcElement {
|
|
|
41
38
|
theme: Theme;
|
|
42
39
|
/** The element whose `data-pc-theme` is shown and set (the page's root element by default) */
|
|
43
40
|
target?: HTMLElement;
|
|
41
|
+
/** Where the theme is kept, if anywhere (e.g. the canvas's `ui`) */
|
|
42
|
+
settings?: UiSettingsLike;
|
|
43
|
+
private changes;
|
|
44
44
|
constructor();
|
|
45
45
|
connectedCallback(): void;
|
|
46
|
+
/** Show the kept theme, and set it on the target */
|
|
47
|
+
protected willUpdate(): void;
|
|
46
48
|
/** The element whose theme is shown and set */
|
|
47
49
|
private get themeTarget();
|
|
48
50
|
/**
|
|
49
|
-
* Pick a theme: show it, set it on the target and tell listeners.
|
|
51
|
+
* Pick a theme: show it, keep it in the settings (if any), set it on the target and tell listeners.
|
|
50
52
|
*
|
|
51
53
|
* @example
|
|
52
|
-
* picker.pick("
|
|
54
|
+
* picker.pick("system");
|
|
53
55
|
*/
|
|
54
56
|
pick(theme: Theme): void;
|
|
55
57
|
render(): import("lit").TemplateResult<1>;
|
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
import { ICON_CONTROLS_CSS } from "../../styles/index.js";
|
|
2
2
|
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
3
|
+
import ChangeController from "../../ChangeController/index.js";
|
|
4
|
+
import { THEMES, isTheme } from "../../../lib/classes/UiSettings/index.js";
|
|
3
5
|
import "../PcButtonGroup/index.js";
|
|
4
6
|
import { css, html, unsafeCSS } from "lit";
|
|
5
7
|
// src/ui/elements/PcThemePicker/index.ts
|
|
6
|
-
/** The themes to pick from: light, dark, or following the device (auto) */
|
|
7
|
-
var THEMES = [
|
|
8
|
-
"light",
|
|
9
|
-
"dark",
|
|
10
|
-
"auto"
|
|
11
|
-
];
|
|
12
8
|
/** Each theme's icon */
|
|
13
9
|
var THEME_ICONS = {
|
|
14
10
|
light: "sun",
|
|
15
11
|
dark: "moon",
|
|
16
|
-
|
|
12
|
+
system: "star"
|
|
17
13
|
};
|
|
18
14
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* isTheme("dark"); // true
|
|
23
|
-
* isTheme(undefined); // false
|
|
24
|
-
*/
|
|
25
|
-
var isTheme = (value) => THEMES.includes(value);
|
|
26
|
-
/**
|
|
27
|
-
* Picks the light, dark or automatic theme (which follows the device), as a labelled group of three radios joined into
|
|
15
|
+
* Picks the light, dark or system theme (which follows the device's), as a labelled group of three radios joined into
|
|
28
16
|
* one pill (a joined `<pc-button-group>`), each with its icon (sun, moon and star) and name; the picked one is purple.
|
|
29
|
-
* Shows the theme of its `target` (the page's root element by default;
|
|
17
|
+
* Shows the theme of its `target` (the page's root element by default; system unless it has another), and sets the
|
|
30
18
|
* target's `data-pc-theme` when the user picks one, firing `change` (detail: the theme).
|
|
31
19
|
*
|
|
20
|
+
* With `settings` (e.g. the canvas's `ui`), it shows and keeps the theme there instead, and sets the target's theme
|
|
21
|
+
* whenever theirs changes (e.g. when restored), so it's kept with the other app settings.
|
|
22
|
+
*
|
|
32
23
|
* @example
|
|
33
24
|
* html`<pc-theme-picker @change=${(e) => save(e.detail)}></pc-theme-picker>`
|
|
34
25
|
*/
|
|
@@ -38,7 +29,8 @@ var PcThemePicker = class extends PcElement {
|
|
|
38
29
|
theme: {
|
|
39
30
|
type: String,
|
|
40
31
|
reflect: true
|
|
41
|
-
}
|
|
32
|
+
},
|
|
33
|
+
settings: { attribute: false }
|
|
42
34
|
};
|
|
43
35
|
static styles = [
|
|
44
36
|
PcElement.styles,
|
|
@@ -88,27 +80,36 @@ var PcThemePicker = class extends PcElement {
|
|
|
88
80
|
];
|
|
89
81
|
/** The element whose `data-pc-theme` is shown and set (the page's root element by default) */
|
|
90
82
|
target;
|
|
83
|
+
changes = new ChangeController(this, () => [this.settings]);
|
|
91
84
|
constructor() {
|
|
92
85
|
super();
|
|
93
|
-
this.theme = "
|
|
86
|
+
this.theme = "system";
|
|
94
87
|
}
|
|
95
88
|
connectedCallback() {
|
|
96
89
|
super.connectedCallback();
|
|
97
90
|
const current = this.themeTarget.dataset.pcTheme;
|
|
98
91
|
if (isTheme(current)) this.theme = current;
|
|
99
92
|
}
|
|
93
|
+
/** Show the kept theme, and set it on the target */
|
|
94
|
+
willUpdate() {
|
|
95
|
+
const theme = this.settings?.data.theme;
|
|
96
|
+
if (theme === void 0) return;
|
|
97
|
+
this.theme = theme;
|
|
98
|
+
this.themeTarget.dataset.pcTheme = theme;
|
|
99
|
+
}
|
|
100
100
|
/** The element whose theme is shown and set */
|
|
101
101
|
get themeTarget() {
|
|
102
102
|
return this.target ?? document.documentElement;
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
* Pick a theme: show it, set it on the target and tell listeners.
|
|
105
|
+
* Pick a theme: show it, keep it in the settings (if any), set it on the target and tell listeners.
|
|
106
106
|
*
|
|
107
107
|
* @example
|
|
108
|
-
* picker.pick("
|
|
108
|
+
* picker.pick("system");
|
|
109
109
|
*/
|
|
110
110
|
pick(theme) {
|
|
111
111
|
this.theme = theme;
|
|
112
|
+
this.settings?.update({ theme });
|
|
112
113
|
this.themeTarget.dataset.pcTheme = theme;
|
|
113
114
|
emit(this, "change", theme);
|
|
114
115
|
}
|