/// /// /// /** CSSでボタンの中身を表示するタイプのボタンの情報を格納しておくための型 */ export type ItemIcon = { type: "icon"; name: string; iconClass: string[]; onClick: (e:MouseEvent)=>void; } /** テキストでボタンの中身を表示するタイプのボタンの情報を格納しておくための型 */ export type ItemText = { type: "text"; name: string; text: string; onClick: (e:MouseEvent)=>void; } /** ボタンの情報を格納しておくための型。こっちは汎用的に使う。 */ export type Item = ItemText | ItemIcon; const makeEditBar = (): HTMLDivElement => { const style = document.createElement("style"); /* ↓editBar.cssを直接埋め込んでいる*/ style.textContent = ".bottom-bar{position:fixed;display:flex;flex-direction:column;align-items:flex-end;z-index:300;bottom:0;width:100%}div.status-bar{position:relative}.edit-bar{position:relative;border-top:var(--edit-bar-border);display:grid;grid-auto-flow:row;grid-template-columns:repeat(auto-fill,48px);grid-template-rows:auto;width:100%;overflow-x:auto;overflow-y:hidden;background-color:#0000001a;--edit-bar-border: 1px solid var(--tool-light-color, #a9aaaf)}.edit-bar>div{border:var(--edit-bar-border);background-color:var(--body-bg, #dcdde0);color:var(--tool-text-color, #666874);font-size:16px;height:34px;line-height:28px;text-align:center;vertical-align:middle;cursor:pointer}.edit-bar>div:first-child{border-top-left-radius:unset}.edit-bar>div:last-child{border-top-right-radius:unset}"; document.head.append(style); const editBar = document.createElement("div"); editBar.classList.add("edit-bar"); const bottomBar = document.createElement("div") bottomBar.classList.add("bottom-bar") const statusBar = document.querySelector(".status-bar")! document.querySelector(".app")!.append(bottomBar) bottomBar.append(statusBar) bottomBar.append(editBar); return editBar; }; const bar = makeEditBar(); export interface UseEditBarResult { /** * 取得した.edit-barの領域にボタンを表示する * @param items ボタンの情報 * @param onClick ボタンを押した時の動作 * */ render: (item: Item) => void; /** 表示したボタンを取得した領域ごと削除する */ dispose: () => void; } /** .edit-barの一区画を取得し、各種操作函数を返す */ export const useEditBar = (): UseEditBarResult => { const status = document.createElement("div"); bar.append(status); let listener: ((e: MouseEvent) => void) | undefined; return { render: (item: Item) => { status.textContent = ""; if (listener) status.removeEventListener("click", listener); listener = item.onClick; status.classList.add("eb-"+item.name) const child = makeGroup(item); if (child) { if (listener) status.addEventListener("click", listener); status.append(child); } }, dispose: () => status.remove(), }; }; const makeGroup = (item: Item): HTMLSpanElement | undefined => { switch (item.type) { case "icon": return makeIcon(...item.iconClass); case "text": return makeItem(item.text); } }; const makeItem = (child: string | Node): HTMLSpanElement => { const span = document.createElement("span"); span.classList.add("item"); span.append(child); return span; }; const makeIcon = (...classNames: string[]): HTMLElement => { const i = document.createElement("span"); if(classNames.join("") != "") i.classList.add(...classNames); return i; };