@lvl99dotcom/paintcanvas 0.3.0 → 0.4.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.
Files changed (98) hide show
  1. package/README.md +1 -1
  2. package/dist/lib/brushes/StrokeEngine/index.d.ts +2 -2
  3. package/dist/lib/brushes/StrokeEngine/index.js +26 -28
  4. package/dist/lib/classes/BrushSettings/index.d.ts +24 -0
  5. package/dist/lib/classes/BrushSettings/index.js +35 -1
  6. package/dist/lib/classes/KeyboardShortcuts/index.d.ts +17 -6
  7. package/dist/lib/classes/KeyboardShortcuts/index.js +81 -18
  8. package/dist/lib/classes/PaintCanvas/index.d.ts +77 -27
  9. package/dist/lib/classes/PaintCanvas/index.js +143 -42
  10. package/dist/lib/classes/PaintCanvas/tool.d.ts +15 -0
  11. package/dist/lib/classes/PaintCanvas/tool.js +18 -0
  12. package/dist/lib/classes/Palette/index.d.ts +58 -0
  13. package/dist/lib/classes/Palette/index.js +92 -0
  14. package/dist/lib/classes/SettingsAutosave/index.d.ts +52 -0
  15. package/dist/lib/classes/SettingsAutosave/index.js +96 -0
  16. package/dist/lib/classes/ShortcutSettings/index.d.ts +63 -0
  17. package/dist/lib/classes/ShortcutSettings/index.js +110 -0
  18. package/dist/lib/palette/index.d.ts +49 -0
  19. package/dist/lib/palette/index.js +82 -0
  20. package/dist/lib/palette/schema.d.ts +45 -0
  21. package/dist/lib/palette/schema.js +41 -0
  22. package/dist/lib/rendering/cursors/index.d.ts +2 -0
  23. package/dist/lib/rendering/cursors/index.js +3 -1
  24. package/dist/lib/rendering/sample/index.js +3 -2
  25. package/dist/lib/settings/index.d.ts +63 -0
  26. package/dist/lib/settings/index.js +91 -0
  27. package/dist/lib/settings/schema.d.ts +150 -0
  28. package/dist/lib/settings/schema.js +102 -0
  29. package/dist/lib/storage/index.d.ts +36 -5
  30. package/dist/lib/storage/index.js +87 -29
  31. package/dist/lib/utils/colour/index.d.ts +72 -0
  32. package/dist/lib/utils/colour/index.js +154 -0
  33. package/dist/lib/utils/shortcuts/index.d.ts +174 -11
  34. package/dist/lib/utils/shortcuts/index.js +391 -145
  35. package/dist/lib/validation/validators.generated.d.ts +5 -0
  36. package/dist/lib/validation/validators.generated.js +872 -1
  37. package/dist/locales/en-GB.js +87 -1
  38. package/dist/locales/en-US.js +87 -1
  39. package/dist/locales/fr.js +87 -1
  40. package/dist/locales/ja.js +87 -1
  41. package/dist/locales/ko.js +87 -1
  42. package/dist/locales/zh-Hans.js +87 -1
  43. package/dist/locales/zh-Hant.js +87 -1
  44. package/dist/package.js +1 -1
  45. package/dist/ui/elements/PaintCanvas/index.d.ts +49 -47
  46. package/dist/ui/elements/PaintCanvas/index.js +128 -169
  47. package/dist/ui/elements/PaintCanvas/style.js +1 -1
  48. package/dist/ui/elements/PcAppSettings/index.d.ts +59 -0
  49. package/dist/ui/elements/PcAppSettings/index.js +222 -0
  50. package/dist/ui/elements/PcBrushConfig/index.js +1 -0
  51. package/dist/ui/elements/PcButton/index.js +1 -0
  52. package/dist/ui/elements/PcCanvas/index.d.ts +1 -1
  53. package/dist/ui/elements/PcCanvas/index.js +7 -5
  54. package/dist/ui/elements/PcColourPair/index.d.ts +43 -0
  55. package/dist/ui/elements/PcColourPair/index.js +125 -0
  56. package/dist/ui/elements/PcContextMenu/index.d.ts +70 -33
  57. package/dist/ui/elements/PcContextMenu/index.js +128 -97
  58. package/dist/ui/elements/PcDialog/index.js +1 -0
  59. package/dist/ui/elements/PcIconToggle/index.js +1 -0
  60. package/dist/ui/elements/PcLayerItem/index.d.ts +13 -34
  61. package/dist/ui/elements/PcLayerItem/index.js +39 -91
  62. package/dist/ui/elements/PcLayerItem/style.js +1 -1
  63. package/dist/ui/elements/PcMenu/index.d.ts +93 -0
  64. package/dist/ui/elements/PcMenu/index.js +204 -0
  65. package/dist/ui/elements/PcPane/index.d.ts +118 -0
  66. package/dist/ui/elements/PcPane/index.js +357 -0
  67. package/dist/ui/elements/PcPanel/index.d.ts +26 -8
  68. package/dist/ui/elements/PcPanel/index.js +76 -8
  69. package/dist/ui/elements/{PcBrushMenu → PcPanelBrushes}/index.d.ts +20 -6
  70. package/dist/ui/elements/{PcBrushMenu → PcPanelBrushes}/index.js +20 -15
  71. package/dist/ui/elements/PcPanelBrushes/style.js +3 -0
  72. package/dist/ui/elements/PcPanelColours/index.d.ts +171 -0
  73. package/dist/ui/elements/PcPanelColours/index.js +650 -0
  74. package/dist/ui/elements/PcPanelColours/style.js +3 -0
  75. package/dist/ui/elements/{PcLayersMenu → PcPanelLayers}/index.d.ts +17 -4
  76. package/dist/ui/elements/{PcLayersMenu → PcPanelLayers}/index.js +17 -10
  77. package/dist/ui/elements/PcPanelLayers/style.js +3 -0
  78. package/dist/ui/elements/PcShortcutSettings/index.d.ts +69 -0
  79. package/dist/ui/elements/PcShortcutSettings/index.js +273 -0
  80. package/dist/ui/elements/PcThemePicker/index.js +1 -0
  81. package/dist/ui/elements/PcToast/index.js +1 -0
  82. package/dist/ui/elements/PcToolSettings/index.js +2 -1
  83. package/dist/ui/elements/PcToolbar/index.d.ts +47 -12
  84. package/dist/ui/elements/PcToolbar/index.js +77 -56
  85. package/dist/ui/elements/PcToolbar/style.js +1 -1
  86. package/dist/ui/index.d.ts +7 -1
  87. package/dist/ui/index.js +8 -2
  88. package/dist/ui/tokens/index.js +3 -1
  89. package/locales/en-GB.json +87 -1
  90. package/locales/en-US.json +87 -1
  91. package/locales/fr.json +87 -1
  92. package/locales/ja.json +87 -1
  93. package/locales/ko.json +87 -1
  94. package/locales/zh-Hans.json +87 -1
  95. package/locales/zh-Hant.json +87 -1
  96. package/package.json +1 -1
  97. package/dist/ui/elements/PcBrushMenu/style.js +0 -3
  98. package/dist/ui/elements/PcLayersMenu/style.js +0 -3
