@lvl99dotcom/paintcanvas 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +131 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/lib/brushes/BrushTipCache/index.d.ts +32 -0
- package/dist/lib/brushes/BrushTipCache/index.js +60 -0
- package/dist/lib/brushes/StrokeEngine/index.d.ts +171 -0
- package/dist/lib/brushes/StrokeEngine/index.js +324 -0
- package/dist/lib/brushes/StrokePath/index.d.ts +53 -0
- package/dist/lib/brushes/StrokePath/index.js +161 -0
- package/dist/lib/brushes/StrokeSampler/index.d.ts +55 -0
- package/dist/lib/brushes/StrokeSampler/index.js +75 -0
- package/dist/lib/brushes/authors/index.d.ts +55 -0
- package/dist/lib/brushes/authors/index.js +60 -0
- package/dist/lib/brushes/configRanges/index.d.ts +52 -0
- package/dist/lib/brushes/configRanges/index.js +206 -0
- package/dist/lib/brushes/index.d.ts +5 -0
- package/dist/lib/brushes/index.js +19 -0
- package/dist/lib/brushes/params/index.d.ts +108 -0
- package/dist/lib/brushes/params/index.js +139 -0
- package/dist/lib/brushes/presetFile/index.d.ts +32 -0
- package/dist/lib/brushes/presetFile/index.js +55 -0
- package/dist/lib/brushes/presets/drawing/brush-pen.js +3 -0
- package/dist/lib/brushes/presets/drawing/felt-pen.js +3 -0
- package/dist/lib/brushes/presets/drawing/index.d.ts +13 -0
- package/dist/lib/brushes/presets/drawing/index.js +88 -0
- package/dist/lib/brushes/presets/drawing/pencil-2b.js +3 -0
- package/dist/lib/brushes/presets/drawing/pencil-hb.js +3 -0
- package/dist/lib/brushes/presets/painting/grass.js +3 -0
- package/dist/lib/brushes/presets/painting/hair.js +3 -0
- package/dist/lib/brushes/presets/painting/index.d.ts +18 -0
- package/dist/lib/brushes/presets/painting/index.js +118 -0
- package/dist/lib/brushes/presets/painting/splatter.js +3 -0
- package/dist/lib/brushes/presets/painting/textured-paint.js +3 -0
- package/dist/lib/brushes/presets/painting/watery-paint.js +3 -0
- package/dist/lib/brushes/presets/round/index.d.ts +9 -0
- package/dist/lib/brushes/presets/round/index.js +44 -0
- package/dist/lib/brushes/presets/round/round.js +3 -0
- package/dist/lib/brushes/presets/round/soft-round.js +3 -0
- package/dist/lib/brushes/presets/sized/index.d.ts +20 -0
- package/dist/lib/brushes/presets/sized/index.js +30 -0
- package/dist/lib/brushes/presets/sketching/index.d.ts +14 -0
- package/dist/lib/brushes/presets/sketching/index.js +107 -0
- package/dist/lib/brushes/presets/square/index.d.ts +7 -0
- package/dist/lib/brushes/presets/square/index.js +22 -0
- package/dist/lib/brushes/presets/square/square.js +3 -0
- package/dist/lib/brushes/shapeImage/index.d.ts +40 -0
- package/dist/lib/brushes/shapeImage/index.js +61 -0
- package/dist/lib/brushes/types/index.d.ts +243 -0
- package/dist/lib/brushes/types/index.js +20 -0
- package/dist/lib/classes/BackgroundWork/index.d.ts +55 -0
- package/dist/lib/classes/BackgroundWork/index.js +97 -0
- package/dist/lib/classes/BrushSettings/index.d.ts +91 -0
- package/dist/lib/classes/BrushSettings/index.js +152 -0
- package/dist/lib/classes/CustomPresets/index.d.ts +53 -0
- package/dist/lib/classes/CustomPresets/index.js +71 -0
- package/dist/lib/classes/ExternalSheets/index.d.ts +64 -0
- package/dist/lib/classes/ExternalSheets/index.js +112 -0
- package/dist/lib/classes/GestureTracker/index.d.ts +62 -0
- package/dist/lib/classes/GestureTracker/index.js +122 -0
- package/dist/lib/classes/History/index.d.ts +83 -0
- package/dist/lib/classes/History/index.js +126 -0
- package/dist/lib/classes/HistoryGuard/index.d.ts +58 -0
- package/dist/lib/classes/HistoryGuard/index.js +97 -0
- package/dist/lib/classes/InputSettings/index.d.ts +74 -0
- package/dist/lib/classes/InputSettings/index.js +101 -0
- package/dist/lib/classes/KeyboardShortcuts/index.d.ts +48 -0
- package/dist/lib/classes/KeyboardShortcuts/index.js +137 -0
- package/dist/lib/classes/Layer/index.d.ts +86 -0
- package/dist/lib/classes/Layer/index.js +111 -0
- package/dist/lib/classes/LayerAutosave/index.d.ts +180 -0
- package/dist/lib/classes/LayerAutosave/index.js +346 -0
- package/dist/lib/classes/LayerStack/index.d.ts +177 -0
- package/dist/lib/classes/LayerStack/index.js +394 -0
- package/dist/lib/classes/PaintCanvas/index.d.ts +537 -0
- package/dist/lib/classes/PaintCanvas/index.js +965 -0
- package/dist/lib/classes/StrokeLog/index.d.ts +149 -0
- package/dist/lib/classes/StrokeLog/index.js +257 -0
- package/dist/lib/classes/Viewport/index.d.ts +108 -0
- package/dist/lib/classes/Viewport/index.js +194 -0
- package/dist/lib/document/index.d.ts +17 -0
- package/dist/lib/document/index.js +25 -0
- package/dist/lib/document/schema.d.ts +132 -0
- package/dist/lib/document/schema.js +110 -0
- package/dist/lib/i18n/index.d.ts +131 -0
- package/dist/lib/i18n/index.js +277 -0
- package/dist/lib/image/index.d.ts +90 -0
- package/dist/lib/image/index.js +147 -0
- package/dist/lib/messages/PatchSender/index.d.ts +75 -0
- package/dist/lib/messages/PatchSender/index.js +125 -0
- package/dist/lib/messages/index.d.ts +26 -0
- package/dist/lib/messages/index.js +59 -0
- package/dist/lib/messages/schema.d.ts +1775 -0
- package/dist/lib/messages/schema.js +192 -0
- package/dist/lib/presets/index.d.ts +32 -0
- package/dist/lib/presets/index.js +35 -0
- package/dist/lib/presets/schema.d.ts +753 -0
- package/dist/lib/presets/schema.js +181 -0
- package/dist/lib/rendering/BrushTip/index.d.ts +63 -0
- package/dist/lib/rendering/BrushTip/index.js +112 -0
- package/dist/lib/rendering/checkerboard/index.d.ts +22 -0
- package/dist/lib/rendering/checkerboard/index.js +31 -0
- package/dist/lib/rendering/compositing/index.d.ts +64 -0
- package/dist/lib/rendering/compositing/index.js +124 -0
- package/dist/lib/rendering/cursor/index.d.ts +14 -0
- package/dist/lib/rendering/cursor/index.js +39 -0
- package/dist/lib/rendering/cursors/index.d.ts +18 -0
- package/dist/lib/rendering/cursors/index.js +23 -0
- package/dist/lib/rendering/maskOutline/index.d.ts +22 -0
- package/dist/lib/rendering/maskOutline/index.js +78 -0
- package/dist/lib/rendering/outline/index.d.ts +36 -0
- package/dist/lib/rendering/outline/index.js +120 -0
- package/dist/lib/rendering/sample/index.d.ts +55 -0
- package/dist/lib/rendering/sample/index.js +83 -0
- package/dist/lib/rendering/screenshot/index.d.ts +67 -0
- package/dist/lib/rendering/screenshot/index.js +96 -0
- package/dist/lib/rendering/transformBox/index.d.ts +10 -0
- package/dist/lib/rendering/transformBox/index.js +57 -0
- package/dist/lib/selection/Lasso/index.d.ts +70 -0
- package/dist/lib/selection/Lasso/index.js +156 -0
- package/dist/lib/selection/Selection/index.d.ts +86 -0
- package/dist/lib/selection/Selection/index.js +228 -0
- package/dist/lib/selection/geometry/index.d.ts +37 -0
- package/dist/lib/selection/geometry/index.js +57 -0
- package/dist/lib/storage/index.d.ts +63 -0
- package/dist/lib/storage/index.js +114 -0
- package/dist/lib/transform/Transformer/index.d.ts +124 -0
- package/dist/lib/transform/Transformer/index.js +286 -0
- package/dist/lib/transform/geometry/index.d.ts +95 -0
- package/dist/lib/transform/geometry/index.js +258 -0
- package/dist/lib/utils/array/index.d.ts +10 -0
- package/dist/lib/utils/array/index.js +21 -0
- package/dist/lib/utils/gestures/index.d.ts +35 -0
- package/dist/lib/utils/gestures/index.js +81 -0
- package/dist/lib/utils/navigation/index.d.ts +51 -0
- package/dist/lib/utils/navigation/index.js +59 -0
- package/dist/lib/utils/random/index.d.ts +18 -0
- package/dist/lib/utils/random/index.js +27 -0
- package/dist/lib/utils/shortcuts/index.d.ts +74 -0
- package/dist/lib/utils/shortcuts/index.js +189 -0
- package/dist/lib/validation/validators.generated.d.ts +27 -0
- package/dist/lib/validation/validators.generated.js +19826 -0
- package/dist/locales/en-GB.js +181 -0
- package/dist/locales/en-US.js +181 -0
- package/dist/locales/fr.js +181 -0
- package/dist/locales/ja.js +181 -0
- package/dist/locales/ko.js +181 -0
- package/dist/locales/zh-Hans.js +181 -0
- package/dist/locales/zh-Hant.js +181 -0
- package/dist/package.js +3 -0
- package/dist/testing/app.d.ts +7 -0
- package/dist/testing/app.js +16 -0
- package/dist/testing/elements.d.ts +42 -0
- package/dist/testing/elements.js +58 -0
- package/dist/testing/fakeCanvas.d.ts +21 -0
- package/dist/testing/fakeCanvas.js +26 -0
- package/dist/testing/layerStore.d.ts +26 -0
- package/dist/testing/layerStore.js +43 -0
- package/dist/testing/locks.d.ts +15 -0
- package/dist/testing/locks.js +41 -0
- package/dist/testing/recordingCanvas.d.ts +14 -0
- package/dist/testing/recordingCanvas.js +28 -0
- package/dist/testing/recordingContext.d.ts +10 -0
- package/dist/testing/recordingContext.js +19 -0
- package/dist/ui/ChangeController/index.d.ts +40 -0
- package/dist/ui/ChangeController/index.js +62 -0
- package/dist/ui/base/index.d.ts +69 -0
- package/dist/ui/base/index.js +94 -0
- package/dist/ui/elements/PaintCanvas/index.d.ts +249 -0
- package/dist/ui/elements/PaintCanvas/index.js +584 -0
- package/dist/ui/elements/PaintCanvas/style.js +3 -0
- package/dist/ui/elements/PcBrushConfig/index.d.ts +130 -0
- package/dist/ui/elements/PcBrushConfig/index.js +465 -0
- package/dist/ui/elements/PcBrushConfig/style.js +3 -0
- package/dist/ui/elements/PcBrushMenu/index.d.ts +121 -0
- package/dist/ui/elements/PcBrushMenu/index.js +362 -0
- package/dist/ui/elements/PcBrushMenu/style.js +3 -0
- package/dist/ui/elements/PcBrushTest/index.d.ts +71 -0
- package/dist/ui/elements/PcBrushTest/index.js +136 -0
- package/dist/ui/elements/PcBrushTest/style.js +3 -0
- package/dist/ui/elements/PcButton/index.d.ts +57 -0
- package/dist/ui/elements/PcButton/index.js +124 -0
- package/dist/ui/elements/PcButtonGroup/index.d.ts +44 -0
- package/dist/ui/elements/PcButtonGroup/index.js +93 -0
- package/dist/ui/elements/PcCanvas/index.d.ts +356 -0
- package/dist/ui/elements/PcCanvas/index.js +1004 -0
- package/dist/ui/elements/PcCanvas/style.js +3 -0
- package/dist/ui/elements/PcCanvasMap/index.d.ts +96 -0
- package/dist/ui/elements/PcCanvasMap/index.js +187 -0
- package/dist/ui/elements/PcCanvasMap/style.js +3 -0
- package/dist/ui/elements/PcContextMenu/index.d.ts +72 -0
- package/dist/ui/elements/PcContextMenu/index.js +148 -0
- package/dist/ui/elements/PcDialog/index.d.ts +63 -0
- package/dist/ui/elements/PcDialog/index.js +114 -0
- package/dist/ui/elements/PcIcon/index.d.ts +36 -0
- package/dist/ui/elements/PcIcon/index.js +43 -0
- package/dist/ui/elements/PcIconToggle/index.d.ts +46 -0
- package/dist/ui/elements/PcIconToggle/index.js +87 -0
- package/dist/ui/elements/PcInfoTip/index.d.ts +40 -0
- package/dist/ui/elements/PcInfoTip/index.js +95 -0
- package/dist/ui/elements/PcInputSettings/index.d.ts +69 -0
- package/dist/ui/elements/PcInputSettings/index.js +154 -0
- package/dist/ui/elements/PcLayerItem/index.d.ts +221 -0
- package/dist/ui/elements/PcLayerItem/index.js +561 -0
- package/dist/ui/elements/PcLayerItem/style.js +3 -0
- package/dist/ui/elements/PcLayersMenu/index.d.ts +108 -0
- package/dist/ui/elements/PcLayersMenu/index.js +208 -0
- package/dist/ui/elements/PcLayersMenu/style.js +3 -0
- package/dist/ui/elements/PcMatch/index.d.ts +31 -0
- package/dist/ui/elements/PcMatch/index.js +58 -0
- package/dist/ui/elements/PcPanel/index.d.ts +43 -0
- package/dist/ui/elements/PcPanel/index.js +51 -0
- package/dist/ui/elements/PcPopover/index.d.ts +48 -0
- package/dist/ui/elements/PcPopover/index.js +86 -0
- package/dist/ui/elements/PcSlider/index.d.ts +57 -0
- package/dist/ui/elements/PcSlider/index.js +88 -0
- package/dist/ui/elements/PcStats/index.d.ts +54 -0
- package/dist/ui/elements/PcStats/index.js +144 -0
- package/dist/ui/elements/PcThemePicker/index.d.ts +56 -0
- package/dist/ui/elements/PcThemePicker/index.js +134 -0
- package/dist/ui/elements/PcToast/index.d.ts +58 -0
- package/dist/ui/elements/PcToast/index.js +110 -0
- package/dist/ui/elements/PcToggleCheckbox/index.d.ts +37 -0
- package/dist/ui/elements/PcToggleCheckbox/index.js +105 -0
- package/dist/ui/elements/PcToolSettings/index.d.ts +128 -0
- package/dist/ui/elements/PcToolSettings/index.js +549 -0
- package/dist/ui/elements/PcToolSettings/style.js +3 -0
- package/dist/ui/elements/PcToolbar/index.d.ts +71 -0
- package/dist/ui/elements/PcToolbar/index.js +190 -0
- package/dist/ui/elements/PcToolbar/style.js +3 -0
- package/dist/ui/icons/images/brush.js +3 -0
- package/dist/ui/icons/images/circle-mask.js +3 -0
- package/dist/ui/icons/images/clipboard.js +3 -0
- package/dist/ui/icons/images/cursor.js +3 -0
- package/dist/ui/icons/images/eraser.js +3 -0
- package/dist/ui/icons/images/eyedropper.js +3 -0
- package/dist/ui/icons/images/flip-horizontal.js +3 -0
- package/dist/ui/icons/images/flip-vertical.js +3 -0
- package/dist/ui/icons/images/focus-pen.js +3 -0
- package/dist/ui/icons/images/freehand-mask.js +3 -0
- package/dist/ui/icons/images/hidden.js +3 -0
- package/dist/ui/icons/images/layers.js +3 -0
- package/dist/ui/icons/images/linked.js +3 -0
- package/dist/ui/icons/images/locked.js +3 -0
- package/dist/ui/icons/images/moon.js +3 -0
- package/dist/ui/icons/images/pan.js +3 -0
- package/dist/ui/icons/images/polygon-mask.js +3 -0
- package/dist/ui/icons/images/pressure.js +3 -0
- package/dist/ui/icons/images/randomise.js +3 -0
- package/dist/ui/icons/images/rectangle-mask.js +3 -0
- package/dist/ui/icons/images/redo.js +3 -0
- package/dist/ui/icons/images/rotate-90-left.js +3 -0
- package/dist/ui/icons/images/rotate-90-right.js +3 -0
- package/dist/ui/icons/images/smoothing-bezier-cubic.js +3 -0
- package/dist/ui/icons/images/smoothing-bezier-quad.js +3 -0
- package/dist/ui/icons/images/smoothing-linear.js +3 -0
- package/dist/ui/icons/images/star.js +3 -0
- package/dist/ui/icons/images/sun.js +3 -0
- package/dist/ui/icons/images/tilt.js +3 -0
- package/dist/ui/icons/images/undo.js +3 -0
- package/dist/ui/icons/images/unlinked.js +3 -0
- package/dist/ui/icons/images/unlocked.js +3 -0
- package/dist/ui/icons/images/visible.js +3 -0
- package/dist/ui/icons/images/zoom-in.js +3 -0
- package/dist/ui/icons/images/zoom-out.js +3 -0
- package/dist/ui/icons/images/zoom.js +3 -0
- package/dist/ui/icons/index.d.ts +42 -0
- package/dist/ui/icons/index.js +130 -0
- package/dist/ui/index.d.ts +21 -0
- package/dist/ui/index.js +22 -0
- package/dist/ui/layout/index.d.ts +88 -0
- package/dist/ui/layout/index.js +96 -0
- package/dist/ui/styles/index.d.ts +13 -0
- package/dist/ui/styles/index.js +195 -0
- package/dist/ui/tokens/index.d.ts +29 -0
- package/dist/ui/tokens/index.js +114 -0
- package/locales/en-GB.json +179 -0
- package/locales/en-US.json +179 -0
- package/locales/fr.json +179 -0
- package/locales/ja.json +179 -0
- package/locales/ko.json +179 -0
- package/locales/zh-Hans.json +179 -0
- package/locales/zh-Hant.json +179 -0
- package/package.json +97 -3
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { nothing, type PropertyValues } from "lit";
|
|
2
|
+
import { PcElement } from "../../base";
|
|
3
|
+
import type PaintCanvas from "../../../lib/classes/PaintCanvas";
|
|
4
|
+
/**
|
|
5
|
+
* A size in bytes in the largest unit it has at least one of, to one decimal place (whole bytes), for a locale.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* formatBytes(84_560, "en-GB"); // "84.6 kB"
|
|
9
|
+
* formatBytes(512, "en-GB"); // "512 byte"
|
|
10
|
+
*/
|
|
11
|
+
export declare const formatBytes: (bytes: number, locale?: string) => string;
|
|
12
|
+
/**
|
|
13
|
+
* A line of small text about the canvas: its size; while the drawing is kept in the browser, how much its layer
|
|
14
|
+
* 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 once a frame. It's not announced to screen readers as it
|
|
16
|
+
* changes, as it changes with every pointer move.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* html`<pc-stats .app=${app}></pc-stats>`
|
|
20
|
+
*/
|
|
21
|
+
export declare class PcStats extends PcElement {
|
|
22
|
+
static properties: {
|
|
23
|
+
app: {
|
|
24
|
+
attribute: boolean;
|
|
25
|
+
};
|
|
26
|
+
translations: {
|
|
27
|
+
attribute: boolean;
|
|
28
|
+
};
|
|
29
|
+
icons: {
|
|
30
|
+
attribute: boolean;
|
|
31
|
+
};
|
|
32
|
+
theme: {
|
|
33
|
+
type: StringConstructor;
|
|
34
|
+
reflect: boolean;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
static styles: import("lit").CSSResultGroup[];
|
|
38
|
+
/** The canvas described */
|
|
39
|
+
app?: PaintCanvas;
|
|
40
|
+
private changes;
|
|
41
|
+
/** The canvas whose pointer is followed */
|
|
42
|
+
private followed?;
|
|
43
|
+
/** The animation frame the next update waits for, if any */
|
|
44
|
+
private frame?;
|
|
45
|
+
private readonly onPointer;
|
|
46
|
+
connectedCallback(): void;
|
|
47
|
+
disconnectedCallback(): void;
|
|
48
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Follow a canvas's pointer (or none), instead of the one followed before.
|
|
51
|
+
*/
|
|
52
|
+
private follow;
|
|
53
|
+
render(): import("lit").TemplateResult<1> | typeof nothing;
|
|
54
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { PcElement, defineElement } from "../../base/index.js";
|
|
2
|
+
import ChangeController from "../../ChangeController/index.js";
|
|
3
|
+
import { zoomPercent } from "../PcToolSettings/index.js";
|
|
4
|
+
import { css, html, nothing } from "lit";
|
|
5
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
6
|
+
// src/ui/elements/PcStats/index.ts
|
|
7
|
+
/** Units for sizes in bytes, each 1000 times the one before */
|
|
8
|
+
var BYTE_UNITS = [
|
|
9
|
+
"byte",
|
|
10
|
+
"kilobyte",
|
|
11
|
+
"megabyte",
|
|
12
|
+
"gigabyte"
|
|
13
|
+
];
|
|
14
|
+
/**
|
|
15
|
+
* A size in bytes in the largest unit it has at least one of, to one decimal place (whole bytes), for a locale.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* formatBytes(84_560, "en-GB"); // "84.6 kB"
|
|
19
|
+
* formatBytes(512, "en-GB"); // "512 byte"
|
|
20
|
+
*/
|
|
21
|
+
var formatBytes = (bytes, locale) => {
|
|
22
|
+
const step = Math.min(Math.max(Math.floor(Math.log10(bytes) / 3), 0), BYTE_UNITS.length - 1);
|
|
23
|
+
return new Intl.NumberFormat(locale, {
|
|
24
|
+
style: "unit",
|
|
25
|
+
unit: BYTE_UNITS[step],
|
|
26
|
+
unitDisplay: "short",
|
|
27
|
+
maximumFractionDigits: step === 0 ? 0 : 1
|
|
28
|
+
}).format(bytes / 1e3 ** step);
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* A line of small text about the canvas: its size; while the drawing is kept in the browser, how much its layer
|
|
32
|
+
* 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 once a frame. It's not announced to screen readers as it
|
|
34
|
+
* changes, as it changes with every pointer move.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* html`<pc-stats .app=${app}></pc-stats>`
|
|
38
|
+
*/
|
|
39
|
+
var PcStats = class extends PcElement {
|
|
40
|
+
static properties = {
|
|
41
|
+
...PcElement.properties,
|
|
42
|
+
app: { attribute: false }
|
|
43
|
+
};
|
|
44
|
+
static styles = [PcElement.styles, css`
|
|
45
|
+
:host {
|
|
46
|
+
display: block;
|
|
47
|
+
padding: 2px var(--pc-space-2);
|
|
48
|
+
border-top: 1px solid var(--pc-border);
|
|
49
|
+
background: var(--pc-bar);
|
|
50
|
+
color: var(--pc-text);
|
|
51
|
+
font-family: var(--pc-font);
|
|
52
|
+
font-size: var(--pc-font-size-small);
|
|
53
|
+
}
|
|
54
|
+
ul {
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-wrap: wrap;
|
|
57
|
+
gap: 2px var(--pc-space-3);
|
|
58
|
+
margin: 0;
|
|
59
|
+
padding: 0;
|
|
60
|
+
list-style: none;
|
|
61
|
+
}
|
|
62
|
+
li {
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 4px;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
font-variant-numeric: tabular-nums;
|
|
68
|
+
}
|
|
69
|
+
.swatch {
|
|
70
|
+
width: 10px;
|
|
71
|
+
height: 10px;
|
|
72
|
+
border: 1px solid var(--pc-border);
|
|
73
|
+
}
|
|
74
|
+
`];
|
|
75
|
+
changes = new ChangeController(this, () => [
|
|
76
|
+
this.app,
|
|
77
|
+
this.app?.viewport,
|
|
78
|
+
this.app?.autosave
|
|
79
|
+
]);
|
|
80
|
+
/** The canvas whose pointer is followed */
|
|
81
|
+
followed;
|
|
82
|
+
/** The animation frame the next update waits for, if any */
|
|
83
|
+
frame;
|
|
84
|
+
onPointer = () => {
|
|
85
|
+
this.frame ??= requestAnimationFrame(() => {
|
|
86
|
+
this.frame = void 0;
|
|
87
|
+
this.requestUpdate();
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
connectedCallback() {
|
|
91
|
+
super.connectedCallback();
|
|
92
|
+
this.follow(this.app);
|
|
93
|
+
}
|
|
94
|
+
disconnectedCallback() {
|
|
95
|
+
super.disconnectedCallback();
|
|
96
|
+
this.follow(void 0);
|
|
97
|
+
if (this.frame !== void 0) cancelAnimationFrame(this.frame);
|
|
98
|
+
this.frame = void 0;
|
|
99
|
+
}
|
|
100
|
+
willUpdate(changed) {
|
|
101
|
+
super.willUpdate(changed);
|
|
102
|
+
if (changed.has("app") && this.isConnected) this.follow(this.app);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Follow a canvas's pointer (or none), instead of the one followed before.
|
|
106
|
+
*/
|
|
107
|
+
follow(app) {
|
|
108
|
+
this.followed?.removeEventListener("pointer", this.onPointer);
|
|
109
|
+
this.followed = app;
|
|
110
|
+
app?.addEventListener("pointer", this.onPointer);
|
|
111
|
+
}
|
|
112
|
+
render() {
|
|
113
|
+
const app = this.app;
|
|
114
|
+
if (!app) return nothing;
|
|
115
|
+
const colour = app.pointer && app.sampleColour(app.pointer);
|
|
116
|
+
const autosave = app.autosave;
|
|
117
|
+
return html`<ul
|
|
118
|
+
part="stats"
|
|
119
|
+
aria-label=${this.t("paintCanvas.stats.label")}
|
|
120
|
+
>
|
|
121
|
+
<li class="size">
|
|
122
|
+
${this.t("paintCanvas.stats.size", {
|
|
123
|
+
width: app.width,
|
|
124
|
+
height: app.height
|
|
125
|
+
})}
|
|
126
|
+
</li>
|
|
127
|
+
${autosave ? html`<li class="stored">
|
|
128
|
+
${this.t("paintCanvas.stats.stored", { size: formatBytes(autosave.storedBytes, this.translations.locale) })}
|
|
129
|
+
</li>` : nothing}
|
|
130
|
+
<li class="zoom">
|
|
131
|
+
${this.t("paintCanvas.stats.zoom", { zoom: zoomPercent(app.viewport.zoom) })}
|
|
132
|
+
</li>
|
|
133
|
+
<li class="colour">
|
|
134
|
+
${this.t("paintCanvas.stats.colour", { colour: colour ?? "—" })}
|
|
135
|
+
${colour ? html`<span
|
|
136
|
+
class="swatch"
|
|
137
|
+
style=${styleMap({ background: colour })}
|
|
138
|
+
></span>` : nothing}
|
|
139
|
+
</li>
|
|
140
|
+
</ul>`;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
defineElement("pc-stats", PcStats);
|
|
144
|
+
export { PcStats, formatBytes };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { PcElement } from "../../base";
|
|
2
|
+
import type { IconName } from "../../icons";
|
|
3
|
+
import "../PcButtonGroup";
|
|
4
|
+
/** The themes to pick from: light, dark, or following the device (auto) */
|
|
5
|
+
export declare const THEMES: readonly ["light", "dark", "auto"];
|
|
6
|
+
export type Theme = (typeof THEMES)[number];
|
|
7
|
+
/** Each theme's icon */
|
|
8
|
+
export declare const THEME_ICONS: Readonly<Record<Theme, IconName>>;
|
|
9
|
+
/**
|
|
10
|
+
* Whether a value is one of the themes.
|
|
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
|
|
19
|
+
* 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; light unless it has another), and sets the
|
|
21
|
+
* target's `data-pc-theme` when the user picks one, firing `change` (detail: the theme).
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* html`<pc-theme-picker @change=${(e) => save(e.detail)}></pc-theme-picker>`
|
|
25
|
+
*/
|
|
26
|
+
export declare class PcThemePicker extends PcElement {
|
|
27
|
+
static properties: {
|
|
28
|
+
theme: {
|
|
29
|
+
type: StringConstructor;
|
|
30
|
+
reflect: boolean;
|
|
31
|
+
};
|
|
32
|
+
translations: {
|
|
33
|
+
attribute: boolean;
|
|
34
|
+
};
|
|
35
|
+
icons: {
|
|
36
|
+
attribute: boolean;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
static styles: import("lit").CSSResultGroup[];
|
|
40
|
+
/** The theme shown as picked */
|
|
41
|
+
theme: Theme;
|
|
42
|
+
/** The element whose `data-pc-theme` is shown and set (the page's root element by default) */
|
|
43
|
+
target?: HTMLElement;
|
|
44
|
+
constructor();
|
|
45
|
+
connectedCallback(): void;
|
|
46
|
+
/** The element whose theme is shown and set */
|
|
47
|
+
private get themeTarget();
|
|
48
|
+
/**
|
|
49
|
+
* Pick a theme: show it, set it on the target and tell listeners.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* picker.pick("auto");
|
|
53
|
+
*/
|
|
54
|
+
pick(theme: Theme): void;
|
|
55
|
+
render(): import("lit").TemplateResult<1>;
|
|
56
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { ICON_CONTROLS_CSS } from "../../styles/index.js";
|
|
2
|
+
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
3
|
+
import { css, html, unsafeCSS } from "lit";
|
|
4
|
+
// src/ui/elements/PcThemePicker/index.ts
|
|
5
|
+
/** The themes to pick from: light, dark, or following the device (auto) */
|
|
6
|
+
var THEMES = [
|
|
7
|
+
"light",
|
|
8
|
+
"dark",
|
|
9
|
+
"auto"
|
|
10
|
+
];
|
|
11
|
+
/** Each theme's icon */
|
|
12
|
+
var THEME_ICONS = {
|
|
13
|
+
light: "sun",
|
|
14
|
+
dark: "moon",
|
|
15
|
+
auto: "star"
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Whether a value is one of the themes.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* isTheme("dark"); // true
|
|
22
|
+
* isTheme(undefined); // false
|
|
23
|
+
*/
|
|
24
|
+
var isTheme = (value) => THEMES.includes(value);
|
|
25
|
+
/**
|
|
26
|
+
* Picks the light, dark or automatic theme (which follows the device), as a labelled group of three radios joined into
|
|
27
|
+
* one pill (a joined `<pc-button-group>`), each with its icon (sun, moon and star) and name; the picked one is purple.
|
|
28
|
+
* Shows the theme of its `target` (the page's root element by default; light unless it has another), and sets the
|
|
29
|
+
* target's `data-pc-theme` when the user picks one, firing `change` (detail: the theme).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* html`<pc-theme-picker @change=${(e) => save(e.detail)}></pc-theme-picker>`
|
|
33
|
+
*/
|
|
34
|
+
var PcThemePicker = class extends PcElement {
|
|
35
|
+
static properties = {
|
|
36
|
+
...PcElement.properties,
|
|
37
|
+
theme: {
|
|
38
|
+
type: String,
|
|
39
|
+
reflect: true
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
static styles = [
|
|
43
|
+
PcElement.styles,
|
|
44
|
+
unsafeCSS(ICON_CONTROLS_CSS),
|
|
45
|
+
css`
|
|
46
|
+
:host {
|
|
47
|
+
display: block;
|
|
48
|
+
}
|
|
49
|
+
fieldset {
|
|
50
|
+
margin: 0;
|
|
51
|
+
padding: 0;
|
|
52
|
+
border: 0;
|
|
53
|
+
min-width: 0;
|
|
54
|
+
color: var(--pc-text);
|
|
55
|
+
font-family: var(--pc-font);
|
|
56
|
+
font-size: var(--pc-font-size);
|
|
57
|
+
}
|
|
58
|
+
legend {
|
|
59
|
+
margin-bottom: var(--pc-space-1);
|
|
60
|
+
padding: 0;
|
|
61
|
+
}
|
|
62
|
+
/* As wide as the picker, with the options sharing the width */
|
|
63
|
+
pc-button-group {
|
|
64
|
+
display: flex;
|
|
65
|
+
}
|
|
66
|
+
pc-button-group::part(group) {
|
|
67
|
+
flex: 1;
|
|
68
|
+
}
|
|
69
|
+
/* One pill: the button group gives each option its corners */
|
|
70
|
+
.icon-toggle {
|
|
71
|
+
flex: 1;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
gap: 4px;
|
|
75
|
+
padding: 2px var(--pc-space-2);
|
|
76
|
+
border-radius: var(--pc-group-radius, var(--pc-radius-small));
|
|
77
|
+
}
|
|
78
|
+
/* The picked option's border shows over its neighbours' */
|
|
79
|
+
.icon-toggle:has(input:checked) {
|
|
80
|
+
z-index: 1;
|
|
81
|
+
color: var(--pc-accent-text);
|
|
82
|
+
}
|
|
83
|
+
.icon-toggle:has(input:focus-visible) {
|
|
84
|
+
z-index: 2;
|
|
85
|
+
}
|
|
86
|
+
`
|
|
87
|
+
];
|
|
88
|
+
/** The element whose `data-pc-theme` is shown and set (the page's root element by default) */
|
|
89
|
+
target;
|
|
90
|
+
constructor() {
|
|
91
|
+
super();
|
|
92
|
+
this.theme = "light";
|
|
93
|
+
}
|
|
94
|
+
connectedCallback() {
|
|
95
|
+
super.connectedCallback();
|
|
96
|
+
const current = this.themeTarget.dataset.pcTheme;
|
|
97
|
+
if (isTheme(current)) this.theme = current;
|
|
98
|
+
}
|
|
99
|
+
/** The element whose theme is shown and set */
|
|
100
|
+
get themeTarget() {
|
|
101
|
+
return this.target ?? document.documentElement;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Pick a theme: show it, set it on the target and tell listeners.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* picker.pick("auto");
|
|
108
|
+
*/
|
|
109
|
+
pick(theme) {
|
|
110
|
+
this.theme = theme;
|
|
111
|
+
this.themeTarget.dataset.pcTheme = theme;
|
|
112
|
+
emit(this, "change", theme);
|
|
113
|
+
}
|
|
114
|
+
render() {
|
|
115
|
+
return html`<fieldset>
|
|
116
|
+
<legend>${this.t("paintCanvas.theme.label")}</legend>
|
|
117
|
+
<pc-button-group joined>
|
|
118
|
+
${THEMES.map((theme) => html`<label class="icon-toggle" data-theme=${theme}>
|
|
119
|
+
<input
|
|
120
|
+
type="radio"
|
|
121
|
+
name="theme"
|
|
122
|
+
value=${theme}
|
|
123
|
+
.checked=${this.theme === theme}
|
|
124
|
+
@change=${() => this.pick(theme)}
|
|
125
|
+
/>
|
|
126
|
+
<img src=${this.iconUrl(THEME_ICONS[theme])} alt="" />
|
|
127
|
+
<span>${this.t(`paintCanvas.theme.${theme}`)}</span>
|
|
128
|
+
</label>`)}
|
|
129
|
+
</pc-button-group>
|
|
130
|
+
</fieldset>`;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
defineElement("pc-theme-picker", PcThemePicker);
|
|
134
|
+
export { PcThemePicker, THEMES, THEME_ICONS, isTheme };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type PropertyValues } from "lit";
|
|
2
|
+
import { PcElement } from "../../base";
|
|
3
|
+
import "../PcButton";
|
|
4
|
+
/** What a toast tells: a notice, an error or a success (each has its own colour) */
|
|
5
|
+
export type ToastKind = "info" | "error" | "success";
|
|
6
|
+
/** How long a toast shows before dismissing itself, unless told otherwise (milliseconds) */
|
|
7
|
+
export declare const TOAST_DURATION_MS = 5000;
|
|
8
|
+
/**
|
|
9
|
+
* A short message, e.g. "Saved", coloured by its kind: a notice (`info`), an `error` (red) or a `success` (green). An
|
|
10
|
+
* error is announced at once; others politely. It dismisses itself after `duration` milliseconds (0 keeps it), or with
|
|
11
|
+
* its dismiss button. With an `action`, it shows that button too. Fires `pc-action` and `pc-dismiss`. The buttons move
|
|
12
|
+
* under the message when there isn't room beside it. The implementer places it (e.g. near the bottom of the screen).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* html`<pc-toast message="Preset deleted" action="Undo" @pc-action=${restore} @pc-dismiss=${hide}></pc-toast>`
|
|
16
|
+
*/
|
|
17
|
+
export declare class PcToast extends PcElement {
|
|
18
|
+
static properties: {
|
|
19
|
+
message: {
|
|
20
|
+
type: StringConstructor;
|
|
21
|
+
};
|
|
22
|
+
kind: {
|
|
23
|
+
type: StringConstructor;
|
|
24
|
+
reflect: boolean;
|
|
25
|
+
};
|
|
26
|
+
action: {
|
|
27
|
+
type: StringConstructor;
|
|
28
|
+
};
|
|
29
|
+
duration: {
|
|
30
|
+
type: NumberConstructor;
|
|
31
|
+
};
|
|
32
|
+
translations: {
|
|
33
|
+
attribute: boolean;
|
|
34
|
+
};
|
|
35
|
+
icons: {
|
|
36
|
+
attribute: boolean;
|
|
37
|
+
};
|
|
38
|
+
theme: {
|
|
39
|
+
type: StringConstructor;
|
|
40
|
+
reflect: boolean;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
static styles: import("lit").CSSResultGroup[];
|
|
44
|
+
message: string;
|
|
45
|
+
/** "info" (default), "error" or "success" */
|
|
46
|
+
kind: ToastKind;
|
|
47
|
+
/** Label of an extra button (e.g. "Undo"), if any */
|
|
48
|
+
action?: string;
|
|
49
|
+
/** Milliseconds before it dismisses itself (0 keeps it until dismissed) */
|
|
50
|
+
duration: number;
|
|
51
|
+
private timer?;
|
|
52
|
+
constructor();
|
|
53
|
+
updated(changed: PropertyValues<this>): void;
|
|
54
|
+
disconnectedCallback(): void;
|
|
55
|
+
/** Tell listeners it should go */
|
|
56
|
+
dismiss(): void;
|
|
57
|
+
render(): import("lit").TemplateResult<1>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
2
|
+
import { css, html, nothing } from "lit";
|
|
3
|
+
// src/ui/elements/PcToast/index.ts
|
|
4
|
+
/** How long a toast shows before dismissing itself, unless told otherwise (milliseconds) */
|
|
5
|
+
var TOAST_DURATION_MS = 5e3;
|
|
6
|
+
/**
|
|
7
|
+
* A short message, e.g. "Saved", coloured by its kind: a notice (`info`), an `error` (red) or a `success` (green). An
|
|
8
|
+
* error is announced at once; others politely. It dismisses itself after `duration` milliseconds (0 keeps it), or with
|
|
9
|
+
* its dismiss button. With an `action`, it shows that button too. Fires `pc-action` and `pc-dismiss`. The buttons move
|
|
10
|
+
* under the message when there isn't room beside it. The implementer places it (e.g. near the bottom of the screen).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* html`<pc-toast message="Preset deleted" action="Undo" @pc-action=${restore} @pc-dismiss=${hide}></pc-toast>`
|
|
14
|
+
*/
|
|
15
|
+
var PcToast = class extends PcElement {
|
|
16
|
+
static properties = {
|
|
17
|
+
...PcElement.properties,
|
|
18
|
+
message: { type: String },
|
|
19
|
+
kind: {
|
|
20
|
+
type: String,
|
|
21
|
+
reflect: true
|
|
22
|
+
},
|
|
23
|
+
action: { type: String },
|
|
24
|
+
duration: { type: Number }
|
|
25
|
+
};
|
|
26
|
+
static styles = [PcElement.styles, css`
|
|
27
|
+
:host {
|
|
28
|
+
display: block;
|
|
29
|
+
}
|
|
30
|
+
.toast {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-wrap: wrap;
|
|
33
|
+
gap: var(--pc-space-2);
|
|
34
|
+
align-items: center;
|
|
35
|
+
padding: var(--pc-space-2) var(--pc-space-3);
|
|
36
|
+
border-radius: var(--pc-radius);
|
|
37
|
+
background: var(--pc-text);
|
|
38
|
+
color: var(--pc-surface);
|
|
39
|
+
box-shadow: var(--pc-shadow);
|
|
40
|
+
font-family: var(--pc-font);
|
|
41
|
+
font-size: var(--pc-font-size);
|
|
42
|
+
}
|
|
43
|
+
:host([kind="error"]) .toast {
|
|
44
|
+
background: var(--pc-red);
|
|
45
|
+
color: #ffffff;
|
|
46
|
+
}
|
|
47
|
+
:host([kind="success"]) .toast {
|
|
48
|
+
background: var(--pc-green);
|
|
49
|
+
color: #ffffff;
|
|
50
|
+
}
|
|
51
|
+
p {
|
|
52
|
+
/* Wide enough to read; the buttons wrap under it when there isn't room */
|
|
53
|
+
flex: 1 1 16em;
|
|
54
|
+
margin: 0;
|
|
55
|
+
}
|
|
56
|
+
.buttons {
|
|
57
|
+
display: flex;
|
|
58
|
+
gap: var(--pc-space-1);
|
|
59
|
+
}
|
|
60
|
+
/* The dismiss button's text is the toast's colour */
|
|
61
|
+
.buttons pc-button[variant="dismiss"] {
|
|
62
|
+
color: inherit;
|
|
63
|
+
}
|
|
64
|
+
pc-button[variant="dismiss"]::part(button) {
|
|
65
|
+
color: inherit;
|
|
66
|
+
}
|
|
67
|
+
`];
|
|
68
|
+
timer;
|
|
69
|
+
constructor() {
|
|
70
|
+
super();
|
|
71
|
+
this.message = "";
|
|
72
|
+
this.kind = "info";
|
|
73
|
+
this.duration = TOAST_DURATION_MS;
|
|
74
|
+
}
|
|
75
|
+
updated(changed) {
|
|
76
|
+
if (!changed.has("message") && !changed.has("duration")) return;
|
|
77
|
+
clearTimeout(this.timer);
|
|
78
|
+
if (this.duration > 0) this.timer = setTimeout(() => this.dismiss(), this.duration);
|
|
79
|
+
}
|
|
80
|
+
disconnectedCallback() {
|
|
81
|
+
super.disconnectedCallback();
|
|
82
|
+
clearTimeout(this.timer);
|
|
83
|
+
}
|
|
84
|
+
/** Tell listeners it should go */
|
|
85
|
+
dismiss() {
|
|
86
|
+
clearTimeout(this.timer);
|
|
87
|
+
emit(this, "pc-dismiss");
|
|
88
|
+
}
|
|
89
|
+
render() {
|
|
90
|
+
return html`<div
|
|
91
|
+
class="toast"
|
|
92
|
+
part="toast"
|
|
93
|
+
role=${this.kind === "error" ? "alert" : "status"}
|
|
94
|
+
>
|
|
95
|
+
<p part="message">${this.message}</p>
|
|
96
|
+
<div class="buttons">
|
|
97
|
+
${this.action ? html`<pc-button
|
|
98
|
+
variant="pill"
|
|
99
|
+
@click=${() => emit(this, "pc-action")}
|
|
100
|
+
>${this.action}</pc-button
|
|
101
|
+
>` : nothing}
|
|
102
|
+
<pc-button variant="dismiss" @click=${() => this.dismiss()}
|
|
103
|
+
>${this.t("paintCanvas.common.dismiss")}</pc-button
|
|
104
|
+
>
|
|
105
|
+
</div>
|
|
106
|
+
</div>`;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
defineElement("pc-toast", PcToast);
|
|
110
|
+
export { PcToast, TOAST_DURATION_MS };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PcElement } from "../../base";
|
|
2
|
+
/**
|
|
3
|
+
* An on/off switch with its text (the element's content) beside it, e.g. for settings. Fires `change` when the user
|
|
4
|
+
* turns it on or off.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* html`<pc-toggle-checkbox .checked=${pinchZoom} @change=${toggle}>Pinch to zoom</pc-toggle-checkbox>`
|
|
8
|
+
*/
|
|
9
|
+
export declare class PcToggleCheckbox extends PcElement {
|
|
10
|
+
static properties: {
|
|
11
|
+
checked: {
|
|
12
|
+
type: BooleanConstructor;
|
|
13
|
+
reflect: boolean;
|
|
14
|
+
};
|
|
15
|
+
disabled: {
|
|
16
|
+
type: BooleanConstructor;
|
|
17
|
+
reflect: boolean;
|
|
18
|
+
};
|
|
19
|
+
translations: {
|
|
20
|
+
attribute: boolean;
|
|
21
|
+
};
|
|
22
|
+
icons: {
|
|
23
|
+
attribute: boolean;
|
|
24
|
+
};
|
|
25
|
+
theme: {
|
|
26
|
+
type: StringConstructor;
|
|
27
|
+
reflect: boolean;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
static styles: import("lit").CSSResultGroup[];
|
|
31
|
+
checked: boolean;
|
|
32
|
+
disabled: boolean;
|
|
33
|
+
constructor();
|
|
34
|
+
/** Follow the user's change, and tell listeners */
|
|
35
|
+
private onChange;
|
|
36
|
+
render(): import("lit").TemplateResult<1>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
2
|
+
import { css, html } from "lit";
|
|
3
|
+
import { live } from "lit/directives/live.js";
|
|
4
|
+
// src/ui/elements/PcToggleCheckbox/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* An on/off switch with its text (the element's content) beside it, e.g. for settings. Fires `change` when the user
|
|
7
|
+
* turns it on or off.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* html`<pc-toggle-checkbox .checked=${pinchZoom} @change=${toggle}>Pinch to zoom</pc-toggle-checkbox>`
|
|
11
|
+
*/
|
|
12
|
+
var PcToggleCheckbox = class extends PcElement {
|
|
13
|
+
static properties = {
|
|
14
|
+
...PcElement.properties,
|
|
15
|
+
checked: {
|
|
16
|
+
type: Boolean,
|
|
17
|
+
reflect: true
|
|
18
|
+
},
|
|
19
|
+
disabled: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
reflect: true
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
static styles = [PcElement.styles, css`
|
|
25
|
+
:host {
|
|
26
|
+
display: flex;
|
|
27
|
+
}
|
|
28
|
+
label {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex: 1;
|
|
31
|
+
gap: var(--pc-space-2);
|
|
32
|
+
align-items: center;
|
|
33
|
+
color: var(--pc-text);
|
|
34
|
+
font-family: var(--pc-font);
|
|
35
|
+
font-size: var(--pc-font-size);
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
:host([disabled]) label {
|
|
39
|
+
opacity: 0.5;
|
|
40
|
+
cursor: default;
|
|
41
|
+
}
|
|
42
|
+
input {
|
|
43
|
+
position: relative;
|
|
44
|
+
flex: none;
|
|
45
|
+
width: 36px;
|
|
46
|
+
height: 20px;
|
|
47
|
+
margin: 0;
|
|
48
|
+
border-radius: var(--pc-radius-pill);
|
|
49
|
+
background: var(--pc-disabled);
|
|
50
|
+
appearance: none;
|
|
51
|
+
cursor: inherit;
|
|
52
|
+
}
|
|
53
|
+
input::before {
|
|
54
|
+
position: absolute;
|
|
55
|
+
top: 2px;
|
|
56
|
+
left: 2px;
|
|
57
|
+
width: 16px;
|
|
58
|
+
height: 16px;
|
|
59
|
+
border-radius: 50%;
|
|
60
|
+
background: #ffffff;
|
|
61
|
+
content: "";
|
|
62
|
+
transition: transform 0.15s;
|
|
63
|
+
}
|
|
64
|
+
input:checked {
|
|
65
|
+
background: var(--pc-accent);
|
|
66
|
+
}
|
|
67
|
+
input:checked::before {
|
|
68
|
+
transform: translateX(16px);
|
|
69
|
+
}
|
|
70
|
+
input:focus-visible {
|
|
71
|
+
outline: var(--pc-focus-width) solid var(--pc-focus);
|
|
72
|
+
outline-offset: 2px;
|
|
73
|
+
}
|
|
74
|
+
@media (prefers-reduced-motion: reduce) {
|
|
75
|
+
input::before {
|
|
76
|
+
transition: none;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`];
|
|
80
|
+
constructor() {
|
|
81
|
+
super();
|
|
82
|
+
this.checked = false;
|
|
83
|
+
this.disabled = false;
|
|
84
|
+
}
|
|
85
|
+
/** Follow the user's change, and tell listeners */
|
|
86
|
+
onChange(event) {
|
|
87
|
+
this.checked = event.target.checked;
|
|
88
|
+
emit(this, "change", { checked: this.checked });
|
|
89
|
+
}
|
|
90
|
+
render() {
|
|
91
|
+
return html`<label part="label">
|
|
92
|
+
<input
|
|
93
|
+
part="switch"
|
|
94
|
+
type="checkbox"
|
|
95
|
+
role="switch"
|
|
96
|
+
.checked=${live(this.checked)}
|
|
97
|
+
?disabled=${this.disabled}
|
|
98
|
+
@change=${this.onChange}
|
|
99
|
+
/>
|
|
100
|
+
<span><slot></slot></span>
|
|
101
|
+
</label>`;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
defineElement("pc-toggle-checkbox", PcToggleCheckbox);
|
|
105
|
+
export { PcToggleCheckbox };
|