UNPKG

@infinite-canvas-tutorial/webcomponents

Version:
336 lines (333 loc) 13.4 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TopNavbar = exports.ExportFormat = void 0; const localize_1 = require("@lit/localize"); const lit_1 = require("lit"); const decorators_js_1 = require("lit/decorators.js"); const when_js_1 = require("lit/directives/when.js"); const context_1 = require("@lit/context"); const ecs_1 = require("@infinite-canvas-tutorial/ecs"); const context_2 = require("../context"); const context_menu_1 = require("./context-menu"); var ExportFormat; (function (ExportFormat) { ExportFormat["SVG"] = "svg"; ExportFormat["PNG"] = "png"; ExportFormat["JPEG"] = "jpeg"; })(ExportFormat || (exports.ExportFormat = ExportFormat = {})); let TopNavbar = class TopNavbar extends lit_1.LitElement { constructor() { super(...arguments); this.isClipboardEmpty = true; this.binded = false; this.handleKeyDown = (e) => { // Canvas is focused if (!this.api || document.activeElement !== this.api.element) { return; } if (e.key === 'z' && e.metaKey) { e.preventDefault(); if (e.shiftKey) { this.handleRedo(); } else { this.handleUndo(); } } }; } firstUpdated(_changedProperties) { var _a; (_a = this.actionMenu) === null || _a === void 0 ? void 0 : _a.addEventListener('sp-opened', this.handleOpen); } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this.handleKeyDown); } handleExport(event) { const format = event.target.value; this.api.export(format); } handleEdit(event) { const value = event.target.value; if (value === 'undo') { this.handleUndo(); } else if (value === 'redo') { this.handleRedo(); } else if (value === 'cut') { this.handleCut(); } else if (value === 'copy') { this.handleCopy(); } else if (value === 'paste') { this.handlePaste(); } } handleConfigView(event) { const value = event.target.value; if (value === 'grid') { this.api.setAppState({ checkboardStyle: ecs_1.CheckboardStyle.GRID, }); } else { this.api.setAppState({ checkboardStyle: ecs_1.CheckboardStyle.NONE, }); } } handleConfigPreferences(event) { const selected = event.target.selected; this.api.setAppState({ snapToPixelGridEnabled: selected.includes('snapToPixelGrid'), snapToObjectsEnabled: selected.includes('snapToObjects'), }); } handleConfigTheme(event) { const selected = event.target.selected[0]; let themeMode = selected === 'dark' ? ecs_1.ThemeMode.DARK : ecs_1.ThemeMode.LIGHT; if (selected === 'system') { themeMode = window.matchMedia('(prefers-color-scheme: dark)').matches ? ecs_1.ThemeMode.DARK : ecs_1.ThemeMode.LIGHT; } this.api.setThemeMode(themeMode); } handleUndo() { this.api.undo(); } handleRedo() { this.api.redo(); } handleCut() { (0, context_menu_1.executeCut)(this.api, this.appState); } handleCopy() { (0, context_menu_1.executeCopy)(this.api, this.appState); } handlePaste() { (0, context_menu_1.executePaste)(this.api, this.appState); } handleOpen() { (0, ecs_1.readSystemClipboard)().then((clipboard) => { this.isClipboardEmpty = Object.keys(clipboard).length === 0; }); } handleConfigLanguage(event) { const selected = event.target.selected[0]; this.api.setAppState({ language: selected, }); this.api.setLocale(selected); } render() { var _a; // FIXME: wait for the element to be ready. if (((_a = this.api) === null || _a === void 0 ? void 0 : _a.element) && !this.binded) { this.api.element.addEventListener('keydown', this.handleKeyDown); this.binded = true; } const isSelectedEmpty = this.appState.layersSelected.length === 0; return (0, when_js_1.when)(this.appState.topbarVisible, () => { var _a, _b, _c, _d; return (0, lit_1.html) ` <div class="top-navbar"> <sp-action-menu size="m" label="Main menu" quiet> <sp-tooltip slot="tooltip" self-managed placement="bottom"> ${(0, localize_1.msg)((0, localize_1.str) `Main menu`)} </sp-tooltip> <sp-icon-show-menu slot="icon" size="l"></sp-icon-show-menu> <sp-menu-item> ${(0, localize_1.msg)((0, localize_1.str) `Edit`)} <sp-menu slot="submenu" @change=${this.handleEdit}> <sp-menu-item value="undo" ?disabled=${(_a = this.api) === null || _a === void 0 ? void 0 : _a.isUndoStackEmpty()} > ${(0, localize_1.msg)((0, localize_1.str) `Undo`)} <kbd slot="value">⌘Z</kbd> </sp-menu-item> <sp-menu-item value="redo" ?disabled=${(_b = this.api) === null || _b === void 0 ? void 0 : _b.isRedoStackEmpty()} > ${(0, localize_1.msg)((0, localize_1.str) `Redo`)} <kbd slot="value">⇧⌘Z</kbd> </sp-menu-item> <sp-menu-divider></sp-menu-divider> <sp-menu-item value="cut" ?disabled=${isSelectedEmpty}> ${(0, localize_1.msg)((0, localize_1.str) `Cut`)} <kbd slot="value">⌘X</kbd> </sp-menu-item> <sp-menu-item value="copy" ?disabled=${isSelectedEmpty}> ${(0, localize_1.msg)((0, localize_1.str) `Copy`)} <kbd slot="value">⌘C</kbd> </sp-menu-item> <sp-menu-item value="paste" ?disabled=${this.isClipboardEmpty} > ${(0, localize_1.msg)((0, localize_1.str) `Paste`)} <kbd slot="value">⌘V</kbd> </sp-menu-item> </sp-menu> </sp-menu-item> <sp-menu-item> ${(0, localize_1.msg)((0, localize_1.str) `View`)} <sp-menu slot="submenu" selects="multiple" .selected=${this.appState.checkboardStyle === ecs_1.CheckboardStyle.GRID ? ['grid'] : []} @change=${this.handleConfigView} > <sp-menu-item value="grid"> ${(0, localize_1.msg)((0, localize_1.str) `Grid`)} </sp-menu-item> </sp-menu> </sp-menu-item> <sp-menu-item> ${(0, localize_1.msg)((0, localize_1.str) `Preferences`)} <sp-menu slot="submenu" selects="multiple" .selected=${[ this.appState.snapToPixelGridEnabled ? 'snapToPixelGrid' : undefined, this.appState.snapToObjectsEnabled ? 'snapToObjects' : undefined, ].filter(Boolean)} @change=${this.handleConfigPreferences} > <sp-menu-item value="snapToPixelGrid"> ${(0, localize_1.msg)((0, localize_1.str) `Snap to pixel grid`)} </sp-menu-item> <sp-menu-item value="snapToObjects"> ${(0, localize_1.msg)((0, localize_1.str) `Snap to objects`)} </sp-menu-item> <sp-menu-divider></sp-menu-divider> <sp-menu-item> ${(0, localize_1.msg)((0, localize_1.str) `Theme`)} <sp-menu slot="submenu" selects="single" .selected=${[this.appState.themeMode]} @change=${this.handleConfigTheme} > <sp-menu-item value="light"> ${(0, localize_1.msg)((0, localize_1.str) `Light`)} </sp-menu-item> <sp-menu-item value="dark"> ${(0, localize_1.msg)((0, localize_1.str) `Dark`)} </sp-menu-item> <sp-menu-item value="system"> ${(0, localize_1.msg)((0, localize_1.str) `System`)} </sp-menu-item> </sp-menu> </sp-menu-item> <sp-menu-item> ${(0, localize_1.msg)((0, localize_1.str) `Language`)} <sp-menu slot="submenu" selects="single" .selected=${[this.appState.language]} @change=${this.handleConfigLanguage} > <sp-menu-item value="en"> English </sp-menu-item> <sp-menu-item value="es-419"> Español </sp-menu-item> <sp-menu-item value="zh-Hans"> 中文 (简体) </sp-menu-item> </sp-menu> </sp-menu-item> </sp-menu> </sp-menu-item> <sp-menu-divider></sp-menu-divider> <sp-menu-item> ${(0, localize_1.msg)((0, localize_1.str) `Export as...`)} <sp-menu slot="submenu" @change=${this.handleExport}> <sp-menu-item value=${ExportFormat.SVG}>SVG</sp-menu-item> <sp-menu-item value=${ExportFormat.PNG}>PNG</sp-menu-item> <sp-menu-item value=${ExportFormat.JPEG}>JPEG</sp-menu-item> </sp-menu> </sp-menu-item> </sp-action-menu> <div class="actions"> <sp-action-button quiet @click=${this.handleUndo} ?disabled=${(_c = this.api) === null || _c === void 0 ? void 0 : _c.isUndoStackEmpty()} > <sp-icon-undo slot="icon"></sp-icon-undo> <sp-tooltip self-managed placement="bottom"> ${(0, localize_1.msg)((0, localize_1.str) `Undo`)} </sp-tooltip> </sp-action-button> <sp-action-button quiet @click=${this.handleRedo} ?disabled=${(_d = this.api) === null || _d === void 0 ? void 0 : _d.isRedoStackEmpty()} > <sp-icon-redo slot="icon"></sp-icon-redo> <sp-tooltip self-managed placement="bottom"> ${(0, localize_1.msg)((0, localize_1.str) `Redo`)} </sp-tooltip> </sp-action-button> <ic-spectrum-zoom-toolbar /> </div> </div> `; }); } }; exports.TopNavbar = TopNavbar; TopNavbar.styles = (0, lit_1.css) ` .top-navbar { position: relative; display: flex; justify-content: space-between; padding: var(--spectrum-global-dimension-size-100); background: var(--spectrum-gray-100); } sp-menu-item { width: 200px; } kbd { font-family: var(--spectrum-alias-body-text-font-family); letter-spacing: 0.1em; white-space: nowrap; border: none; padding: none; padding: 0; line-height: normal; } .actions { display: flex; align-items: center; gap: var(--spectrum-global-dimension-size-100); } `; __decorate([ (0, context_1.consume)({ context: context_2.appStateContext, subscribe: true }) ], TopNavbar.prototype, "appState", void 0); __decorate([ (0, context_1.consume)({ context: context_2.apiContext, subscribe: true }) ], TopNavbar.prototype, "api", void 0); __decorate([ (0, decorators_js_1.state)() ], TopNavbar.prototype, "isClipboardEmpty", void 0); __decorate([ (0, decorators_js_1.query)('sp-action-menu', true) ], TopNavbar.prototype, "actionMenu", void 0); exports.TopNavbar = TopNavbar = __decorate([ (0, decorators_js_1.customElement)('ic-spectrum-top-navbar'), (0, localize_1.localized)() ], TopNavbar); //# sourceMappingURL=top-navbar.js.map