制作一个表格生成器

这次我们来创建一个快捷创建markdown的表格。当我们输入/create table时,显示出一个create table窗口,填入我们想要的rowcol就往logseq插入我们想要的markdown表格。

这次项目同样基于logseq-plugin-template-react

搭建

参考上一章

注册命令

main.tsx

 logseq.Editor.registerSlashCommand(
      'create table', async () => {
        logseq.showMainUI()
      },
  )

写窗口

新建table.tsxtable.css

import React, {useEffect} from "react";
import "./table.css"

const createTable = (row:number, col:number)=>{ // 生成markdown表格的内容
    let content = "|"
    let rowContent = "|"

    for(let i = 0; i < col; i++){
        content += ` Col ${i} |`
    }
    content += "\n"
    content += "|"

    for(let i = 0; i < col; i++){
        content += " --- |"
    }
    content += "\n"

    for(let j = 0; j < col; j++){
        rowContent += "   |"
    }
    rowContent += "\n"

    for(let i = 0; i < row; i++){
        content +=
            rowContent
    }
    return content
}

const insertContent = async (content:string) =>{ // 把内容插入到logseq
    window.logseq.hideMainUI({ restoreEditingCursor: true });
    await window.logseq.Editor.insertAtEditingCursor(content);
    // 
}

// eslint-disable-next-line react/display-name,no-empty-pattern
export const Table = React.forwardRef<HTMLDivElement>(({}, ref) => {
    const [row, setRow] = React.useState("3");
    const [col, setCol] = React.useState("4");

    return(
        <div
            ref={ref}
            className="table-root"
            >
            <div className="center">
                <div>
                    Rows: <input value={row} onChange={(e)=>setRow(e.target.value)}/>
                </div>
                <div>
                    Cols: <input value={col} onChange={(e)=>setCol(e.target.value)} />
                </div>
                <div>
                    <button onClick={()=>{insertContent(createTable(Number(row),Number(col)))}}>Insert</button>
                </div>
            </div>
        </div>
    );
});

main.tsx和上一章基本一样,导入的组件变了而已。

现在已经能调出create table窗口了,但是窗口出现在logseq的左上角。我们要调整一下窗口出现的位置。

让窗口出现在光标处

这次我们希望它像emoji-picker一样工作。窗口在光标的地方。我们直接从那边扒代码。

修改table.tsx

效果不错!

美化窗口

虽然现在一个插件的基本功能做到了,但是还是很丑。我们进行一番修改。让窗口边框变的光滑,然后居中组件。

虽然现在还是很丑,但是已经比之前好很多了。

注册快捷键

我们还希望能更方便一点。比如当我们按下esc时关闭窗口,按下Enter时就等于按下insert

esc实现

main.tsx中加入监听器

通过ESC键关闭窗口

图:通过esc关闭窗口

Enter实现

修改main.tsx

监听Enter事件。这里用到了logseqevent机制。通过logseq.emit提交事件。

table.tsx组件里监听logseq其它地方发来的可能的监听事件。

这里之所以要off掉之前的事件,是因为有修改row或者col会挂载多个事件的。导致一按回车,触发多个事件。

通过Enter键代替按按扭

现在就可以通过esc关闭窗口和Enter进行触发按扭了。

拓展

调整窗口位置的实现和逻辑:

代码分析与解释:未完待续

logseq-plugin-heatmap的实现

useWindowSizereact-use提供的hook,为我们提供当前窗口的大小。

这里获得right、bottom的意义不必多说。

这段代码的意义是

未完待续

logseq-emoji-picker的实现

logseq.Editor.getEditingCursorPosition获取当前光标所在位置的api。

返回值示例:

与我们窗口有关的属性在rect之中。

未完待续

最后更新于