import { html, css, LitElement, PropertyValues } from "lit"; import { provide, consume, createContext } from "@lit/context"; import { LitElementWw } from "@webwriter/lit"; import { customElement, property, query } from "lit/decorators.js"; import search from "@tabler/icons/outline/search.svg"; import file from "@tabler/icons/outline/file.svg"; import squares from "@tabler/icons/outline/squares.svg"; import arrowsSplit2 from "@tabler/icons/outline/arrows-split-2.svg"; import book from "@tabler/icons/outline/book.svg"; import packages from "@tabler/icons/outline/packages.svg"; import trash from "@tabler/icons/outline/trash.svg"; import circleArrowRight from "@tabler/icons/filled/circle-arrow-right.svg"; import infoSquareRounded from "@tabler/icons/filled/info-square-rounded.svg"; import { editorState, GamebookEditorState, } from "../../utils/gamebook-editor-state-context"; //Drawflow Imports import Drawflow, { DrawflowNode } from "drawflow"; // Shoelace Imports import "@shoelace-style/shoelace/dist/themes/light.css"; import { SlInput, SlIcon, SlButton, SlSwitch, SlSelect, SlDivider, SlIconButton, SlButtonGroup, SlDropdown, SlMenu, SlMenuItem, SlMenuLabel, } from "@shoelace-style/shoelace"; @customElement("webwriter-gamebook-options") export class WebWriterGamebookOptions extends LitElementWw { static get styles() { return css` :host { padding-left: 10px; } .author-only { display: flex; flex-direction: column; box-sizing: border-box; gap: 10px; width: 180px; } .author-only .header p { margin: 0px; font-weight: 500; font-size: 15px; box-sizing: border-box; color: #52525b; } .author-only .header { display: flex; flex-direction: row; align-items: center; justify-items: center; border-bottom: 2px solid #52525b; gap: 7px; padding-bottom: 10px; } .author-only .searchBar { display: flex; flex-direction: row; align-items: flex-start; justify-items: center; width: 100%; height: 65px; } .author-only .searchBar * { width: 100%; } .author-only sl-icon { color: #52525b; } .author-only .horizontalStack { display: flex; flex-direction: row; align-items: center; gap: 5px; width: 100%; } sl-button.square { width: 42px; /* Set this value to whatever size you want */ height: 42px; /* Same value as width to ensure it's a square */ } p { margin: 0px; font-weight: 400; font-size: 15px; box-sizing: border-box; color: #52525b; } `; } //registering custom elements used in the widget static get scopedElements() { return { "sl-input": SlInput, "sl-icon": SlIcon, "sl-button": SlButton, "sl-button-group": SlButtonGroup, "sl-select": SlSelect, "sl-divider": SlDivider, "sl-icon-button": SlIconButton, "sl-switch": SlSwitch, "sl-dropdown": SlDropdown, "sl-menu": SlMenu, "sl-menu-item": SlMenuItem, "sl-menu-label": SlMenuLabel, }; } @query("#searchInput") accessor searchInput; @consume({ context: editorState, subscribe: true }) @property({ type: Object, attribute: true, reflect: false }) public accessor editorStore = new GamebookEditorState("Default"); render() { const options = (data) => Object.keys(data) .filter( (key) => this.editorStore.searchResults !== undefined ? this.editorStore.searchResults.includes(Number(key)) : true // No filtering when searchResults is empty ) .map( (key) => html` this.moveTo(data[key])} >

${data[key].data.title}

${data[key].class === "page" || data[key].class === "origin" ? html` ` : data[key].class === "popup" ? html` ` : data[key].class === "branch" ? html` ` : null}
` ); return html`

Gamebook

${this.editorStore.searchResults ? html` ${this.editorStore.searchResults.length} nodes ` : null} ${options(this.editorStore.editorContent.drawflow.Home.data)} this.editorStore.setCopiedNode(this.editorStore.selectedNode)} ?disabled=${this.editorStore.selectedNode.id === -1} > Copy this.dispatchEvent( new CustomEvent("pasteNode", { bubbles: true, composed: true, }) )} ?disabled=${this.editorStore.copiedNode.id === -1} > Paste this.deleteSelectedNode()} ?disabled=${this.editorStore.selectedNode.id === -1 || this.editorStore.selectedNode.class == "origin" ? true : false} > ${this.editorStore.selectedNode.id != -1 ? html`
${this.editorStore.selectedNode.class == "page" ? html`

Page

` : this.editorStore.selectedNode.class == "origin" ? html`

Start Page

` : this.editorStore.selectedNode.class == "popup" ? html`

Popup

` : this.editorStore.selectedNode.class == "branch" ? html`

Branch

` : null}
${this.editorStore.selectedNode.class == "page" || this.editorStore.selectedNode.class == "origin" ? html` this.makeNodeOrigin()} ?disabled=${this.editorStore.selectedNode.class == "origin" ? true : false} > Set as Start Page ` : null} ${this.editorStore.selectedNode.class == "branch" ? html`

Create rules to guide how your gamebook progresses. The first rule that applies will be used.

Requires WebWriter Quiz Widget .

` : null} ${this.editorStore.selectedNode.class == "popup" ? html` this.handleSwitchPreventClosing(event)} > Prevent Closing this.handleSwitchNoHeader(event)} > Header ` : null} ` : null}
`; } /* */ private _handleNodeSearch(event: Event) { const inputText = (event.target as SlInput).value; this.editorStore.setSearchTerm(inputText); this.dispatchEvent( new CustomEvent("nodeSearch", { bubbles: true, composed: true, }) ); this.requestUpdate(); } /* */ private makeNodeOrigin() { this.dispatchEvent( new CustomEvent("makeSelectedNodeOrigin", { detail: { newId: this.editorStore.selectedNode.id }, bubbles: true, composed: true, }) ); } /* */ private handleSwitchPreventClosing(event: Event) { const value = (event.target as SlSwitch).checked; this.editorStore.selectedContainer.preventClosing = value; this.editorStore.setSelectedContainer(this.editorStore.selectedContainer); this.requestUpdate(); } /* */ private handleSwitchNoHeader(event: Event) { const value = (event.target as SlSwitch).checked; this.editorStore.selectedContainer.noHeader = !value; this.editorStore.setSelectedContainer(this.editorStore.selectedContainer); this.requestUpdate(); } /* */ private deleteSelectedNode() { this.dispatchEvent( new CustomEvent("deleteSelectedNode", { bubbles: true, composed: true, }) ); } /* */ private moveTo(node: DrawflowNode) { this.dispatchEvent( new CustomEvent("moveTo", { detail: { node: node }, bubbles: true, composed: true, }) ); } /* */ _handleInputKeydown(event) { if (event.key === " ") { // Prevent space from triggering any unwanted events (e.g., dropdown closing) event.stopPropagation(); } } }