@@ -1,13 +1,14 @@
1
1
  import style_default from "./style.js";
2
2
  import { NO_TEXT_SELECTION_CSS, PILLS_CSS, WINDOWS_CSS } from "../../styles/index.js";
3
- import { PcElement, defineElement } from "../../base/index.js";
3
+ import { defineElement } from "../../base/index.js";
4
+ import { PcPanel } from "../PcPanel/index.js";
4
5
  import ChangeController from "../../ChangeController/index.js";
5
6
  import { maskModeFor } from "../../../lib/selection/geometry/index.js";
6
7
  import { LAYER_ALPHA_MASK_EVENT, LAYER_DRAG_EVENT, LAYER_MENU_OPEN_EVENT } from "../PcLayerItem/index.js";
7
8
  import { html, nothing, unsafeCSS } from "lit";
8
9
  import { styleMap } from "lit/directives/style-map.js";
9
10
  import { repeat } from "lit/directives/repeat.js";
10
- // src/ui/elements/PcLayersMenu/index.ts
11
+ // src/ui/elements/PcPanelLayers/index.ts
11
12
  /**
12
13
  * Whether a point is inside a rectangle (edges included).
13
14
  *
@@ -41,17 +42,17 @@ var dropSlot = (rows, y, ghost) => {
41
42
  * highlighted for touch). Escape cancels the drag. Moves and duplicates are announced to screen readers.
42
43
  *
43
44
  * @example
44
- * html`<pc-layers-menu .app=${app}></pc-layers-menu>`
45
+ * html`<pc-panel-layers .app=${app}></pc-panel-layers>`
45
46
  */
