import { html, svg } from 'sinuous/packages/sinuous' import { focus, format, insert } from '/src/instance' import { getState } from '/src/state' import * as InkValues from '/types/values' import { styles } from './styles' import type InkInternal from '/types/internal' interface ButtonProps { content: HTMLElement | string handler: () => void } interface FormatProps { enabled: boolean ref: InkInternal.Ref } interface ToolbarProps { ref: InkInternal.Ref } const Button = ({ content, handler }: ButtonProps) => { return html` ` } const InsertBold = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Bold) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertCode = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Code) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertCodeBlock = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.CodeBlock) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertHeading = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Heading) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertImage = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Image) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertItalic = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Italic) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertLink = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Link) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertList = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.List) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertOrderedList = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.OrderedList) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertQuote = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.Quote) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const InsertTaskList = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const content = svg` ` const handler = () => { format(ref, InkValues.Markup.TaskList) focus(ref) } return html` <${Button} content=${content} handler=${handler} /> ` } const UploadFile = ({ enabled, ref }: FormatProps) => { if (!enabled) { return } const { options: { files } } = getState(ref) const icon = svg` ` const uploader = document.createElement('input') const handler = () => { uploader.click() } uploader.style.display = 'none' uploader.type = 'file' uploader.onchange = (event: Event) => { const target = event.target as HTMLInputElement if (target?.files) { Promise.resolve(files.handler(target.files)).then((url) => { const markup = `![](${url})` insert(ref, markup) focus(ref) }) } } const content = html` ${icon} ${uploader} ` return html` <${Button} content=${content} handler=${handler} /> ` } const Toolbar = ({ ref }: ToolbarProps) => { const { options: { toolbar } } = getState(ref) return html`
<${styles} /> ${() => { const { bold, heading, italic } = toolbar if (!bold && !heading && !italic) { return } return html`
<${InsertHeading} enabled=${heading} ref=${ref} /> <${InsertBold} enabled=${bold} ref=${ref} /> <${InsertItalic} enabled=${italic} ref=${ref} />
` }} ${() => { const { code, codeBlock, quote } = toolbar if (!code && !codeBlock && !quote) { return } return html`
<${InsertQuote} enabled=${quote} ref=${ref} /> <${InsertCodeBlock} enabled=${codeBlock} ref=${ref} /> <${InsertCode} enabled=${code} ref=${ref} />
` }} ${() => { const { list, orderedList, taskList } = toolbar if (!list && !orderedList && !taskList) { return } return html`
<${InsertList} enabled=${list} ref=${ref} /> <${InsertOrderedList} enabled=${orderedList} ref=${ref} /> <${InsertTaskList} enabled=${taskList} ref=${ref} />
` }} ${() => { const { image, link, upload} = toolbar if (!image && !link && !upload) { return } return html`
<${InsertLink} enabled=${link} ref=${ref} /> <${InsertImage} enabled=${image} ref=${ref} /> <${UploadFile} enabled=${upload} ref=${ref} />
` }}
` } export const createToolbar = (ref: InkInternal.Ref) => { return html` <${Toolbar} ref=${ref} /> ` }