@lvl99dotcom/paintcanvas 0.3.1 → 0.5.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/StrokeEngine/index.d.ts +2 -2
- package/dist/lib/brushes/StrokeEngine/index.js +26 -28
- 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/classes/BrushSettings/index.d.ts +53 -2
- package/dist/lib/classes/BrushSettings/index.js +85 -14
- package/dist/lib/classes/KeyboardShortcuts/index.d.ts +47 -7
- package/dist/lib/classes/KeyboardShortcuts/index.js +145 -20
- package/dist/lib/classes/PaintCanvas/index.d.ts +123 -27
- package/dist/lib/classes/PaintCanvas/index.js +208 -41
- package/dist/lib/classes/PaintCanvas/tool.d.ts +15 -0
- package/dist/lib/classes/PaintCanvas/tool.js +18 -0
- package/dist/lib/classes/Palette/index.d.ts +58 -0
- package/dist/lib/classes/Palette/index.js +92 -0
- package/dist/lib/classes/SettingsAutosave/index.d.ts +53 -0
- package/dist/lib/classes/SettingsAutosave/index.js +98 -0
- package/dist/lib/classes/ShortcutSettings/index.d.ts +63 -0
- package/dist/lib/classes/ShortcutSettings/index.js +110 -0
- package/dist/lib/classes/UiSettings/index.d.ts +68 -0
- package/dist/lib/classes/UiSettings/index.js +82 -0
- package/dist/lib/palette/index.d.ts +49 -0
- package/dist/lib/palette/index.js +82 -0
- package/dist/lib/palette/schema.d.ts +45 -0
- package/dist/lib/palette/schema.js +41 -0
- package/dist/lib/rendering/cursors/index.d.ts +2 -0
- package/dist/lib/rendering/cursors/index.js +3 -1
- package/dist/lib/rendering/sample/index.js +3 -2
- package/dist/lib/settings/index.d.ts +63 -0
- package/dist/lib/settings/index.js +93 -0
- package/dist/lib/settings/schema.d.ts +168 -0
- package/dist/lib/settings/schema.js +116 -0
- package/dist/lib/storage/index.d.ts +36 -5
- package/dist/lib/storage/index.js +87 -29
- package/dist/lib/utils/colour/index.d.ts +72 -0
- package/dist/lib/utils/colour/index.js +154 -0
- package/dist/lib/utils/shortcuts/index.d.ts +174 -11
- package/dist/lib/utils/shortcuts/index.js +391 -145
- package/dist/lib/validation/validators.generated.d.ts +5 -0
- package/dist/lib/validation/validators.generated.js +1040 -1
- package/dist/locales/en-GB.js +96 -3
- package/dist/locales/en-US.js +96 -3
- package/dist/locales/fr.js +96 -3
- package/dist/locales/ja.js +96 -3
- package/dist/locales/ko.js +96 -3
- package/dist/locales/zh-Hans.js +96 -3
- package/dist/locales/zh-Hant.js +96 -3
- package/dist/package.js +1 -1
- package/dist/testing/recordingCanvas.js +2 -1
- package/dist/ui/base/index.d.ts +2 -2
- 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 +57 -50
- package/dist/ui/elements/PaintCanvas/index.js +141 -174
- package/dist/ui/elements/PaintCanvas/style.js +1 -1
- package/dist/ui/elements/PcAppSettings/index.d.ts +59 -0
- package/dist/ui/elements/PcAppSettings/index.js +222 -0
- package/dist/ui/elements/PcBrushConfig/index.d.ts +9 -2
- package/dist/ui/elements/PcBrushConfig/index.js +47 -7
- 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 +73 -5
- package/dist/ui/elements/PcBrushTest/style.js +1 -1
- package/dist/ui/elements/PcCanvas/index.d.ts +22 -2
- package/dist/ui/elements/PcCanvas/index.js +60 -15
- package/dist/ui/elements/PcCanvasMap/style.js +1 -1
- package/dist/ui/elements/PcClipboardTools/index.d.ts +48 -0
- package/dist/ui/elements/PcClipboardTools/index.js +118 -0
- package/dist/ui/elements/PcColourPair/index.d.ts +43 -0
- package/dist/ui/elements/PcColourPair/index.js +125 -0
- package/dist/ui/elements/PcContextMenu/index.d.ts +71 -34
- package/dist/ui/elements/PcContextMenu/index.js +128 -97
- package/dist/ui/elements/PcInputSettings/index.d.ts +13 -0
- package/dist/ui/elements/PcInputSettings/index.js +16 -1
- package/dist/ui/elements/PcLayerItem/index.d.ts +13 -34
- package/dist/ui/elements/PcLayerItem/index.js +39 -91
- package/dist/ui/elements/PcLayerItem/style.js +1 -1
- package/dist/ui/elements/PcMenu/index.d.ts +138 -0
- package/dist/ui/elements/PcMenu/index.js +296 -0
- 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 +120 -0
- package/dist/ui/elements/PcPane/index.js +394 -0
- package/dist/ui/elements/PcPanel/index.d.ts +26 -8
- package/dist/ui/elements/PcPanel/index.js +76 -8
- package/dist/ui/elements/{PcBrushMenu → PcPanelBrushes}/index.d.ts +22 -21
- package/dist/ui/elements/{PcBrushMenu → PcPanelBrushes}/index.js +24 -57
- package/dist/ui/elements/PcPanelBrushes/style.js +3 -0
- package/dist/ui/elements/PcPanelColours/index.d.ts +171 -0
- package/dist/ui/elements/PcPanelColours/index.js +650 -0
- package/dist/ui/elements/PcPanelColours/style.js +3 -0
- package/dist/ui/elements/{PcLayersMenu → PcPanelLayers}/index.d.ts +17 -4
- package/dist/ui/elements/{PcLayersMenu → PcPanelLayers}/index.js +17 -10
- package/dist/ui/elements/PcPanelLayers/style.js +3 -0
- package/dist/ui/elements/PcPopover/index.d.ts +39 -1
- package/dist/ui/elements/PcPopover/index.js +72 -4
- package/dist/ui/elements/PcShortcutSettings/index.d.ts +69 -0
- package/dist/ui/elements/PcShortcutSettings/index.js +273 -0
- 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 +384 -319
- package/dist/ui/elements/PcToolSettings/style.js +1 -1
- package/dist/ui/elements/PcToolbar/index.d.ts +62 -12
- package/dist/ui/elements/PcToolbar/index.js +119 -57
- 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-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 +84 -72
- package/dist/ui/index.d.ts +13 -2
- package/dist/ui/index.js +16 -4
- package/dist/ui/layout/index.d.ts +9 -1
- package/dist/ui/layout/index.js +11 -2
- package/dist/ui/tokens/index.d.ts +5 -4
- package/dist/ui/tokens/index.js +15 -8
- package/locales/en-GB.json +96 -3
- package/locales/en-US.json +96 -3
- package/locales/fr.json +96 -3
- package/locales/ja.json +96 -3
- package/locales/ko.json +96 -3
- package/locales/zh-Hans.json +96 -3
- package/locales/zh-Hant.json +96 -3
- package/package.json +11 -4
- package/dist/ui/elements/PcBrushMenu/style.js +0 -3
- package/dist/ui/elements/PcLayersMenu/style.js +0 -3
- 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,120 @@
|
|
|
1
|
+
import { nothing, type PropertyValues, type TemplateResult } from "lit";
|
|
2
|
+
import { PcElement } from "../../base";
|
|
3
|
+
import { PcPanel } from "../PcPanel";
|
|
4
|
+
import { type SideMode } from "../../layout";
|
|
5
|
+
/** Which way a pane's start, middle and end run */
|
|
6
|
+
export type PaneOrientation = "vertical" | "horizontal";
|
|
7
|
+
/** Which edge of the layout a pane is on: panels opened from its rail, and its floating box, go the other way */
|
|
8
|
+
export type PaneEdge = "left" | "right" | "top" | "bottom";
|
|
9
|
+
/** Event fired when a floating pane is shown or collapsed (detail: `{ collapsed }`) */
|
|
10
|
+
export declare const PANE_COLLAPSE_EVENT = "pc-collapse";
|
|
11
|
+
/**
|
|
12
|
+
* An area where buttons and panels are shown or docked, e.g. a side of the `<paint-canvas>` layout. Its content goes in
|
|
13
|
+
* its `start`, `middle` and `end` slots (content without a slot goes at the start), which run down a `vertical` pane
|
|
14
|
+
* (the default) or across a `horizontal` one; the middle takes the space left.
|
|
15
|
+
*
|
|
16
|
+
* Its `mode` sets how it shows its panels (`PcPanel`s, e.g. `<pc-panel-layers>`):
|
|
17
|
+
* - `docked`: as they are.
|
|
18
|
+
* - `rail`: as a column of buttons (with each panel's icon, name and badge) that open one panel at a time over the
|
|
19
|
+
* canvas, beside the pane (away from its `edge`). Focus moves into the panel; Escape, a press outside it or its
|
|
20
|
+
* button again closes it, and focus goes back to the button.
|
|
21
|
+
* - `floating`: the pane floats over the canvas as a box that collapses to a button (`collapsed`, named with its
|
|
22
|
+
* `label`), firing `pc-collapse` when it's shown or collapsed.
|
|
23
|
+
* - `overlay`: a rail over the canvas, without a background: each button has its own, and presses between them reach
|
|
24
|
+
* the canvas. Its panels stay solid.
|
|
25
|
+
*
|
|
26
|
+
* Panes made for one purpose extend it and put their own content in its regions (see `renderStart`, `renderMiddle`
|
|
27
|
+
* and `renderEnd`), e.g. `<pc-toolbar>`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* html`<pc-pane edge="right" mode="rail" label="Panels"><pc-panel-layers .app=${app}></pc-panel-layers></pc-pane>`
|
|
31
|
+
*/
|
|
32
|
+
export declare class PcPane extends PcElement {
|
|
33
|
+
static properties: {
|
|
34
|
+
orientation: {
|
|
35
|
+
type: StringConstructor;
|
|
36
|
+
reflect: boolean;
|
|
37
|
+
};
|
|
38
|
+
mode: {
|
|
39
|
+
type: StringConstructor;
|
|
40
|
+
reflect: boolean;
|
|
41
|
+
};
|
|
42
|
+
edge: {
|
|
43
|
+
type: StringConstructor;
|
|
44
|
+
reflect: boolean;
|
|
45
|
+
};
|
|
46
|
+
label: {
|
|
47
|
+
type: StringConstructor;
|
|
48
|
+
};
|
|
49
|
+
collapsed: {
|
|
50
|
+
type: BooleanConstructor;
|
|
51
|
+
reflect: boolean;
|
|
52
|
+
};
|
|
53
|
+
openPanel: {
|
|
54
|
+
state: boolean;
|
|
55
|
+
};
|
|
56
|
+
translations: {
|
|
57
|
+
attribute: boolean;
|
|
58
|
+
};
|
|
59
|
+
icons: {
|
|
60
|
+
attribute: boolean;
|
|
61
|
+
};
|
|
62
|
+
theme: {
|
|
63
|
+
type: StringConstructor;
|
|
64
|
+
reflect: boolean;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
static styles: import("lit").CSSResultGroup[];
|
|
68
|
+
/** Which way its start, middle and end run (`vertical` by default) */
|
|
69
|
+
orientation: PaneOrientation;
|
|
70
|
+
/** How it shows its panels (`docked` by default) */
|
|
71
|
+
mode: SideMode;
|
|
72
|
+
/** Which edge of the layout it's on (`left` by default) */
|
|
73
|
+
edge: PaneEdge;
|
|
74
|
+
/** Names it, e.g. on its button when floating and collapsed */
|
|
75
|
+
label: string;
|
|
76
|
+
/** Whether it's collapsed to a button while floating (true until opened) */
|
|
77
|
+
collapsed: boolean;
|
|
78
|
+
/** The panel open from its rail, if any */
|
|
79
|
+
openPanel?: PcPanel;
|
|
80
|
+
/** The panels in it */
|
|
81
|
+
private panels;
|
|
82
|
+
/** The rail button that opened the open panel, to return focus to */
|
|
83
|
+
private opener?;
|
|
84
|
+
private readonly panelObserver;
|
|
85
|
+
private readonly onDocumentPointerDown;
|
|
86
|
+
private readonly onKeyDown;
|
|
87
|
+
constructor();
|
|
88
|
+
connectedCallback(): void;
|
|
89
|
+
disconnectedCallback(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Open a panel over the canvas from its rail button (closing any other), or close it if it's open. Focus moves into
|
|
92
|
+
* the panel: to the first thing in it that takes focus, or the panel itself.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* pane.togglePanel(pane.querySelector("pc-panel-layers"));
|
|
96
|
+
*/
|
|
97
|
+
togglePanel(panel: PcPanel, opener?: HTMLElement): void;
|
|
98
|
+
/**
|
|
99
|
+
* Close the panel open from the rail, moving focus back to its rail button if asked.
|
|
100
|
+
*/
|
|
101
|
+
closePanel(returnFocus: boolean): void;
|
|
102
|
+
/** Show or collapse the floating pane, telling listeners */
|
|
103
|
+
private toggleCollapsed;
|
|
104
|
+
/** Follow the panels slotted into it */
|
|
105
|
+
private onSlotChange;
|
|
106
|
+
/** Show the panels for the mode: hidden behind the rail (except the open one, beside the pane) or as they are */
|
|
107
|
+
private syncPanels;
|
|
108
|
+
protected updated(changed: PropertyValues<this>): void;
|
|
109
|
+
/** Content of its own at its start, before what's slotted there */
|
|
110
|
+
protected renderStart(): TemplateResult | typeof nothing;
|
|
111
|
+
/** Content of its own in its middle, before what's slotted there */
|
|
112
|
+
protected renderMiddle(): TemplateResult | typeof nothing;
|
|
113
|
+
/** Content of its own at its end, before what's slotted there */
|
|
114
|
+
protected renderEnd(): TemplateResult | typeof nothing;
|
|
115
|
+
/** The rail: a button per panel */
|
|
116
|
+
private renderRail;
|
|
117
|
+
/** The button that shows or collapses a floating pane */
|
|
118
|
+
private renderCollapse;
|
|
119
|
+
render(): TemplateResult<1>;
|
|
120
|
+
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { PcElement, defineElement, emit } from "../../base/index.js";
|
|
2
|
+
import { markDismissingPress } from "../../dismiss/index.js";
|
|
3
|
+
import { PcPanel } from "../PcPanel/index.js";
|
|
4
|
+
import { showsRail } from "../../layout/index.js";
|
|
5
|
+
import { css, html, nothing } from "lit";
|
|
6
|
+
// src/ui/elements/PcPane/index.ts
|
|
7
|
+
/** Event fired when a floating pane is shown or collapsed (detail: `{ collapsed }`) */
|
|
8
|
+
var PANE_COLLAPSE_EVENT = "pc-collapse";
|
|
9
|
+
/** Elements that can take keyboard focus */
|
|
10
|
+
var FOCUSABLE = "button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])";
|
|
11
|
+
/**
|
|
12
|
+
* An area where buttons and panels are shown or docked, e.g. a side of the `<paint-canvas>` layout. Its content goes in
|
|
13
|
+
* its `start`, `middle` and `end` slots (content without a slot goes at the start), which run down a `vertical` pane
|
|
14
|
+
* (the default) or across a `horizontal` one; the middle takes the space left.
|
|
15
|
+
*
|
|
16
|
+
* Its `mode` sets how it shows its panels (`PcPanel`s, e.g. `<pc-panel-layers>`):
|
|
17
|
+
* - `docked`: as they are.
|
|
18
|
+
* - `rail`: as a column of buttons (with each panel's icon, name and badge) that open one panel at a time over the
|
|
19
|
+
* canvas, beside the pane (away from its `edge`). Focus moves into the panel; Escape, a press outside it or its
|
|
20
|
+
* button again closes it, and focus goes back to the button.
|
|
21
|
+
* - `floating`: the pane floats over the canvas as a box that collapses to a button (`collapsed`, named with its
|
|
22
|
+
* `label`), firing `pc-collapse` when it's shown or collapsed.
|
|
23
|
+
* - `overlay`: a rail over the canvas, without a background: each button has its own, and presses between them reach
|
|
24
|
+
* the canvas. Its panels stay solid.
|
|
25
|
+
*
|
|
26
|
+
* Panes made for one purpose extend it and put their own content in its regions (see `renderStart`, `renderMiddle`
|
|
27
|
+
* and `renderEnd`), e.g. `<pc-toolbar>`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* html`<pc-pane edge="right" mode="rail" label="Panels"><pc-panel-layers .app=${app}></pc-panel-layers></pc-pane>`
|
|
31
|
+
*/
|
|
32
|
+
var PcPane = class extends PcElement {
|
|
33
|
+
static properties = {
|
|
34
|
+
...PcElement.properties,
|
|
35
|
+
orientation: {
|
|
36
|
+
type: String,
|
|
37
|
+
reflect: true
|
|
38
|
+
},
|
|
39
|
+
mode: {
|
|
40
|
+
type: String,
|
|
41
|
+
reflect: true
|
|
42
|
+
},
|
|
43
|
+
edge: {
|
|
44
|
+
type: String,
|
|
45
|
+
reflect: true
|
|
46
|
+
},
|
|
47
|
+
label: { type: String },
|
|
48
|
+
collapsed: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
reflect: true
|
|
51
|
+
},
|
|
52
|
+
openPanel: { state: true }
|
|
53
|
+
};
|
|
54
|
+
static styles = [PcElement.styles, css`
|
|
55
|
+
:host {
|
|
56
|
+
position: relative;
|
|
57
|
+
display: flex;
|
|
58
|
+
box-sizing: border-box;
|
|
59
|
+
min-width: 0;
|
|
60
|
+
min-height: 0;
|
|
61
|
+
font-family: var(--pc-font);
|
|
62
|
+
font-size: var(--pc-font-size);
|
|
63
|
+
}
|
|
64
|
+
:host([edge="right"]) {
|
|
65
|
+
flex-direction: row-reverse;
|
|
66
|
+
}
|
|
67
|
+
.regions {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex: 1;
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
min-width: 0;
|
|
72
|
+
min-height: 0;
|
|
73
|
+
}
|
|
74
|
+
:host([orientation="horizontal"]) .regions {
|
|
75
|
+
flex-direction: row;
|
|
76
|
+
}
|
|
77
|
+
.start,
|
|
78
|
+
.middle,
|
|
79
|
+
.end {
|
|
80
|
+
display: flex;
|
|
81
|
+
flex-direction: inherit;
|
|
82
|
+
}
|
|
83
|
+
/* The middle takes the space left, and gives it up first; the start and end keep their content's size */
|
|
84
|
+
.middle {
|
|
85
|
+
flex: 1;
|
|
86
|
+
min-width: 0;
|
|
87
|
+
min-height: 0;
|
|
88
|
+
}
|
|
89
|
+
.regions[hidden] {
|
|
90
|
+
display: none;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Rail: a column of buttons, one per panel, on the side facing the canvas */
|
|
94
|
+
.rail {
|
|
95
|
+
display: flex;
|
|
96
|
+
flex-direction: column;
|
|
97
|
+
gap: var(--pc-space-1);
|
|
98
|
+
padding: var(--pc-space-1);
|
|
99
|
+
border-inline: 1px solid var(--pc-border);
|
|
100
|
+
background: var(--pc-bar);
|
|
101
|
+
}
|
|
102
|
+
/* The same size as the toolbars' buttons (borders included) */
|
|
103
|
+
.rail button {
|
|
104
|
+
position: relative;
|
|
105
|
+
display: inline-flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
justify-content: center;
|
|
108
|
+
box-sizing: border-box;
|
|
109
|
+
width: var(--pc-side-button-size);
|
|
110
|
+
height: var(--pc-side-button-size);
|
|
111
|
+
padding: 0;
|
|
112
|
+
border: 1px solid transparent;
|
|
113
|
+
border-radius: var(--pc-radius-small);
|
|
114
|
+
background: transparent;
|
|
115
|
+
cursor: pointer;
|
|
116
|
+
}
|
|
117
|
+
.rail button:hover {
|
|
118
|
+
background: var(--pc-surface-hover);
|
|
119
|
+
}
|
|
120
|
+
.rail button[aria-expanded="true"] {
|
|
121
|
+
border-color: var(--pc-accent);
|
|
122
|
+
background: var(--pc-accent);
|
|
123
|
+
}
|
|
124
|
+
.rail button:focus-visible {
|
|
125
|
+
outline: var(--pc-focus-width) solid var(--pc-focus);
|
|
126
|
+
}
|
|
127
|
+
.rail img {
|
|
128
|
+
width: var(--pc-side-icon-size);
|
|
129
|
+
height: var(--pc-side-icon-size);
|
|
130
|
+
filter: var(--pc-icon-filter);
|
|
131
|
+
}
|
|
132
|
+
.rail .badge {
|
|
133
|
+
position: absolute;
|
|
134
|
+
top: -2px;
|
|
135
|
+
right: -2px;
|
|
136
|
+
width: 10px;
|
|
137
|
+
height: 10px;
|
|
138
|
+
border: 2px solid var(--pc-bar);
|
|
139
|
+
border-radius: 50%;
|
|
140
|
+
background: var(--pc-red);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Overlay: the rail over the canvas without a background, so only its buttons (each with its own) take presses */
|
|
144
|
+
:host([mode="overlay"]) {
|
|
145
|
+
pointer-events: none;
|
|
146
|
+
}
|
|
147
|
+
:host([mode="overlay"]) .rail {
|
|
148
|
+
border-inline: 0;
|
|
149
|
+
background: transparent;
|
|
150
|
+
}
|
|
151
|
+
:host([mode="overlay"]) .rail button,
|
|
152
|
+
:host([mode="overlay"]) ::slotted(*) {
|
|
153
|
+
pointer-events: auto;
|
|
154
|
+
}
|
|
155
|
+
:host([mode="overlay"]) .rail button {
|
|
156
|
+
border-color: var(--pc-border);
|
|
157
|
+
background: var(--pc-surface-raised);
|
|
158
|
+
box-shadow: var(--pc-shadow);
|
|
159
|
+
}
|
|
160
|
+
:host([mode="overlay"]) .rail button:hover {
|
|
161
|
+
background: var(--pc-surface-hover);
|
|
162
|
+
}
|
|
163
|
+
:host([mode="overlay"]) .rail button[aria-expanded="true"] {
|
|
164
|
+
border-color: var(--pc-accent);
|
|
165
|
+
background: var(--pc-accent);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Floating: the pane floats over the canvas as a box, and collapses to a button */
|
|
169
|
+
:host([mode="floating"]) {
|
|
170
|
+
position: absolute;
|
|
171
|
+
z-index: 5;
|
|
172
|
+
top: var(--pc-space-2);
|
|
173
|
+
bottom: var(--pc-space-2);
|
|
174
|
+
flex-direction: column;
|
|
175
|
+
gap: var(--pc-space-1);
|
|
176
|
+
max-width: var(--pc-floating-panel-width, min(360px, 85vw));
|
|
177
|
+
border-radius: var(--pc-radius);
|
|
178
|
+
background: var(--pc-surface-raised);
|
|
179
|
+
box-shadow: var(--pc-shadow);
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
}
|
|
182
|
+
:host([mode="floating"]:not([edge="right"])) {
|
|
183
|
+
left: var(--pc-space-2);
|
|
184
|
+
}
|
|
185
|
+
:host([mode="floating"][edge="right"]) {
|
|
186
|
+
right: var(--pc-space-2);
|
|
187
|
+
}
|
|
188
|
+
:host([mode="floating"][collapsed]) {
|
|
189
|
+
bottom: auto;
|
|
190
|
+
}
|
|
191
|
+
.collapse {
|
|
192
|
+
align-self: flex-end;
|
|
193
|
+
min-width: var(--pc-control-size);
|
|
194
|
+
min-height: var(--pc-control-size);
|
|
195
|
+
border: 0;
|
|
196
|
+
background: transparent;
|
|
197
|
+
color: var(--pc-text);
|
|
198
|
+
font-size: 18px;
|
|
199
|
+
cursor: pointer;
|
|
200
|
+
}
|
|
201
|
+
.collapse:focus-visible {
|
|
202
|
+
outline: var(--pc-focus-width) solid var(--pc-focus);
|
|
203
|
+
}
|
|
204
|
+
`];
|
|
205
|
+
/** The panels in it */
|
|
206
|
+
panels = [];
|
|
207
|
+
/** The rail button that opened the open panel, to return focus to */
|
|
208
|
+
opener;
|
|
209
|
+
panelObserver = new MutationObserver(() => this.requestUpdate());
|
|
210
|
+
onDocumentPointerDown = (event) => {
|
|
211
|
+
const panel = this.openPanel;
|
|
212
|
+
if (!panel) return;
|
|
213
|
+
const path = event.composedPath();
|
|
214
|
+
if (path.includes(panel) || this.opener && path.includes(this.opener)) return;
|
|
215
|
+
markDismissingPress(event);
|
|
216
|
+
this.closePanel(false);
|
|
217
|
+
};
|
|
218
|
+
onKeyDown = (event) => {
|
|
219
|
+
if (event.key !== "Escape" || !this.openPanel) return;
|
|
220
|
+
event.preventDefault();
|
|
221
|
+
this.closePanel(true);
|
|
222
|
+
};
|
|
223
|
+
constructor() {
|
|
224
|
+
super();
|
|
225
|
+
this.orientation = "vertical";
|
|
226
|
+
this.mode = "docked";
|
|
227
|
+
this.edge = "left";
|
|
228
|
+
this.label = "";
|
|
229
|
+
this.collapsed = true;
|
|
230
|
+
}
|
|
231
|
+
connectedCallback() {
|
|
232
|
+
super.connectedCallback();
|
|
233
|
+
this.panelObserver.observe(this, {
|
|
234
|
+
subtree: true,
|
|
235
|
+
attributes: true,
|
|
236
|
+
attributeFilter: [
|
|
237
|
+
"icon",
|
|
238
|
+
"label",
|
|
239
|
+
"badge"
|
|
240
|
+
]
|
|
241
|
+
});
|
|
242
|
+
this.addEventListener("keydown", this.onKeyDown);
|
|
243
|
+
document.addEventListener("pointerdown", this.onDocumentPointerDown, true);
|
|
244
|
+
}
|
|
245
|
+
disconnectedCallback() {
|
|
246
|
+
super.disconnectedCallback();
|
|
247
|
+
this.panelObserver.disconnect();
|
|
248
|
+
this.removeEventListener("keydown", this.onKeyDown);
|
|
249
|
+
document.removeEventListener("pointerdown", this.onDocumentPointerDown, true);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Open a panel over the canvas from its rail button (closing any other), or close it if it's open. Focus moves into
|
|
253
|
+
* the panel: to the first thing in it that takes focus, or the panel itself.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* pane.togglePanel(pane.querySelector("pc-panel-layers"));
|
|
257
|
+
*/
|
|
258
|
+
togglePanel(panel, opener) {
|
|
259
|
+
if (this.openPanel === panel) {
|
|
260
|
+
this.closePanel(true);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (this.openPanel) this.closePanel(false);
|
|
264
|
+
this.openPanel = panel;
|
|
265
|
+
this.opener = opener;
|
|
266
|
+
this.syncPanels();
|
|
267
|
+
const focusable = panel.querySelector(FOCUSABLE);
|
|
268
|
+
if (focusable) focusable.focus();
|
|
269
|
+
else {
|
|
270
|
+
panel.tabIndex = -1;
|
|
271
|
+
panel.focus();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Close the panel open from the rail, moving focus back to its rail button if asked.
|
|
276
|
+
*/
|
|
277
|
+
closePanel(returnFocus) {
|
|
278
|
+
if (!this.openPanel) return;
|
|
279
|
+
this.openPanel = void 0;
|
|
280
|
+
this.syncPanels();
|
|
281
|
+
if (returnFocus) this.opener?.focus();
|
|
282
|
+
this.opener = void 0;
|
|
283
|
+
}
|
|
284
|
+
/** Show or collapse the floating pane, telling listeners */
|
|
285
|
+
toggleCollapsed() {
|
|
286
|
+
this.collapsed = !this.collapsed;
|
|
287
|
+
emit(this, PANE_COLLAPSE_EVENT, { collapsed: this.collapsed });
|
|
288
|
+
}
|
|
289
|
+
/** Follow the panels slotted into it */
|
|
290
|
+
onSlotChange() {
|
|
291
|
+
this.panels = [...this.renderRoot.querySelectorAll("slot")].flatMap((slot) => slot.assignedElements({ flatten: true }).filter((element) => element instanceof PcPanel));
|
|
292
|
+
if (this.openPanel && !this.panels.includes(this.openPanel)) this.closePanel(false);
|
|
293
|
+
this.syncPanels();
|
|
294
|
+
this.requestUpdate();
|
|
295
|
+
}
|
|
296
|
+
/** Show the panels for the mode: hidden behind the rail (except the open one, beside the pane) or as they are */
|
|
297
|
+
syncPanels() {
|
|
298
|
+
const rail = showsRail(this.mode);
|
|
299
|
+
for (const panel of this.panels) {
|
|
300
|
+
panel.toggleAttribute("data-pc-rail", rail);
|
|
301
|
+
if (rail && panel === this.openPanel) panel.setAttribute("data-pc-open", this.edge);
|
|
302
|
+
else panel.removeAttribute("data-pc-open");
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
updated(changed) {
|
|
306
|
+
if (!changed.has("mode") && !changed.has("edge")) return;
|
|
307
|
+
if (!showsRail(this.mode)) this.closePanel(false);
|
|
308
|
+
this.syncPanels();
|
|
309
|
+
}
|
|
310
|
+
/** Content of its own at its start, before what's slotted there */
|
|
311
|
+
renderStart() {
|
|
312
|
+
return nothing;
|
|
313
|
+
}
|
|
314
|
+
/** Content of its own in its middle, before what's slotted there */
|
|
315
|
+
renderMiddle() {
|
|
316
|
+
return nothing;
|
|
317
|
+
}
|
|
318
|
+
/** Content of its own at its end, before what's slotted there */
|
|
319
|
+
renderEnd() {
|
|
320
|
+
return nothing;
|
|
321
|
+
}
|
|
322
|
+
/** The rail: a button per panel */
|
|
323
|
+
renderRail() {
|
|
324
|
+
if (!showsRail(this.mode) || this.panels.length === 0) return nothing;
|
|
325
|
+
return html`<div
|
|
326
|
+
class="rail"
|
|
327
|
+
part="rail"
|
|
328
|
+
role="toolbar"
|
|
329
|
+
aria-orientation="vertical"
|
|
330
|
+
aria-label=${this.label || nothing}
|
|
331
|
+
>
|
|
332
|
+
${this.panels.map((panel) => {
|
|
333
|
+
const label = panel.panelLabel;
|
|
334
|
+
return html`<button
|
|
335
|
+
type="button"
|
|
336
|
+
title=${label}
|
|
337
|
+
aria-label=${panel.badge ? this.t("paintCanvas.layout.new", { name: label }) : label}
|
|
338
|
+
aria-expanded=${String(this.openPanel === panel)}
|
|
339
|
+
@click=${(event) => this.togglePanel(panel, event.currentTarget)}
|
|
340
|
+
>
|
|
341
|
+
<img src=${this.iconUrl(panel.panelIcon)} alt="" />
|
|
342
|
+
${panel.badge ? html`<span class="badge"></span>` : nothing}
|
|
343
|
+
</button>`;
|
|
344
|
+
})}
|
|
345
|
+
</div>`;
|
|
346
|
+
}
|
|
347
|
+
/** The button that shows or collapses a floating pane */
|
|
348
|
+
renderCollapse() {
|
|
349
|
+
if (this.mode !== "floating") return nothing;
|
|
350
|
+
const collapsed = this.collapsed;
|
|
351
|
+
const arrows = this.edge === "right" ? ["«", "»"] : ["»", "«"];
|
|
352
|
+
return html`<button
|
|
353
|
+
type="button"
|
|
354
|
+
class="collapse"
|
|
355
|
+
part="collapse"
|
|
356
|
+
aria-expanded=${String(!collapsed)}
|
|
357
|
+
aria-label=${this.t(collapsed ? "paintCanvas.layout.show" : "paintCanvas.layout.hide", { name: this.label })}
|
|
358
|
+
@click=${this.toggleCollapsed}
|
|
359
|
+
>
|
|
360
|
+
${collapsed ? arrows[0] : arrows[1]}
|
|
361
|
+
</button>`;
|
|
362
|
+
}
|
|
363
|
+
render() {
|
|
364
|
+
return html`${this.renderCollapse()}
|
|
365
|
+
<div
|
|
366
|
+
class="regions"
|
|
367
|
+
part="regions"
|
|
368
|
+
?hidden=${this.mode === "floating" && this.collapsed}
|
|
369
|
+
>
|
|
370
|
+
<div class="start" part="start">
|
|
371
|
+
${this.renderStart()}<slot
|
|
372
|
+
name="start"
|
|
373
|
+
@slotchange=${this.onSlotChange}
|
|
374
|
+
></slot
|
|
375
|
+
><slot @slotchange=${this.onSlotChange}></slot>
|
|
376
|
+
</div>
|
|
377
|
+
<div class="middle" part="middle">
|
|
378
|
+
${this.renderMiddle()}<slot
|
|
379
|
+
name="middle"
|
|
380
|
+
@slotchange=${this.onSlotChange}
|
|
381
|
+
></slot>
|
|
382
|
+
</div>
|
|
383
|
+
<div class="end" part="end">
|
|
384
|
+
${this.renderEnd()}<slot
|
|
385
|
+
name="end"
|
|
386
|
+
@slotchange=${this.onSlotChange}
|
|
387
|
+
></slot>
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
${this.renderRail()}`;
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
defineElement("pc-pane", PcPane);
|
|
394
|
+
export { PANE_COLLAPSE_EVENT, PcPane };
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
import { nothing, type TemplateResult } from "lit";
|
|
1
2
|
import { PcElement } from "../../base";
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* A panel: a box of settings or content for one purpose, docked in a `<pc-pane>` or floating over the canvas. It has
|
|
5
|
+
* `header`, `body` and `footer` slots; content without a slot goes in the body. It names its region with its `label`
|
|
6
|
+
* for screen readers.
|
|
7
|
+
*
|
|
8
|
+
* Its `icon`, `label` and `badge` are what a pane shows for it when the pane narrows to a rail of buttons; the badge is
|
|
9
|
+
* a dot meaning something new (e.g. unread messages). It's 290px wide (`--pc-panel-width`), and in every layout it's
|
|
10
|
+
* never wider than 290px (`--pc-panel-max-width`) or the space it has.
|
|
11
|
+
*
|
|
12
|
+
* Panels made for one purpose extend `PcPanel`, so they share its look: e.g. `<pc-panel-layers>`,
|
|
13
|
+
* `<pc-panel-brushes>` and `<pc-panel-colours>`. They put their own content in the body (see `renderBody`), and give
|
|
14
|
+
* their own `defaultLabel` and `defaultIcon`.
|
|
7
15
|
*
|
|
8
16
|
* @example
|
|
9
|
-
* html`<pc-panel
|
|
17
|
+
* html`<pc-panel icon="chat" label="Chat"><my-chat></my-chat></pc-panel>`
|
|
10
18
|
*/
|
|
11
19
|
export declare class PcPanel extends PcElement {
|
|
12
20
|
static properties: {
|
|
@@ -32,12 +40,22 @@ export declare class PcPanel extends PcElement {
|
|
|
32
40
|
};
|
|
33
41
|
};
|
|
34
42
|
static styles: import("lit").CSSResultGroup[];
|
|
35
|
-
/** Name of the icon for its rail button */
|
|
43
|
+
/** Name of the icon for its rail button (`defaultIcon` if not given) */
|
|
36
44
|
icon: string;
|
|
37
|
-
/** Names the panel
|
|
45
|
+
/** Names the panel: its region and rail button (`defaultLabel` if not given) */
|
|
38
46
|
label: string;
|
|
39
47
|
/** Whether there's something new in it */
|
|
40
48
|
badge: boolean;
|
|
41
49
|
constructor();
|
|
42
|
-
|
|
50
|
+
/** The icon a panel made for a purpose shows on its rail button when none is given */
|
|
51
|
+
protected get defaultIcon(): string;
|
|
52
|
+
/** The name a panel made for a purpose has when none is given, in the chosen language */
|
|
53
|
+
protected get defaultLabel(): string;
|
|
54
|
+
/** The icon shown on its rail button */
|
|
55
|
+
get panelIcon(): string;
|
|
56
|
+
/** The panel's name, for its region and rail button */
|
|
57
|
+
get panelLabel(): string;
|
|
58
|
+
/** The panel's own body content, before what's slotted into its body (none for a plain `<pc-panel>`) */
|
|
59
|
+
protected renderBody(): TemplateResult | typeof nothing;
|
|
60
|
+
render(): TemplateResult<1>;
|
|
43
61
|
}
|
|
@@ -2,13 +2,20 @@ import { PcElement, defineElement } from "../../base/index.js";
|
|
|
2
2
|
import { css, html, nothing } from "lit";
|
|
3
3
|
// src/ui/elements/PcPanel/index.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* A panel: a box of settings or content for one purpose, docked in a `<pc-pane>` or floating over the canvas. It has
|
|
6
|
+
* `header`, `body` and `footer` slots; content without a slot goes in the body. It names its region with its `label`
|
|
7
|
+
* for screen readers.
|
|
8
|
+
*
|
|
9
|
+
* Its `icon`, `label` and `badge` are what a pane shows for it when the pane narrows to a rail of buttons; the badge is
|
|
10
|
+
* a dot meaning something new (e.g. unread messages). It's 290px wide (`--pc-panel-width`), and in every layout it's
|
|
11
|
+
* never wider than 290px (`--pc-panel-max-width`) or the space it has.
|
|
12
|
+
*
|
|
13
|
+
* Panels made for one purpose extend `PcPanel`, so they share its look: e.g. `<pc-panel-layers>`,
|
|
14
|
+
* `<pc-panel-brushes>` and `<pc-panel-colours>`. They put their own content in the body (see `renderBody`), and give
|
|
15
|
+
* their own `defaultLabel` and `defaultIcon`.
|
|
9
16
|
*
|
|
10
17
|
* @example
|
|
11
|
-
* html`<pc-panel
|
|
18
|
+
* html`<pc-panel icon="chat" label="Chat"><my-chat></my-chat></pc-panel>`
|
|
12
19
|
*/
|
|
13
20
|
var PcPanel = class extends PcElement {
|
|
14
21
|
static properties = {
|
|
@@ -23,10 +30,38 @@ var PcPanel = class extends PcElement {
|
|
|
23
30
|
static styles = [PcElement.styles, css`
|
|
24
31
|
:host {
|
|
25
32
|
display: flex;
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
width: var(--pc-panel-width, var(--pc-panel-default-width, 290px));
|
|
26
35
|
min-width: 0;
|
|
27
|
-
max-width: var(--pc-panel-max-width, 290px);
|
|
36
|
+
max-width: min(100%, var(--pc-panel-max-width, 290px));
|
|
28
37
|
min-height: 0;
|
|
38
|
+
max-height: 100%;
|
|
29
39
|
flex-direction: column;
|
|
40
|
+
/* Light grey, like the bars */
|
|
41
|
+
background: var(--pc-bar);
|
|
42
|
+
color: var(--pc-text);
|
|
43
|
+
box-shadow: var(--pc-shadow);
|
|
44
|
+
font-family: var(--pc-font);
|
|
45
|
+
font-size: var(--pc-font-size);
|
|
46
|
+
}
|
|
47
|
+
/* In a pane's rail (set by the pane): hidden until opened from its button, then over the canvas beside the pane,
|
|
48
|
+
as tall as its content needs (at most 90% of the window's height, and never taller than the pane) */
|
|
49
|
+
:host([data-pc-rail]:not([data-pc-open])) {
|
|
50
|
+
display: none;
|
|
51
|
+
}
|
|
52
|
+
:host([data-pc-open]) {
|
|
53
|
+
position: absolute;
|
|
54
|
+
z-index: 5;
|
|
55
|
+
top: 0;
|
|
56
|
+
/* Its usual width, kept within the window (the pane it opens from is narrower than it) */
|
|
57
|
+
max-width: min(var(--pc-panel-max-width, 290px), 85vw);
|
|
58
|
+
max-height: min(90vh, 100%);
|
|
59
|
+
}
|
|
60
|
+
:host([data-pc-open="left"]) {
|
|
61
|
+
left: 100%;
|
|
62
|
+
}
|
|
63
|
+
:host([data-pc-open="right"]) {
|
|
64
|
+
right: 100%;
|
|
30
65
|
}
|
|
31
66
|
section {
|
|
32
67
|
display: flex;
|
|
@@ -34,6 +69,15 @@ var PcPanel = class extends PcElement {
|
|
|
34
69
|
min-height: 0;
|
|
35
70
|
flex-direction: column;
|
|
36
71
|
}
|
|
72
|
+
.body {
|
|
73
|
+
display: flex;
|
|
74
|
+
flex: 1;
|
|
75
|
+
min-height: 0;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
gap: var(--pc-space-2);
|
|
78
|
+
padding: var(--pc-space-2);
|
|
79
|
+
overflow: auto;
|
|
80
|
+
}
|
|
37
81
|
`];
|
|
38
82
|
constructor() {
|
|
39
83
|
super();
|
|
@@ -41,9 +85,33 @@ var PcPanel = class extends PcElement {
|
|
|
41
85
|
this.label = "";
|
|
42
86
|
this.badge = false;
|
|
43
87
|
}
|
|
88
|
+
/** The icon a panel made for a purpose shows on its rail button when none is given */
|
|
89
|
+
get defaultIcon() {
|
|
90
|
+
return "";
|
|
91
|
+
}
|
|
92
|
+
/** The name a panel made for a purpose has when none is given, in the chosen language */
|
|
93
|
+
get defaultLabel() {
|
|
94
|
+
return "";
|
|
95
|
+
}
|
|
96
|
+
/** The icon shown on its rail button */
|
|
97
|
+
get panelIcon() {
|
|
98
|
+
return this.icon || this.defaultIcon;
|
|
99
|
+
}
|
|
100
|
+
/** The panel's name, for its region and rail button */
|
|
101
|
+
get panelLabel() {
|
|
102
|
+
return this.label || this.defaultLabel;
|
|
103
|
+
}
|
|
104
|
+
/** The panel's own body content, before what's slotted into its body (none for a plain `<pc-panel>`) */
|
|
105
|
+
renderBody() {
|
|
106
|
+
return nothing;
|
|
107
|
+
}
|
|
44
108
|
render() {
|
|
45
|
-
return html`<section part="panel" aria-label=${this.
|
|
46
|
-
<slot></slot>
|
|
109
|
+
return html`<section part="panel" aria-label=${this.panelLabel || nothing}>
|
|
110
|
+
<slot name="header"></slot>
|
|
111
|
+
<div class="body" part="body">
|
|
112
|
+
${this.renderBody()}<slot name="body"><slot></slot></slot>
|
|
113
|
+
</div>
|
|
114
|
+
<slot name="footer"></slot>
|
|
47
115
|
</section>`;
|
|
48
116
|
}
|
|
49
117
|
};
|