46
- var PcLayersMenu = class extends PcElement {
47
+ var PcPanelLayers = class extends PcPanel {
47
48
  static properties = {
48
- ...PcElement.properties,
49
+ ...PcPanel.properties,
49
50
  app: { attribute: false },
50
51
  drag: { state: true },
51
52
  announcement: { state: true }
52
53
  };
53
54
  static styles = [
54
- PcElement.styles,
55
+ ...PcPanel.styles,
55
56
  unsafeCSS(NO_TEXT_SELECTION_CSS),
56
57
  unsafeCSS(style_default),
57
58
  unsafeCSS(WINDOWS_CSS),
@@ -185,9 +186,15 @@ var PcLayersMenu = class extends PcElement {
185
186
  if (slot === others) entries.push(ghost);
186
187
  return repeat(entries, (entry) => entry.key, (entry) => entry.view);
187
188
  }
188
- render() {
189
+ get defaultIcon() {
190
+ return "layers";
191
+ }
192
+ get defaultLabel() {
193
+ return this.t("paintCanvas.toolbar.layers");
194
+ }
195
+ renderBody() {
189
196
  const layers = this.app?.layers;
190
- if (!layers) return html``;
197
+ if (!layers) return nothing;
191
198
  return html`
192
199
  ${this.renderRows(layers)}
193
200
  <button
@@ -204,5 +211,5 @@ var PcLayersMenu = class extends PcElement {
204
211
  `;
205
212
  }
206
213
  };
207
- defineElement("pc-layers-menu", PcLayersMenu);
208
- export { PcLayersMenu, dropSlot, isInside };
214
+ defineElement("pc-panel-layers", PcPanelLayers);
215
+ export { PcPanelLayers, dropSlot, isInside };
@@ -0,0 +1,3 @@
1
+ // src/ui/elements/PcPanelLayers/style.css?inline
2
+ var style_default = "/* \"New Layer\": a full-width purple pill */\nbutton.new {\n width: 100%;\n min-height: 40px;\n}\n/* Where a dragged layer would land: a full-width block with its name, as tall as the row (set by the menu) */\n.ghost {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n padding: 0 8px;\n border: 2px dashed;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n/* Dropping a dragged layer here duplicates it (highlighted for touch, where there is no \"+\" cursor) */\nbutton.new.drop-target {\n outline: var(--pc-focus-width) solid var(--pc-focus);\n outline-offset: 2px;\n}\n/* For screen readers only */\n.announcement {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n";
3
+ export { style_default as default };
@@ -0,0 +1,69 @@
1
+ import { nothing } from "lit";
2
+ import { PcElement } from "../../base";
3
+ import { type KeyCombo } from "../../../lib/utils/shortcuts";
4
+ import type { ShortcutChangeResult } from "../../../lib/classes/ShortcutSettings";
5
+ /** Keyboard shortcut settings `pc-shortcut-settings` can change: PaintCanvas's `ShortcutSettings`, or anything like it */
6
+ export interface ShortcutSettingsLike extends EventTarget {
7
+ combo(id: string): KeyCombo | null;
8
+ set(id: string, combo: KeyCombo | null): ShortcutChangeResult;
9
+ reset(): void;
10
+ }
11
+ /**
12
+ * Every keyboard shortcut action and its key combination, in groups. A configurable action's key combination is changed
13
+ * by focusing its field and pressing the keys (the modifiers held show as they are pressed, e.g. `shift alt cmd ctrl
14
+ * g`); Tab and Escape aren't recorded, so they still move focus and close. Its ⨉ button removes it. A key combination
15
+ * another action has moves to this one; one a fixed action uses isn't set. Both are announced, and sent as
16
+ * `pc-toast`. Fixed actions (e.g. undo, and layer opacity on 1–0) are shown but can't be changed. "Reset" goes back to
17
+ * the default key combinations.
18
+ *
19
+ * @example
20
+ * html`<pc-shortcut-settings .settings=${canvas.shortcuts}></pc-shortcut-settings>`
21
+ */
22
+ export declare class PcShortcutSettings extends PcElement {
23
+ static properties: {
24
+ settings: {
25
+ attribute: boolean;
26
+ };
27
+ recording: {
28
+ state: boolean;
29
+ };
30
+ status: {
31
+ state: boolean;
32
+ };
33
+ translations: {
34
+ attribute: boolean;
35
+ };
36
+ icons: {
37
+ attribute: boolean;
38
+ };
39
+ theme: {
40
+ type: StringConstructor;
41
+ reflect: boolean;
42
+ };
43
+ };
44
+ static styles: import("lit").CSSResultGroup[];
45
+ /** The key combinations shown and changed */
46
+ settings?: ShortcutSettingsLike;
47
+ /** The action being recorded and the modifiers held so far */
48
+ recording?: {
49
+ id: string;
50
+ text: string;
51
+ };
52
+ /** The last change's message, for screen readers */
53
+ status: string;
54
+ private changes;
55
+ constructor();
56
+ /** A shortcut action's name in the chosen language */
57
+ private name;
58
+ /** Record the keys pressed in an action's field */
59
+ private onRecordKeyDown;
60
+ /** Show the key combination again once modifiers are let go without pressing a key */
61
+ private onRecordKeyUp;
62
+ /** Set or remove an action's key combination, saying what happened */
63
+ private change;
64
+ /** A configurable action's field and remove button */
65
+ private renderField;
66
+ /** A fixed action's key combinations */
67
+ private renderFixed;
68
+ render(): import("lit").TemplateResult<1> | typeof nothing;
69
+ }
@@ -0,0 +1,273 @@
1
+ import { PcElement, defineElement, emit } from "../../base/index.js";
2
+ import ChangeController from "../../ChangeController/index.js";
3
+ import { SHORTCUT_DEFINITIONS, comboFromEvent, comboText, heldModifiers } from "../../../lib/utils/shortcuts/index.js";
4
+ import { css, html, nothing } from "lit";
5
+ // src/ui/elements/PcShortcutSettings/index.ts
6
+ /** Keys used to move through and leave the settings, which are never recorded */
7
+ var PASSED_KEYS = /* @__PURE__ */ new Set(["Tab", "Escape"]);
8
+ /**
9
+ * Translation key and values of a shortcut action's name.
10
+ *
11
+ * @example
12
+ * actionName({ id: "layer-opacity-30", ... }); // ["paintCanvas.shortcuts.layerOpacity", { percent: 30 }]
13
+ */
14
+ var actionName = ({ id, action }) => action.type === "layer-opacity" ? ["paintCanvas.shortcuts.layerOpacity", { percent: Math.round(action.opacity * 100) }] : [`paintCanvas.shortcuts.${id}`];
15
+ /**
16
+ * The shortcut actions in groups, in the order they are listed.
17
+ */
18
+ var groups = () => {
19
+ const grouped = /* @__PURE__ */ new Map();
20
+ for (const definition of SHORTCUT_DEFINITIONS) grouped.set(definition.group, [...grouped.get(definition.group) ?? [], definition]);
21
+ return [...grouped];
22
+ };
23
+ /**
24
+ * Every keyboard shortcut action and its key combination, in groups. A configurable action's key combination is changed
25
+ * by focusing its field and pressing the keys (the modifiers held show as they are pressed, e.g. `shift alt cmd ctrl
26
+ * g`); Tab and Escape aren't recorded, so they still move focus and close. Its ⨉ button removes it. A key combination
27
+ * another action has moves to this one; one a fixed action uses isn't set. Both are announced, and sent as
28
+ * `pc-toast`. Fixed actions (e.g. undo, and layer opacity on 1–0) are shown but can't be changed. "Reset" goes back to
29
+ * the default key combinations.
30
+ *
31
+ * @example
32
+ * html`<pc-shortcut-settings .settings=${canvas.shortcuts}></pc-shortcut-settings>`
33
+ */
34
+ var PcShortcutSettings = class extends PcElement {
35
+ static properties = {
36
+ ...PcElement.properties,
37
+ settings: { attribute: false },
38
+ recording: { state: true },
39
+ status: { state: true }
40
+ };
41
+ static styles = [PcElement.styles, css`
42
+ :host {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: var(--pc-space-3);
46
+ color: var(--pc-text);
47
+ font-family: var(--pc-font);
48
+ font-size: var(--pc-font-size);
49
+ }
50
+ section {
51
+ display: grid;
52
+ grid-template-columns: 1fr auto;
53
+ gap: var(--pc-space-1) var(--pc-space-2);
54
+ align-items: center;
55
+ }
56
+ h3 {
57
+ grid-column: 1 / -1;
58
+ margin: 0;
59
+ padding-bottom: var(--pc-space-1);
60
+ border-bottom: 1px solid var(--pc-border);
61
+ font-size: inherit;
62
+ }
63
+ .keys {
64
+ display: flex;
65
+ gap: var(--pc-space-1);
66
+ align-items: center;
67
+ justify-content: flex-end;
68
+ }
69
+ .combo {
70
+ box-sizing: border-box;
71
+ width: 11em;
72
+ min-height: var(--pc-control-size);
73
+ padding: var(--pc-space-1) var(--pc-space-2);
74
+ border: 1px solid var(--pc-border);
75
+ border-radius: var(--pc-radius-small);
76
+ background: var(--pc-surface);
77
+ color: var(--pc-text);
78
+ font: inherit;
79
+ font-variant-numeric: tabular-nums;
80
+ }
81
+ input.combo {
82
+ cursor: pointer;
83
+ }
84
+ input.combo:focus {
85
+ border-color: var(--pc-accent);
86
+ }
87
+ input.combo:focus-visible,
88
+ button:focus-visible {
89
+ outline: var(--pc-focus-width) solid var(--pc-focus);
90
+ outline-offset: 1px;
91
+ }
92
+ /* Fixed key combinations: shown like the fields, but muted */
93
+ span.combo {
94
+ display: inline-flex;
95
+ align-items: center;
96
+ margin-right: calc(var(--pc-control-size) + var(--pc-space-1));
97
+ background: var(--pc-bar);
98
+ color: var(--pc-text-muted);
99
+ }
100
+ button.remove {
101
+ width: var(--pc-control-size);
102
+ height: var(--pc-control-size);
103
+ padding: 0;
104
+ border: 1px solid var(--pc-border);
105
+ border-radius: var(--pc-radius-small);
106
+ background: var(--pc-surface);
107
+ color: var(--pc-text);
108
+ font: inherit;
109
+ cursor: pointer;
110
+ }
111
+ button.remove:hover:not(:disabled) {
112
+ background: var(--pc-surface-hover);
113
+ }
114
+ button.remove:disabled {
115
+ opacity: 0.4;
116
+ cursor: default;
117
+ }
118
+ .status:empty {
119
+ display: none;
120
+ }
121
+ /* Stays in view at the bottom of a scrolling window, where toasts may be hidden behind it */
122
+ .status {
123
+ position: sticky;
124
+ bottom: 0;
125
+ margin: 0;
126
+ padding: var(--pc-space-2);
127
+ border: 1px solid var(--pc-border);
128
+ border-radius: var(--pc-radius-small);
129
+ background: var(--pc-surface-raised);
130
+ box-shadow: var(--pc-shadow);
131
+ }
132
+ button.reset {
133
+ align-self: flex-start;
134
+ min-height: var(--pc-control-size);
135
+ padding: var(--pc-space-1) var(--pc-space-3);
136
+ border: 0;
137
+ border-radius: var(--pc-radius-pill);
138
+ background: var(--pc-accent);
139
+ color: var(--pc-accent-text);
140
+ font: inherit;
141
+ font-weight: bold;
142
+ cursor: pointer;
143
+ }
144
+ `];
145
+ changes = new ChangeController(this, () => [this.settings]);
146
+ constructor() {
147
+ super();
148
+ this.status = "";
149
+ }
150
+ /** A shortcut action's name in the chosen language */
151
+ name(definition) {
152
+ const [key, values] = actionName(definition);
153
+ return this.t(key, values);
154
+ }
155
+ /** Record the keys pressed in an action's field */
156
+ onRecordKeyDown(event, id) {
157
+ if (PASSED_KEYS.has(event.key)) return;
158
+ event.preventDefault();
159
+ event.stopPropagation();
160
+ const combo = comboFromEvent(event);
161
+ if (!combo) {
162
+ this.recording = {
163
+ id,
164
+ text: comboText(heldModifiers(event))
165
+ };
166
+ return;
167
+ }
168
+ this.recording = void 0;
169
+ this.change(id, combo);
170
+ }
171
+ /** Show the key combination again once modifiers are let go without pressing a key */
172
+ onRecordKeyUp(event) {
173
+ if (!this.recording) return;
174
+ const text = comboText(heldModifiers(event));
175
+ this.recording = text ? {
176
+ ...this.recording,
177
+ text
178
+ } : void 0;
179
+ }
180
+ /** Set or remove an action's key combination, saying what happened */
181
+ change(id, combo) {
182
+ const result = this.settings.set(id, combo);
183
+ const definition = (id) => SHORTCUT_DEFINITIONS.find((each) => each.id === id);
184
+ const keys = combo ? comboText(combo) : "";
185
+ const message = result.fixed ? this.t("paintCanvas.shortcuts.fixedUsed", {
186
+ keys,
187
+ action: this.name(definition(result.fixed))
188
+ }) : result.movedFrom ? this.t("paintCanvas.shortcuts.moved", {
189
+ keys,
190
+ from: this.name(definition(result.movedFrom)),
191
+ to: this.name(definition(id))
192
+ }) : "";
193
+ this.status = message;
194
+ if (message) emit(this, "pc-toast", {
195
+ message,
196
+ kind: "info"
197
+ });
198
+ }
199
+ /** A configurable action's field and remove button */
200
+ renderField(settings, definition) {
201
+ const { id } = definition;
202
+ const combo = settings.combo(id);
203
+ const name = this.name(definition);
204
+ const recording = this.recording?.id === id ? this.recording : void 0;
205
+ return html`<span class="keys">
206
+ <input
207
+ class="combo"
208
+ id="combo-${id}"
209
+ data-id=${id}
210
+ readonly
211
+ autocomplete="off"
212
+ aria-description=${this.t("paintCanvas.shortcuts.recordHint")}
213
+ placeholder=${this.t("paintCanvas.shortcuts.none")}
214
+ .value=${recording ? recording.text : combo ? comboText(combo) : ""}
215
+ @keydown=${(e) => this.onRecordKeyDown(e, id)}
216
+ @keyup=${this.onRecordKeyUp}
217
+ @blur=${() => this.recording = void 0}
218
+ />
219
+ <button
220
+ type="button"
221
+ class="remove"
222
+ data-id=${id}
223
+ title=${this.t("paintCanvas.shortcuts.remove", { action: name })}
224
+ aria-label=${this.t("paintCanvas.shortcuts.remove", { action: name })}
225
+ ?disabled=${!combo}
226
+ @click=${() => this.change(id, null)}
227
+ >
228
+ ⨉
229
+ </button>
230
+ </span>`;
231
+ }
232
+ /** A fixed action's key combinations */
233
+ renderFixed(definition) {
234
+ return html`<span class="keys">
235
+ <span
236
+ class="combo"
237
+ id="combo-${definition.id}"
238
+ data-id=${definition.id}
239
+ role="note"
240
+ aria-labelledby="name-${definition.id}"
241
+ aria-description=${this.t("paintCanvas.shortcuts.fixed")}
242
+ >${definition.combos.map((combo) => comboText(combo)).join(", ")}</span
243
+ >
244
+ </span>`;
245
+ }
246
+ render() {
247
+ const settings = this.settings;
248
+ if (!settings) return nothing;
249
+ return html`${groups().map(([group, definitions]) => html`<section aria-labelledby="group-${group}">
250
+ <h3 id="group-${group}">
251
+ ${this.t(`paintCanvas.shortcuts.group.${group}`)}
252
+ </h3>
253
+ ${definitions.map((definition) => definition.configurable ? html`<label for="combo-${definition.id}"
254
+ >${this.name(definition)}</label
255
+ >${this.renderField(settings, definition)}` : html`<span id="name-${definition.id}"
256
+ >${this.name(definition)}</span
257
+ >${this.renderFixed(definition)}`)}
258
+ </section>`)}
259
+ <p class="status" role="status">${this.status}</p>
260
+ <button
261
+ type="button"
262
+ class="reset"
263
+ @click=${() => {
264
+ settings.reset();
265
+ this.status = this.t("paintCanvas.shortcuts.wasReset");
266
+ }}
267
+ >
268
+ ${this.t("paintCanvas.shortcuts.reset")}
269
+ </button>`;
270
+ }
271
+ };
272
+ defineElement("pc-shortcut-settings", PcShortcutSettings);
273
+ export { PcShortcutSettings };
@@ -1,5 +1,6 @@
1
1
  import { ICON_CONTROLS_CSS } from "../../styles/index.js";
2
2
  import { PcElement, defineElement, emit } from "../../base/index.js";
3
+ import "../PcButtonGroup/index.js";
3
4
  import { css, html, unsafeCSS } from "lit";
4
5
  // src/ui/elements/PcThemePicker/index.ts
5
6
  /** The themes to pick from: light, dark, or following the device (auto) */
@@ -1,4 +1,5 @@
1
1
  import { PcElement, defineElement, emit } from "../../base/index.js";
2
+ import "../PcButton/index.js";
2
3
  import { css, html, nothing } from "lit";
3
4
  // src/ui/elements/PcToast/index.ts
4
5
  /** How long a toast shows before dismissing itself, unless told otherwise (milliseconds) */
@@ -1,8 +1,9 @@
1
+ import { Tool } from "../../../lib/classes/PaintCanvas/tool.js";
1
2
  import style_default from "./style.js";
2
3
  import { ICON_CONTROLS_CSS, PILLS_CSS } from "../../styles/index.js";
3
4
  import { PcElement, defineElement } from "../../base/index.js";
4
5
  import ChangeController from "../../ChangeController/index.js";
5
- import { Panel, Tool } from "../../../lib/classes/PaintCanvas/index.js";
6
+ import { Panel } from "../../../lib/classes/PaintCanvas/index.js";
6
7
  import "../../../lib/classes/BrushSettings/index.js";
7
8
  import { MAX_ZOOM, MIN_ZOOM } from "../../../lib/classes/Viewport/index.js";
8
9
  import { iconLabel } from "../../icons/index.js";
@@ -1,25 +1,31 @@
1
- import { PcElement } from "../../base";
1
+ import { nothing } from "lit";
2
+ import { PcPane } from "../PcPane";
2
3
  import { Tool, type default as PaintCanvas } from "../../../lib/classes/PaintCanvas";
3
- /** Toolbar buttons in display order: tool, icon name, translation key of its name, and its keyboard shortcut */
4
+ import "../PcColourPair";
5
+ /** Toolbar buttons in display order: tool, icon name, translation key of its name, and its keyboard shortcut action */
4
6
  export declare const TOOLBAR_TOOLS: readonly {
5
7
  tool: Tool;
6
8
  /** The button's icon, by name in the icon registry */
7
9
  icon: string;
8
10
  /** Translation key of the tool's name */
9
11
  name: string;
10
- /** The tool's keyboard shortcut, shown with its name */
11
- shortcut: string;
12
+ /** ID of the tool's keyboard shortcut action (see `SHORTCUT_DEFINITIONS`), whose key combination is shown with its name */
13
+ shortcutId: string;
12
14
  }[];
13
15
  /**
14
- * Vertical toolbar: current colour, tools, undo and redo (disabled when there is nothing to undo or redo), layers menu
15
- * toggle (unless `layers` is false) and app menu toggle. Tools, undo, redo and the layers toggle show their icons; undo
16
- * and redo have their shortcuts (⌘ on Apple devices, ^ elsewhere) in their tooltips. The app menu button shows
17
- * `menuText` and is named `menuLabel` for screen readers.
16
+ * Vertical toolbar: the foreground and background colours, tools, undo and redo (disabled when there is nothing to undo
17
+ * or redo), layers menu toggle (unless `layers` is false) and app menu toggle. Pressing a colour selects it and opens the
18
+ * colour palette (if it isn't open). Tools, undo, redo and the layers toggle show
19
+ * their icons; tools have the user's keyboard shortcuts in their tooltips, and undo and redo theirs (⌘ on Apple
20
+ * devices, ^ elsewhere). The app menu button shows `menuText` and is named `menuLabel` for screen readers.
21
+ *
22
+ * It's a `PcPane`: the colours and tools are at its start, and undo, redo, the layers toggle and the app menu toggle at
23
+ * its end, after anything slotted there.
18
24
  *
19
25
  * @example
20
26
  * html`<pc-toolbar .app=${app} menuText="App" menuLabel="App menu"></pc-toolbar>`
21
27
  */
22
- export declare class PcToolbar extends PcElement {
28
+ export declare class PcToolbar extends PcPane {
23
29
  static properties: {
24
30
  app: {
25
31
  attribute: boolean;
@@ -36,6 +42,28 @@ export declare class PcToolbar extends PcElement {
36
42
  layers: {
37
43
  type: BooleanConstructor;
38
44
  };
45
+ orientation: {
46
+ type: StringConstructor;
47
+ reflect: boolean;
48
+ };
49
+ mode: {
50
+ type: StringConstructor;
51
+ reflect: boolean;
52
+ };
53
+ edge: {
54
+ type: StringConstructor;
55
+ reflect: boolean;
56
+ };
57
+ label: {
58
+ type: StringConstructor;
59
+ };
60
+ collapsed: {
61
+ type: BooleanConstructor;
62
+ reflect: boolean;
63
+ };
64
+ openPanel: {
65
+ state: boolean;
66
+ };
39
67
  translations: {
40
68
  attribute: boolean;
41
69
  };
@@ -64,8 +92,15 @@ export declare class PcToolbar extends PcElement {
64
92
  */
65
93
  private onToolClick;
66
94
  /**
67
- * Update the drawing colour from the colour input.
95
+ * Select the pressed colour, and open the colour palette if it isn't open.
68
96
  */
69
- private onColourInput;
70
- render(): import("lit").TemplateResult<1>;
97
+ private onColourClick;
98
+ /** A tool's name, with its keyboard shortcut if it has one */
99
+ private toolLabel;
100
+ /** The colours and tools */
101
+ protected renderStart(): import("lit").TemplateResult<1> | typeof nothing;
102
+ /** The space between the tools and the end */
103
+ protected renderMiddle(): import("lit").TemplateResult<1>;
104
+ /** Undo, redo, and the layers and app menu toggles */
105
+ protected renderEnd(): import("lit").TemplateResult<1> | typeof nothing;
71
106
  }