notra-editor 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/link-popover/link-popover.cjs +1 -1
- package/dist/components/link-popover/link-popover.cjs.map +1 -1
- package/dist/components/link-popover/link-popover.mjs +1 -1
- package/dist/components/link-popover/link-popover.mjs.map +1 -1
- package/dist/hooks/use-markdown-editor.cjs +9 -0
- package/dist/hooks/use-markdown-editor.cjs.map +1 -1
- package/dist/hooks/use-markdown-editor.d.cts +0 -1
- package/dist/hooks/use-markdown-editor.d.ts +0 -1
- package/dist/hooks/use-markdown-editor.mjs +9 -0
- package/dist/hooks/use-markdown-editor.mjs.map +1 -1
- package/dist/notra-editor.cjs +3 -12
- package/dist/notra-editor.cjs.map +1 -1
- package/dist/notra-editor.d.cts +1 -7
- package/dist/notra-editor.d.ts +1 -7
- package/dist/notra-editor.mjs +3 -12
- package/dist/notra-editor.mjs.map +1 -1
- package/dist/notra-reader.cjs +1 -3
- package/dist/notra-reader.cjs.map +1 -1
- package/dist/notra-reader.d.cts +1 -3
- package/dist/notra-reader.d.ts +1 -3
- package/dist/notra-reader.mjs +1 -3
- package/dist/notra-reader.mjs.map +1 -1
- package/dist/styles/globals.css +3 -1
- package/dist/themes/default/editor.css +3020 -299
- package/dist/themes/default/reader.css +965 -10
- package/package.json +3 -3
- package/dist/themes/default/shared.css +0 -609
|
@@ -91,7 +91,7 @@ const LinkPopover = (0, import_react.forwardRef)(
|
|
|
91
91
|
import_popover.PopoverContent,
|
|
92
92
|
{
|
|
93
93
|
align: "start",
|
|
94
|
-
className: "nt:flex nt:w-auto nt:items-center nt:gap-1 nt:p-1",
|
|
94
|
+
className: "nt:flex nt:w-auto nt:flex-row nt:items-center nt:gap-1 nt:p-1",
|
|
95
95
|
children: [
|
|
96
96
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
97
97
|
import_input.Input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/link-popover/link-popover.tsx"],"sourcesContent":["'use client';\n\nimport {\n\tCornerDownLeft,\n\tExternalLink,\n\tLink as LinkIcon,\n\tTrash2\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { useLinkPopover } from './use-link-popover';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { Separator } from '../ui/separator';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface LinkPopoverProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nexport const LinkPopover = forwardRef<HTMLButtonElement, LinkPopoverProps>(\n\t({ editor, ...buttonProps }, ref) => {\n\t\tconst [isOpen, setIsOpen] = useState(false);\n\n\t\tconst {\n\t\t\turl,\n\t\t\tsetUrl,\n\t\t\tisActive,\n\t\t\tcanSet,\n\t\t\tsetLink,\n\t\t\tremoveLink,\n\t\t\topenLink,\n\t\t\twasSelectionMove\n\t\t} = useLinkPopover({ editor });\n\n\t\t// Auto-open popover when cursor moves onto an existing link (selection-only transaction)\n\t\tuseEffect(() => {\n\t\t\tif (isActive && wasSelectionMove) {\n\t\t\t\tsetIsOpen(true);\n\t\t\t}\n\t\t}, [isActive, wasSelectionMove]);\n\n\t\tconst handleSetLink = useCallback(() => {\n\t\t\tsetLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [setLink]);\n\n\t\tconst handleRemoveLink = useCallback(() => {\n\t\t\tremoveLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [removeLink]);\n\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\thandleSetLink();\n\t\t\t\t}\n\t\t\t},\n\t\t\t[handleSetLink]\n\t\t);\n\n\t\treturn (\n\t\t\t<Popover open={isOpen} onOpenChange={setIsOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\taria-label=\"Link\"\n\t\t\t\t\t\taria-pressed={isActive}\n\t\t\t\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\t\t\t\tdisabled={!canSet}\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t{...buttonProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LinkIcon\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tisActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"nt:flex nt:w-auto nt:items-center nt:gap-1 nt:p-1\"\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tclassName=\"nt:h-7 nt:min-w-48 nt:border-none nt:shadow-none nt:focus-visible:ring-0\"\n\t\t\t\t\t\tplaceholder=\"Paste a link...\"\n\t\t\t\t\t\ttype=\"url\"\n\t\t\t\t\t\tvalue={url}\n\t\t\t\t\t\tonChange={(e) => setUrl(e.target.value)}\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Apply link\"\n\t\t\t\t\t\tdisabled={!url && !isActive}\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleSetLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<CornerDownLeft />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Separator className=\"nt:h-5\" orientation=\"vertical\" />\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Open link in new window\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={openLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ExternalLink />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Remove link\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleRemoveLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Trash2 />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t);\n\t}\n);\n\nLinkPopover.displayName = 'LinkPopover';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkFM;AAhFN,0BAKO;AACP,mBAA6D;AAE7D,8BAA+B;AAC/B,oBAAuB;AACvB,mBAAsB;AACtB,qBAAwD;AACxD,uBAA0B;AAWnB,MAAM,kBAAc;AAAA,EAC1B,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,QAAQ;AACpC,UAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,QAAI,wCAAe,EAAE,OAAO,CAAC;AAG7B,gCAAU,MAAM;AACf,UAAI,YAAY,kBAAkB;AACjC,kBAAU,IAAI;AAAA,MACf;AAAA,IACD,GAAG,CAAC,UAAU,gBAAgB,CAAC;AAE/B,UAAM,oBAAgB,0BAAY,MAAM;AACvC,cAAQ;AACR,gBAAU,KAAK;AAAA,IAChB,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,uBAAmB,0BAAY,MAAM;AAC1C,iBAAW;AACX,gBAAU,KAAK;AAAA,IAChB,GAAG,CAAC,UAAU,CAAC;AAEf,UAAM,oBAAgB;AAAA,MACrB,CAAC,UAAiD;AACjD,YAAI,MAAM,QAAQ,SAAS;AAC1B,gBAAM,eAAe;AACrB,wBAAc;AAAA,QACf;AAAA,MACD;AAAA,MACA,CAAC,aAAa;AAAA,IACf;AAEA,WACC,6CAAC,0BAAQ,MAAM,QAAQ,cAAc,WACpC;AAAA,kDAAC,iCAAe,SAAO,MACtB;AAAA,QAAC;AAAA;AAAA,UACA;AAAA,UACA,cAAW;AAAA,UACX,gBAAc;AAAA,UACd,qBAAmB,WAAW,OAAO;AAAA,UACrC,UAAU,CAAC;AAAA,UACX,MAAK;AAAA,UACL,UAAU;AAAA,UACV,MAAK;AAAA,UACL,SAAQ;AAAA,UACP,GAAG;AAAA,UAEJ;AAAA,YAAC,oBAAAA;AAAA,YAAA;AAAA,cACA,WACC,WAAW,wCAAwC;AAAA;AAAA,UAErD;AAAA;AAAA,MACD,GACD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACA,OAAM;AAAA,UACN,WAAU;AAAA,UAEV;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA,WAAS;AAAA,gBACT,WAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,KAAK;AAAA,gBACtC,WAAW;AAAA;AAAA,YACZ;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACA,cAAW;AAAA,gBACX,UAAU,CAAC,OAAO,CAAC;AAAA,gBACnB,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAET,sDAAC,sCAAe;AAAA;AAAA,YACjB;AAAA,YACA,4CAAC,8BAAU,WAAU,UAAS,aAAY,YAAW;AAAA,YACrD;AAAA,cAAC;AAAA;AAAA,gBACA,cAAW;AAAA,gBACX,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAET,sDAAC,oCAAa;AAAA;AAAA,YACf;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACA,cAAW;AAAA,gBACX,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAET,sDAAC,8BAAO;AAAA;AAAA,YACT;AAAA;AAAA;AAAA,MACD;AAAA,OACD;AAAA,EAEF;AACD;AAEA,YAAY,cAAc;","names":["LinkIcon"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/link-popover/link-popover.tsx"],"sourcesContent":["'use client';\n\nimport {\n\tCornerDownLeft,\n\tExternalLink,\n\tLink as LinkIcon,\n\tTrash2\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { useLinkPopover } from './use-link-popover';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { Separator } from '../ui/separator';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface LinkPopoverProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nexport const LinkPopover = forwardRef<HTMLButtonElement, LinkPopoverProps>(\n\t({ editor, ...buttonProps }, ref) => {\n\t\tconst [isOpen, setIsOpen] = useState(false);\n\n\t\tconst {\n\t\t\turl,\n\t\t\tsetUrl,\n\t\t\tisActive,\n\t\t\tcanSet,\n\t\t\tsetLink,\n\t\t\tremoveLink,\n\t\t\topenLink,\n\t\t\twasSelectionMove\n\t\t} = useLinkPopover({ editor });\n\n\t\t// Auto-open popover when cursor moves onto an existing link (selection-only transaction)\n\t\tuseEffect(() => {\n\t\t\tif (isActive && wasSelectionMove) {\n\t\t\t\tsetIsOpen(true);\n\t\t\t}\n\t\t}, [isActive, wasSelectionMove]);\n\n\t\tconst handleSetLink = useCallback(() => {\n\t\t\tsetLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [setLink]);\n\n\t\tconst handleRemoveLink = useCallback(() => {\n\t\t\tremoveLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [removeLink]);\n\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\thandleSetLink();\n\t\t\t\t}\n\t\t\t},\n\t\t\t[handleSetLink]\n\t\t);\n\n\t\treturn (\n\t\t\t<Popover open={isOpen} onOpenChange={setIsOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\taria-label=\"Link\"\n\t\t\t\t\t\taria-pressed={isActive}\n\t\t\t\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\t\t\t\tdisabled={!canSet}\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t{...buttonProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LinkIcon\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tisActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"nt:flex nt:w-auto nt:flex-row nt:items-center nt:gap-1 nt:p-1\"\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tclassName=\"nt:h-7 nt:min-w-48 nt:border-none nt:shadow-none nt:focus-visible:ring-0\"\n\t\t\t\t\t\tplaceholder=\"Paste a link...\"\n\t\t\t\t\t\ttype=\"url\"\n\t\t\t\t\t\tvalue={url}\n\t\t\t\t\t\tonChange={(e) => setUrl(e.target.value)}\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Apply link\"\n\t\t\t\t\t\tdisabled={!url && !isActive}\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleSetLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<CornerDownLeft />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Separator className=\"nt:h-5\" orientation=\"vertical\" />\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Open link in new window\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={openLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ExternalLink />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Remove link\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleRemoveLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Trash2 />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t);\n\t}\n);\n\nLinkPopover.displayName = 'LinkPopover';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkFM;AAhFN,0BAKO;AACP,mBAA6D;AAE7D,8BAA+B;AAC/B,oBAAuB;AACvB,mBAAsB;AACtB,qBAAwD;AACxD,uBAA0B;AAWnB,MAAM,kBAAc;AAAA,EAC1B,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,QAAQ;AACpC,UAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,QAAI,wCAAe,EAAE,OAAO,CAAC;AAG7B,gCAAU,MAAM;AACf,UAAI,YAAY,kBAAkB;AACjC,kBAAU,IAAI;AAAA,MACf;AAAA,IACD,GAAG,CAAC,UAAU,gBAAgB,CAAC;AAE/B,UAAM,oBAAgB,0BAAY,MAAM;AACvC,cAAQ;AACR,gBAAU,KAAK;AAAA,IAChB,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,uBAAmB,0BAAY,MAAM;AAC1C,iBAAW;AACX,gBAAU,KAAK;AAAA,IAChB,GAAG,CAAC,UAAU,CAAC;AAEf,UAAM,oBAAgB;AAAA,MACrB,CAAC,UAAiD;AACjD,YAAI,MAAM,QAAQ,SAAS;AAC1B,gBAAM,eAAe;AACrB,wBAAc;AAAA,QACf;AAAA,MACD;AAAA,MACA,CAAC,aAAa;AAAA,IACf;AAEA,WACC,6CAAC,0BAAQ,MAAM,QAAQ,cAAc,WACpC;AAAA,kDAAC,iCAAe,SAAO,MACtB;AAAA,QAAC;AAAA;AAAA,UACA;AAAA,UACA,cAAW;AAAA,UACX,gBAAc;AAAA,UACd,qBAAmB,WAAW,OAAO;AAAA,UACrC,UAAU,CAAC;AAAA,UACX,MAAK;AAAA,UACL,UAAU;AAAA,UACV,MAAK;AAAA,UACL,SAAQ;AAAA,UACP,GAAG;AAAA,UAEJ;AAAA,YAAC,oBAAAA;AAAA,YAAA;AAAA,cACA,WACC,WAAW,wCAAwC;AAAA;AAAA,UAErD;AAAA;AAAA,MACD,GACD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACA,OAAM;AAAA,UACN,WAAU;AAAA,UAEV;AAAA;AAAA,cAAC;AAAA;AAAA,gBACA,WAAS;AAAA,gBACT,WAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,KAAK;AAAA,gBACtC,WAAW;AAAA;AAAA,YACZ;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACA,cAAW;AAAA,gBACX,UAAU,CAAC,OAAO,CAAC;AAAA,gBACnB,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAET,sDAAC,sCAAe;AAAA;AAAA,YACjB;AAAA,YACA,4CAAC,8BAAU,WAAU,UAAS,aAAY,YAAW;AAAA,YACrD;AAAA,cAAC;AAAA;AAAA,gBACA,cAAW;AAAA,gBACX,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAET,sDAAC,oCAAa;AAAA;AAAA,YACf;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACA,cAAW;AAAA,gBACX,MAAK;AAAA,gBACL,UAAU;AAAA,gBACV,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,SAAS;AAAA,gBAET,sDAAC,8BAAO;AAAA;AAAA,YACT;AAAA;AAAA;AAAA,MACD;AAAA,OACD;AAAA,EAEF;AACD;AAEA,YAAY,cAAc;","names":["LinkIcon"]}
|
|
@@ -73,7 +73,7 @@ const LinkPopover = forwardRef(
|
|
|
73
73
|
PopoverContent,
|
|
74
74
|
{
|
|
75
75
|
align: "start",
|
|
76
|
-
className: "nt:flex nt:w-auto nt:items-center nt:gap-1 nt:p-1",
|
|
76
|
+
className: "nt:flex nt:w-auto nt:flex-row nt:items-center nt:gap-1 nt:p-1",
|
|
77
77
|
children: [
|
|
78
78
|
/* @__PURE__ */ jsx(
|
|
79
79
|
Input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/link-popover/link-popover.tsx"],"sourcesContent":["'use client';\n\nimport {\n\tCornerDownLeft,\n\tExternalLink,\n\tLink as LinkIcon,\n\tTrash2\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { useLinkPopover } from './use-link-popover';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { Separator } from '../ui/separator';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface LinkPopoverProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nexport const LinkPopover = forwardRef<HTMLButtonElement, LinkPopoverProps>(\n\t({ editor, ...buttonProps }, ref) => {\n\t\tconst [isOpen, setIsOpen] = useState(false);\n\n\t\tconst {\n\t\t\turl,\n\t\t\tsetUrl,\n\t\t\tisActive,\n\t\t\tcanSet,\n\t\t\tsetLink,\n\t\t\tremoveLink,\n\t\t\topenLink,\n\t\t\twasSelectionMove\n\t\t} = useLinkPopover({ editor });\n\n\t\t// Auto-open popover when cursor moves onto an existing link (selection-only transaction)\n\t\tuseEffect(() => {\n\t\t\tif (isActive && wasSelectionMove) {\n\t\t\t\tsetIsOpen(true);\n\t\t\t}\n\t\t}, [isActive, wasSelectionMove]);\n\n\t\tconst handleSetLink = useCallback(() => {\n\t\t\tsetLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [setLink]);\n\n\t\tconst handleRemoveLink = useCallback(() => {\n\t\t\tremoveLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [removeLink]);\n\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\thandleSetLink();\n\t\t\t\t}\n\t\t\t},\n\t\t\t[handleSetLink]\n\t\t);\n\n\t\treturn (\n\t\t\t<Popover open={isOpen} onOpenChange={setIsOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\taria-label=\"Link\"\n\t\t\t\t\t\taria-pressed={isActive}\n\t\t\t\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\t\t\t\tdisabled={!canSet}\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t{...buttonProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LinkIcon\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tisActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"nt:flex nt:w-auto nt:items-center nt:gap-1 nt:p-1\"\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tclassName=\"nt:h-7 nt:min-w-48 nt:border-none nt:shadow-none nt:focus-visible:ring-0\"\n\t\t\t\t\t\tplaceholder=\"Paste a link...\"\n\t\t\t\t\t\ttype=\"url\"\n\t\t\t\t\t\tvalue={url}\n\t\t\t\t\t\tonChange={(e) => setUrl(e.target.value)}\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Apply link\"\n\t\t\t\t\t\tdisabled={!url && !isActive}\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleSetLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<CornerDownLeft />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Separator className=\"nt:h-5\" orientation=\"vertical\" />\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Open link in new window\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={openLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ExternalLink />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Remove link\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleRemoveLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Trash2 />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t);\n\t}\n);\n\nLinkPopover.displayName = 'LinkPopover';\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/link-popover/link-popover.tsx"],"sourcesContent":["'use client';\n\nimport {\n\tCornerDownLeft,\n\tExternalLink,\n\tLink as LinkIcon,\n\tTrash2\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useState } from 'react';\n\nimport { useLinkPopover } from './use-link-popover';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';\nimport { Separator } from '../ui/separator';\n\nimport type { Editor } from '@tiptap/core';\n\nexport interface LinkPopoverProps extends Omit<\n\tReact.ButtonHTMLAttributes<HTMLButtonElement>,\n\t'type'\n> {\n\teditor: Editor | null;\n}\n\nexport const LinkPopover = forwardRef<HTMLButtonElement, LinkPopoverProps>(\n\t({ editor, ...buttonProps }, ref) => {\n\t\tconst [isOpen, setIsOpen] = useState(false);\n\n\t\tconst {\n\t\t\turl,\n\t\t\tsetUrl,\n\t\t\tisActive,\n\t\t\tcanSet,\n\t\t\tsetLink,\n\t\t\tremoveLink,\n\t\t\topenLink,\n\t\t\twasSelectionMove\n\t\t} = useLinkPopover({ editor });\n\n\t\t// Auto-open popover when cursor moves onto an existing link (selection-only transaction)\n\t\tuseEffect(() => {\n\t\t\tif (isActive && wasSelectionMove) {\n\t\t\t\tsetIsOpen(true);\n\t\t\t}\n\t\t}, [isActive, wasSelectionMove]);\n\n\t\tconst handleSetLink = useCallback(() => {\n\t\t\tsetLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [setLink]);\n\n\t\tconst handleRemoveLink = useCallback(() => {\n\t\t\tremoveLink();\n\t\t\tsetIsOpen(false);\n\t\t}, [removeLink]);\n\n\t\tconst handleKeyDown = useCallback(\n\t\t\t(event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\thandleSetLink();\n\t\t\t\t}\n\t\t\t},\n\t\t\t[handleSetLink]\n\t\t);\n\n\t\treturn (\n\t\t\t<Popover open={isOpen} onOpenChange={setIsOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\taria-label=\"Link\"\n\t\t\t\t\t\taria-pressed={isActive}\n\t\t\t\t\t\tdata-active-state={isActive ? 'on' : 'off'}\n\t\t\t\t\t\tdisabled={!canSet}\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t{...buttonProps}\n\t\t\t\t\t>\n\t\t\t\t\t\t<LinkIcon\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tisActive ? 'nt:text-[var(--tt-brand-color-500)]' : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"nt:flex nt:w-auto nt:flex-row nt:items-center nt:gap-1 nt:p-1\"\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tclassName=\"nt:h-7 nt:min-w-48 nt:border-none nt:shadow-none nt:focus-visible:ring-0\"\n\t\t\t\t\t\tplaceholder=\"Paste a link...\"\n\t\t\t\t\t\ttype=\"url\"\n\t\t\t\t\t\tvalue={url}\n\t\t\t\t\t\tonChange={(e) => setUrl(e.target.value)}\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t/>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Apply link\"\n\t\t\t\t\t\tdisabled={!url && !isActive}\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleSetLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<CornerDownLeft />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Separator className=\"nt:h-5\" orientation=\"vertical\" />\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Open link in new window\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={openLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ExternalLink />\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\taria-label=\"Remove link\"\n\t\t\t\t\t\tsize=\"icon-sm\"\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tonClick={handleRemoveLink}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Trash2 />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t);\n\t}\n);\n\nLinkPopover.displayName = 'LinkPopover';\n"],"mappings":"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","names":[]}
|
|
@@ -40,6 +40,15 @@ function useMarkdownEditor({
|
|
|
40
40
|
extensions: import_extensions.editorExtensions,
|
|
41
41
|
editable,
|
|
42
42
|
content: value,
|
|
43
|
+
editorProps: {
|
|
44
|
+
attributes: {
|
|
45
|
+
autocomplete: "off",
|
|
46
|
+
autocorrect: "off",
|
|
47
|
+
autocapitalize: "off",
|
|
48
|
+
"aria-label": "Main content area, start typing to enter text.",
|
|
49
|
+
class: "notra-prose"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
43
52
|
onUpdate({ editor: editor2 }) {
|
|
44
53
|
const md = getMarkdown(
|
|
45
54
|
editor2.storage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-markdown-editor.ts"],"sourcesContent":["import { EditorState } from '@tiptap/pm/state';\nimport { useEditor } from '@tiptap/react';\nimport { useEffect, useRef } from 'react';\n\nimport { editorExtensions } from '../extensions';\n\nimport type { MarkdownStorage } from 'tiptap-markdown';\n\nexport interface UseMarkdownEditorOptions {\n\tvalue: string;\n\tonChange: (value: string) => void;\n\
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-markdown-editor.ts"],"sourcesContent":["import { EditorState } from '@tiptap/pm/state';\nimport { useEditor } from '@tiptap/react';\nimport { useEffect, useRef } from 'react';\n\nimport { editorExtensions } from '../extensions';\n\nimport type { MarkdownStorage } from 'tiptap-markdown';\n\nexport interface UseMarkdownEditorOptions {\n\tvalue: string;\n\tonChange: (value: string) => void;\n\teditable?: boolean;\n}\n\nfunction getMarkdown(storage: Record<string, unknown>): string {\n\treturn (storage.markdown as MarkdownStorage).getMarkdown();\n}\n\nexport function useMarkdownEditor({\n\tvalue,\n\tonChange,\n\teditable = true\n}: UseMarkdownEditorOptions) {\n\tconst externalValue = useRef(value);\n\tconst onChangeRef = useRef(onChange);\n\n\tonChangeRef.current = onChange;\n\n\tconst editor = useEditor({\n\t\textensions: editorExtensions,\n\t\teditable,\n\t\tcontent: value,\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\tautocomplete: 'off',\n\t\t\t\tautocorrect: 'off',\n\t\t\t\tautocapitalize: 'off',\n\t\t\t\t'aria-label': 'Main content area, start typing to enter text.',\n\t\t\t\tclass: 'notra-prose'\n\t\t\t}\n\t\t},\n\t\tonUpdate({ editor }) {\n\t\t\tconst md = getMarkdown(\n\t\t\t\teditor.storage as unknown as Record<string, unknown>\n\t\t\t);\n\n\t\t\texternalValue.current = md;\n\t\t\tonChangeRef.current(md);\n\t\t},\n\t\tonCreate({ editor }) {\n\t\t\t// Browser-specific behaviors (MutationObserver, DOM reconciliation)\n\t\t\t// may create unwanted transactions during mount, polluting the history\n\t\t\t// and making undo available before the user has made any changes.\n\t\t\t// Reset the editor state after initialization to ensure a clean history.\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (editor.isDestroyed) return;\n\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst freshState = EditorState.create({\n\t\t\t\t\tdoc: state.doc,\n\t\t\t\t\tselection: state.selection,\n\t\t\t\t\tplugins: state.plugins\n\t\t\t\t});\n\n\t\t\t\teditor.view.updateState(freshState);\n\t\t\t\t// Dispatch empty transaction to notify state listeners (undo/redo buttons)\n\t\t\t\teditor.view.dispatch(editor.view.state.tr);\n\t\t\t}, 0);\n\t\t}\n\t});\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\tif (value === externalValue.current) return;\n\n\t\texternalValue.current = value;\n\t\teditor.commands.setContent(value);\n\t}, [value, editor]);\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\teditor.setEditable(editable);\n\t}, [editable, editor]);\n\n\treturn { editor };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAC5B,mBAA0B;AAC1B,IAAAA,gBAAkC;AAElC,wBAAiC;AAUjC,SAAS,YAAY,SAA0C;AAC9D,SAAQ,QAAQ,SAA6B,YAAY;AAC1D;AAEO,SAAS,kBAAkB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,WAAW;AACZ,GAA6B;AAC5B,QAAM,oBAAgB,sBAAO,KAAK;AAClC,QAAM,kBAAc,sBAAO,QAAQ;AAEnC,cAAY,UAAU;AAEtB,QAAM,aAAS,wBAAU;AAAA,IACxB,YAAY;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,MACZ,YAAY;AAAA,QACX,cAAc;AAAA,QACd,aAAa;AAAA,QACb,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,OAAO;AAAA,MACR;AAAA,IACD;AAAA,IACA,SAAS,EAAE,QAAAC,QAAO,GAAG;AACpB,YAAM,KAAK;AAAA,QACVA,QAAO;AAAA,MACR;AAEA,oBAAc,UAAU;AACxB,kBAAY,QAAQ,EAAE;AAAA,IACvB;AAAA,IACA,SAAS,EAAE,QAAAA,QAAO,GAAG;AAKpB,iBAAW,MAAM;AAChB,YAAIA,QAAO,YAAa;AAExB,cAAM,EAAE,MAAM,IAAIA;AAClB,cAAM,aAAa,yBAAY,OAAO;AAAA,UACrC,KAAK,MAAM;AAAA,UACX,WAAW,MAAM;AAAA,UACjB,SAAS,MAAM;AAAA,QAChB,CAAC;AAED,QAAAA,QAAO,KAAK,YAAY,UAAU;AAElC,QAAAA,QAAO,KAAK,SAASA,QAAO,KAAK,MAAM,EAAE;AAAA,MAC1C,GAAG,CAAC;AAAA,IACL;AAAA,EACD,CAAC;AAED,+BAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,QAAI,UAAU,cAAc,QAAS;AAErC,kBAAc,UAAU;AACxB,WAAO,SAAS,WAAW,KAAK;AAAA,EACjC,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,+BAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,WAAO,YAAY,QAAQ;AAAA,EAC5B,GAAG,CAAC,UAAU,MAAM,CAAC;AAErB,SAAO,EAAE,OAAO;AACjB;","names":["import_react","editor"]}
|
|
@@ -3,7 +3,6 @@ import * as _tiptap_core from '@tiptap/core';
|
|
|
3
3
|
interface UseMarkdownEditorOptions {
|
|
4
4
|
value: string;
|
|
5
5
|
onChange: (value: string) => void;
|
|
6
|
-
placeholder?: string;
|
|
7
6
|
editable?: boolean;
|
|
8
7
|
}
|
|
9
8
|
declare function useMarkdownEditor({ value, onChange, editable }: UseMarkdownEditorOptions): {
|
|
@@ -3,7 +3,6 @@ import * as _tiptap_core from '@tiptap/core';
|
|
|
3
3
|
interface UseMarkdownEditorOptions {
|
|
4
4
|
value: string;
|
|
5
5
|
onChange: (value: string) => void;
|
|
6
|
-
placeholder?: string;
|
|
7
6
|
editable?: boolean;
|
|
8
7
|
}
|
|
9
8
|
declare function useMarkdownEditor({ value, onChange, editable }: UseMarkdownEditorOptions): {
|
|
@@ -17,6 +17,15 @@ function useMarkdownEditor({
|
|
|
17
17
|
extensions: editorExtensions,
|
|
18
18
|
editable,
|
|
19
19
|
content: value,
|
|
20
|
+
editorProps: {
|
|
21
|
+
attributes: {
|
|
22
|
+
autocomplete: "off",
|
|
23
|
+
autocorrect: "off",
|
|
24
|
+
autocapitalize: "off",
|
|
25
|
+
"aria-label": "Main content area, start typing to enter text.",
|
|
26
|
+
class: "notra-prose"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
20
29
|
onUpdate({ editor: editor2 }) {
|
|
21
30
|
const md = getMarkdown(
|
|
22
31
|
editor2.storage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/use-markdown-editor.ts"],"sourcesContent":["import { EditorState } from '@tiptap/pm/state';\nimport { useEditor } from '@tiptap/react';\nimport { useEffect, useRef } from 'react';\n\nimport { editorExtensions } from '../extensions';\n\nimport type { MarkdownStorage } from 'tiptap-markdown';\n\nexport interface UseMarkdownEditorOptions {\n\tvalue: string;\n\tonChange: (value: string) => void;\n\
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/use-markdown-editor.ts"],"sourcesContent":["import { EditorState } from '@tiptap/pm/state';\nimport { useEditor } from '@tiptap/react';\nimport { useEffect, useRef } from 'react';\n\nimport { editorExtensions } from '../extensions';\n\nimport type { MarkdownStorage } from 'tiptap-markdown';\n\nexport interface UseMarkdownEditorOptions {\n\tvalue: string;\n\tonChange: (value: string) => void;\n\teditable?: boolean;\n}\n\nfunction getMarkdown(storage: Record<string, unknown>): string {\n\treturn (storage.markdown as MarkdownStorage).getMarkdown();\n}\n\nexport function useMarkdownEditor({\n\tvalue,\n\tonChange,\n\teditable = true\n}: UseMarkdownEditorOptions) {\n\tconst externalValue = useRef(value);\n\tconst onChangeRef = useRef(onChange);\n\n\tonChangeRef.current = onChange;\n\n\tconst editor = useEditor({\n\t\textensions: editorExtensions,\n\t\teditable,\n\t\tcontent: value,\n\t\teditorProps: {\n\t\t\tattributes: {\n\t\t\t\tautocomplete: 'off',\n\t\t\t\tautocorrect: 'off',\n\t\t\t\tautocapitalize: 'off',\n\t\t\t\t'aria-label': 'Main content area, start typing to enter text.',\n\t\t\t\tclass: 'notra-prose'\n\t\t\t}\n\t\t},\n\t\tonUpdate({ editor }) {\n\t\t\tconst md = getMarkdown(\n\t\t\t\teditor.storage as unknown as Record<string, unknown>\n\t\t\t);\n\n\t\t\texternalValue.current = md;\n\t\t\tonChangeRef.current(md);\n\t\t},\n\t\tonCreate({ editor }) {\n\t\t\t// Browser-specific behaviors (MutationObserver, DOM reconciliation)\n\t\t\t// may create unwanted transactions during mount, polluting the history\n\t\t\t// and making undo available before the user has made any changes.\n\t\t\t// Reset the editor state after initialization to ensure a clean history.\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (editor.isDestroyed) return;\n\n\t\t\t\tconst { state } = editor;\n\t\t\t\tconst freshState = EditorState.create({\n\t\t\t\t\tdoc: state.doc,\n\t\t\t\t\tselection: state.selection,\n\t\t\t\t\tplugins: state.plugins\n\t\t\t\t});\n\n\t\t\t\teditor.view.updateState(freshState);\n\t\t\t\t// Dispatch empty transaction to notify state listeners (undo/redo buttons)\n\t\t\t\teditor.view.dispatch(editor.view.state.tr);\n\t\t\t}, 0);\n\t\t}\n\t});\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\tif (value === externalValue.current) return;\n\n\t\texternalValue.current = value;\n\t\teditor.commands.setContent(value);\n\t}, [value, editor]);\n\n\tuseEffect(() => {\n\t\tif (!editor) return;\n\n\t\teditor.setEditable(editable);\n\t}, [editable, editor]);\n\n\treturn { editor };\n}\n"],"mappings":"AAAA,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,WAAW,cAAc;AAElC,SAAS,wBAAwB;AAUjC,SAAS,YAAY,SAA0C;AAC9D,SAAQ,QAAQ,SAA6B,YAAY;AAC1D;AAEO,SAAS,kBAAkB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,WAAW;AACZ,GAA6B;AAC5B,QAAM,gBAAgB,OAAO,KAAK;AAClC,QAAM,cAAc,OAAO,QAAQ;AAEnC,cAAY,UAAU;AAEtB,QAAM,SAAS,UAAU;AAAA,IACxB,YAAY;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,MACZ,YAAY;AAAA,QACX,cAAc;AAAA,QACd,aAAa;AAAA,QACb,gBAAgB;AAAA,QAChB,cAAc;AAAA,QACd,OAAO;AAAA,MACR;AAAA,IACD;AAAA,IACA,SAAS,EAAE,QAAAA,QAAO,GAAG;AACpB,YAAM,KAAK;AAAA,QACVA,QAAO;AAAA,MACR;AAEA,oBAAc,UAAU;AACxB,kBAAY,QAAQ,EAAE;AAAA,IACvB;AAAA,IACA,SAAS,EAAE,QAAAA,QAAO,GAAG;AAKpB,iBAAW,MAAM;AAChB,YAAIA,QAAO,YAAa;AAExB,cAAM,EAAE,MAAM,IAAIA;AAClB,cAAM,aAAa,YAAY,OAAO;AAAA,UACrC,KAAK,MAAM;AAAA,UACX,WAAW,MAAM;AAAA,UACjB,SAAS,MAAM;AAAA,QAChB,CAAC;AAED,QAAAA,QAAO,KAAK,YAAY,UAAU;AAElC,QAAAA,QAAO,KAAK,SAASA,QAAO,KAAK,MAAM,EAAE;AAAA,MAC1C,GAAG,CAAC;AAAA,IACL;AAAA,EACD,CAAC;AAED,YAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,QAAI,UAAU,cAAc,QAAS;AAErC,kBAAc,UAAU;AACxB,WAAO,SAAS,WAAW,KAAK;AAAA,EACjC,GAAG,CAAC,OAAO,MAAM,CAAC;AAElB,YAAU,MAAM;AACf,QAAI,CAAC,OAAQ;AAEb,WAAO,YAAY,QAAQ;AAAA,EAC5B,GAAG,CAAC,UAAU,MAAM,CAAC;AAErB,SAAO,EAAE,OAAO;AACjB;","names":["editor"]}
|
package/dist/notra-editor.cjs
CHANGED
|
@@ -35,21 +35,12 @@ var import_toolbar = require("./components/toolbar/toolbar");
|
|
|
35
35
|
var import_spacer = require("./components/ui/spacer");
|
|
36
36
|
var import_undo_redo_button = require("./components/undo-redo-button/undo-redo-button");
|
|
37
37
|
var import_use_markdown_editor = require("./hooks/use-markdown-editor");
|
|
38
|
-
function NotraEditor({
|
|
39
|
-
value,
|
|
40
|
-
onChange,
|
|
41
|
-
placeholder,
|
|
42
|
-
readOnly = false,
|
|
43
|
-
className
|
|
44
|
-
}) {
|
|
38
|
+
function NotraEditor({ value, onChange }) {
|
|
45
39
|
const { editor } = (0, import_use_markdown_editor.useMarkdownEditor)({
|
|
46
40
|
value,
|
|
47
|
-
onChange
|
|
48
|
-
placeholder,
|
|
49
|
-
editable: !readOnly
|
|
41
|
+
onChange
|
|
50
42
|
});
|
|
51
|
-
|
|
52
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: classNames, children: [
|
|
43
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "notra notra-editor-wrapper", children: [
|
|
53
44
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_toolbar.Toolbar, { variant: "fixed", children: [
|
|
54
45
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_spacer.Spacer, {}),
|
|
55
46
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_toolbar.ToolbarGroup, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/notra-editor.tsx"],"sourcesContent":["'use client';\n\nimport { EditorContent } from '@tiptap/react';\n\nimport { BlockquoteButton } from './components/blockquote-button/blockquote-button';\nimport { CodeBlockButton } from './components/code-block-button/code-block-button';\nimport { HeadingDropdownMenu } from './components/heading-dropdown-menu/heading-dropdown-menu';\nimport { ImagePopover } from './components/image-popover/image-popover';\nimport { LinkPopover } from './components/link-popover/link-popover';\nimport { ListDropdownMenu } from './components/list-dropdown-menu/list-dropdown-menu';\nimport { MarkButton } from './components/mark-button/mark-button';\nimport {\n\tToolbar,\n\tToolbarGroup,\n\tToolbarSeparator\n} from './components/toolbar/toolbar';\nimport { Spacer } from './components/ui/spacer';\nimport { UndoRedoButton } from './components/undo-redo-button/undo-redo-button';\nimport { useMarkdownEditor } from './hooks/use-markdown-editor';\n\nexport interface NotraEditorProps {\n\t/** Markdown content (source of truth) */\n\tvalue: string;\n\t/** Called when content changes, receives updated Markdown */\n\tonChange: (value: string) => void;\n
|
|
1
|
+
{"version":3,"sources":["../src/notra-editor.tsx"],"sourcesContent":["'use client';\n\nimport { EditorContent } from '@tiptap/react';\n\nimport { BlockquoteButton } from './components/blockquote-button/blockquote-button';\nimport { CodeBlockButton } from './components/code-block-button/code-block-button';\nimport { HeadingDropdownMenu } from './components/heading-dropdown-menu/heading-dropdown-menu';\nimport { ImagePopover } from './components/image-popover/image-popover';\nimport { LinkPopover } from './components/link-popover/link-popover';\nimport { ListDropdownMenu } from './components/list-dropdown-menu/list-dropdown-menu';\nimport { MarkButton } from './components/mark-button/mark-button';\nimport {\n\tToolbar,\n\tToolbarGroup,\n\tToolbarSeparator\n} from './components/toolbar/toolbar';\nimport { Spacer } from './components/ui/spacer';\nimport { UndoRedoButton } from './components/undo-redo-button/undo-redo-button';\nimport { useMarkdownEditor } from './hooks/use-markdown-editor';\n\nexport interface NotraEditorProps {\n\t/** Markdown content (source of truth) */\n\tvalue: string;\n\t/** Called when content changes, receives updated Markdown */\n\tonChange: (value: string) => void;\n}\n\nexport function NotraEditor({ value, onChange }: NotraEditorProps) {\n\tconst { editor } = useMarkdownEditor({\n\t\tvalue,\n\t\tonChange\n\t});\n\n\treturn (\n\t\t<div className=\"notra notra-editor-wrapper\">\n\t\t\t<Toolbar variant=\"fixed\">\n\t\t\t\t<Spacer />\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<UndoRedoButton action=\"undo\" editor={editor} />\n\t\t\t\t\t<UndoRedoButton action=\"redo\" editor={editor} />\n\t\t\t\t</ToolbarGroup>\n\t\t\t\t<ToolbarSeparator />\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<HeadingDropdownMenu editor={editor} levels={[1, 2, 3, 4]} />\n\t\t\t\t\t<ListDropdownMenu\n\t\t\t\t\t\teditor={editor}\n\t\t\t\t\t\ttypes={['bulletList', 'orderedList', 'taskList']}\n\t\t\t\t\t/>\n\t\t\t\t\t<BlockquoteButton editor={editor} />\n\t\t\t\t\t<CodeBlockButton editor={editor} />\n\t\t\t\t</ToolbarGroup>\n\t\t\t\t<ToolbarSeparator />\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<MarkButton editor={editor} type=\"bold\" />\n\t\t\t\t\t<MarkButton editor={editor} type=\"italic\" />\n\t\t\t\t\t<MarkButton editor={editor} type=\"strike\" />\n\t\t\t\t\t<MarkButton editor={editor} type=\"code\" />\n\t\t\t\t\t<LinkPopover editor={editor} />\n\t\t\t\t\t<ImagePopover editor={editor} />\n\t\t\t\t</ToolbarGroup>\n\t\t\t\t<Spacer />\n\t\t\t</Toolbar>\n\t\t\t<EditorContent className=\"notra-editor-content\" editor={editor} />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCI;AAlCJ,mBAA8B;AAE9B,+BAAiC;AACjC,+BAAgC;AAChC,mCAAoC;AACpC,2BAA6B;AAC7B,0BAA4B;AAC5B,gCAAiC;AACjC,yBAA2B;AAC3B,qBAIO;AACP,oBAAuB;AACvB,8BAA+B;AAC/B,iCAAkC;AAS3B,SAAS,YAAY,EAAE,OAAO,SAAS,GAAqB;AAClE,QAAM,EAAE,OAAO,QAAI,8CAAkB;AAAA,IACpC;AAAA,IACA;AAAA,EACD,CAAC;AAED,SACC,6CAAC,SAAI,WAAU,8BACd;AAAA,iDAAC,0BAAQ,SAAQ,SAChB;AAAA,kDAAC,wBAAO;AAAA,MACR,6CAAC,+BACA;AAAA,oDAAC,0CAAe,QAAO,QAAO,QAAgB;AAAA,QAC9C,4CAAC,0CAAe,QAAO,QAAO,QAAgB;AAAA,SAC/C;AAAA,MACA,4CAAC,mCAAiB;AAAA,MAClB,6CAAC,+BACA;AAAA,oDAAC,oDAAoB,QAAgB,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG;AAAA,QAC3D;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,OAAO,CAAC,cAAc,eAAe,UAAU;AAAA;AAAA,QAChD;AAAA,QACA,4CAAC,6CAAiB,QAAgB;AAAA,QAClC,4CAAC,4CAAgB,QAAgB;AAAA,SAClC;AAAA,MACA,4CAAC,mCAAiB;AAAA,MAClB,6CAAC,+BACA;AAAA,oDAAC,iCAAW,QAAgB,MAAK,QAAO;AAAA,QACxC,4CAAC,iCAAW,QAAgB,MAAK,UAAS;AAAA,QAC1C,4CAAC,iCAAW,QAAgB,MAAK,UAAS;AAAA,QAC1C,4CAAC,iCAAW,QAAgB,MAAK,QAAO;AAAA,QACxC,4CAAC,mCAAY,QAAgB;AAAA,QAC7B,4CAAC,qCAAa,QAAgB;AAAA,SAC/B;AAAA,MACA,4CAAC,wBAAO;AAAA,OACT;AAAA,IACA,4CAAC,8BAAc,WAAU,wBAAuB,QAAgB;AAAA,KACjE;AAEF;","names":[]}
|
package/dist/notra-editor.d.cts
CHANGED
|
@@ -5,13 +5,7 @@ interface NotraEditorProps {
|
|
|
5
5
|
value: string;
|
|
6
6
|
/** Called when content changes, receives updated Markdown */
|
|
7
7
|
onChange: (value: string) => void;
|
|
8
|
-
/** Placeholder text shown when editor is empty */
|
|
9
|
-
placeholder?: string;
|
|
10
|
-
/** Disable editing */
|
|
11
|
-
readOnly?: boolean;
|
|
12
|
-
/** Additional CSS class on the wrapper element */
|
|
13
|
-
className?: string;
|
|
14
8
|
}
|
|
15
|
-
declare function NotraEditor({ value, onChange
|
|
9
|
+
declare function NotraEditor({ value, onChange }: NotraEditorProps): react_jsx_runtime.JSX.Element;
|
|
16
10
|
|
|
17
11
|
export { NotraEditor, type NotraEditorProps };
|
package/dist/notra-editor.d.ts
CHANGED
|
@@ -5,13 +5,7 @@ interface NotraEditorProps {
|
|
|
5
5
|
value: string;
|
|
6
6
|
/** Called when content changes, receives updated Markdown */
|
|
7
7
|
onChange: (value: string) => void;
|
|
8
|
-
/** Placeholder text shown when editor is empty */
|
|
9
|
-
placeholder?: string;
|
|
10
|
-
/** Disable editing */
|
|
11
|
-
readOnly?: boolean;
|
|
12
|
-
/** Additional CSS class on the wrapper element */
|
|
13
|
-
className?: string;
|
|
14
8
|
}
|
|
15
|
-
declare function NotraEditor({ value, onChange
|
|
9
|
+
declare function NotraEditor({ value, onChange }: NotraEditorProps): react_jsx_runtime.JSX.Element;
|
|
16
10
|
|
|
17
11
|
export { NotraEditor, type NotraEditorProps };
|
package/dist/notra-editor.mjs
CHANGED
|
@@ -16,21 +16,12 @@ import {
|
|
|
16
16
|
import { Spacer } from "./components/ui/spacer";
|
|
17
17
|
import { UndoRedoButton } from "./components/undo-redo-button/undo-redo-button";
|
|
18
18
|
import { useMarkdownEditor } from "./hooks/use-markdown-editor";
|
|
19
|
-
function NotraEditor({
|
|
20
|
-
value,
|
|
21
|
-
onChange,
|
|
22
|
-
placeholder,
|
|
23
|
-
readOnly = false,
|
|
24
|
-
className
|
|
25
|
-
}) {
|
|
19
|
+
function NotraEditor({ value, onChange }) {
|
|
26
20
|
const { editor } = useMarkdownEditor({
|
|
27
21
|
value,
|
|
28
|
-
onChange
|
|
29
|
-
placeholder,
|
|
30
|
-
editable: !readOnly
|
|
22
|
+
onChange
|
|
31
23
|
});
|
|
32
|
-
|
|
33
|
-
return /* @__PURE__ */ jsxs("div", { className: classNames, children: [
|
|
24
|
+
return /* @__PURE__ */ jsxs("div", { className: "notra notra-editor-wrapper", children: [
|
|
34
25
|
/* @__PURE__ */ jsxs(Toolbar, { variant: "fixed", children: [
|
|
35
26
|
/* @__PURE__ */ jsx(Spacer, {}),
|
|
36
27
|
/* @__PURE__ */ jsxs(ToolbarGroup, { children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/notra-editor.tsx"],"sourcesContent":["'use client';\n\nimport { EditorContent } from '@tiptap/react';\n\nimport { BlockquoteButton } from './components/blockquote-button/blockquote-button';\nimport { CodeBlockButton } from './components/code-block-button/code-block-button';\nimport { HeadingDropdownMenu } from './components/heading-dropdown-menu/heading-dropdown-menu';\nimport { ImagePopover } from './components/image-popover/image-popover';\nimport { LinkPopover } from './components/link-popover/link-popover';\nimport { ListDropdownMenu } from './components/list-dropdown-menu/list-dropdown-menu';\nimport { MarkButton } from './components/mark-button/mark-button';\nimport {\n\tToolbar,\n\tToolbarGroup,\n\tToolbarSeparator\n} from './components/toolbar/toolbar';\nimport { Spacer } from './components/ui/spacer';\nimport { UndoRedoButton } from './components/undo-redo-button/undo-redo-button';\nimport { useMarkdownEditor } from './hooks/use-markdown-editor';\n\nexport interface NotraEditorProps {\n\t/** Markdown content (source of truth) */\n\tvalue: string;\n\t/** Called when content changes, receives updated Markdown */\n\tonChange: (value: string) => void;\n
|
|
1
|
+
{"version":3,"sources":["../src/notra-editor.tsx"],"sourcesContent":["'use client';\n\nimport { EditorContent } from '@tiptap/react';\n\nimport { BlockquoteButton } from './components/blockquote-button/blockquote-button';\nimport { CodeBlockButton } from './components/code-block-button/code-block-button';\nimport { HeadingDropdownMenu } from './components/heading-dropdown-menu/heading-dropdown-menu';\nimport { ImagePopover } from './components/image-popover/image-popover';\nimport { LinkPopover } from './components/link-popover/link-popover';\nimport { ListDropdownMenu } from './components/list-dropdown-menu/list-dropdown-menu';\nimport { MarkButton } from './components/mark-button/mark-button';\nimport {\n\tToolbar,\n\tToolbarGroup,\n\tToolbarSeparator\n} from './components/toolbar/toolbar';\nimport { Spacer } from './components/ui/spacer';\nimport { UndoRedoButton } from './components/undo-redo-button/undo-redo-button';\nimport { useMarkdownEditor } from './hooks/use-markdown-editor';\n\nexport interface NotraEditorProps {\n\t/** Markdown content (source of truth) */\n\tvalue: string;\n\t/** Called when content changes, receives updated Markdown */\n\tonChange: (value: string) => void;\n}\n\nexport function NotraEditor({ value, onChange }: NotraEditorProps) {\n\tconst { editor } = useMarkdownEditor({\n\t\tvalue,\n\t\tonChange\n\t});\n\n\treturn (\n\t\t<div className=\"notra notra-editor-wrapper\">\n\t\t\t<Toolbar variant=\"fixed\">\n\t\t\t\t<Spacer />\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<UndoRedoButton action=\"undo\" editor={editor} />\n\t\t\t\t\t<UndoRedoButton action=\"redo\" editor={editor} />\n\t\t\t\t</ToolbarGroup>\n\t\t\t\t<ToolbarSeparator />\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<HeadingDropdownMenu editor={editor} levels={[1, 2, 3, 4]} />\n\t\t\t\t\t<ListDropdownMenu\n\t\t\t\t\t\teditor={editor}\n\t\t\t\t\t\ttypes={['bulletList', 'orderedList', 'taskList']}\n\t\t\t\t\t/>\n\t\t\t\t\t<BlockquoteButton editor={editor} />\n\t\t\t\t\t<CodeBlockButton editor={editor} />\n\t\t\t\t</ToolbarGroup>\n\t\t\t\t<ToolbarSeparator />\n\t\t\t\t<ToolbarGroup>\n\t\t\t\t\t<MarkButton editor={editor} type=\"bold\" />\n\t\t\t\t\t<MarkButton editor={editor} type=\"italic\" />\n\t\t\t\t\t<MarkButton editor={editor} type=\"strike\" />\n\t\t\t\t\t<MarkButton editor={editor} type=\"code\" />\n\t\t\t\t\t<LinkPopover editor={editor} />\n\t\t\t\t\t<ImagePopover editor={editor} />\n\t\t\t\t</ToolbarGroup>\n\t\t\t\t<Spacer />\n\t\t\t</Toolbar>\n\t\t\t<EditorContent className=\"notra-editor-content\" editor={editor} />\n\t\t</div>\n\t);\n}\n"],"mappings":";AAoCI,cACA,YADA;AAlCJ,SAAS,qBAAqB;AAE9B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AACjC,SAAS,kBAAkB;AAC3B;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAS3B,SAAS,YAAY,EAAE,OAAO,SAAS,GAAqB;AAClE,QAAM,EAAE,OAAO,IAAI,kBAAkB;AAAA,IACpC;AAAA,IACA;AAAA,EACD,CAAC;AAED,SACC,qBAAC,SAAI,WAAU,8BACd;AAAA,yBAAC,WAAQ,SAAQ,SAChB;AAAA,0BAAC,UAAO;AAAA,MACR,qBAAC,gBACA;AAAA,4BAAC,kBAAe,QAAO,QAAO,QAAgB;AAAA,QAC9C,oBAAC,kBAAe,QAAO,QAAO,QAAgB;AAAA,SAC/C;AAAA,MACA,oBAAC,oBAAiB;AAAA,MAClB,qBAAC,gBACA;AAAA,4BAAC,uBAAoB,QAAgB,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG;AAAA,QAC3D;AAAA,UAAC;AAAA;AAAA,YACA;AAAA,YACA,OAAO,CAAC,cAAc,eAAe,UAAU;AAAA;AAAA,QAChD;AAAA,QACA,oBAAC,oBAAiB,QAAgB;AAAA,QAClC,oBAAC,mBAAgB,QAAgB;AAAA,SAClC;AAAA,MACA,oBAAC,oBAAiB;AAAA,MAClB,qBAAC,gBACA;AAAA,4BAAC,cAAW,QAAgB,MAAK,QAAO;AAAA,QACxC,oBAAC,cAAW,QAAgB,MAAK,UAAS;AAAA,QAC1C,oBAAC,cAAW,QAAgB,MAAK,UAAS;AAAA,QAC1C,oBAAC,cAAW,QAAgB,MAAK,QAAO;AAAA,QACxC,oBAAC,eAAY,QAAgB;AAAA,QAC7B,oBAAC,gBAAa,QAAgB;AAAA,SAC/B;AAAA,MACA,oBAAC,UAAO;AAAA,OACT;AAAA,IACA,oBAAC,iBAAc,WAAU,wBAAuB,QAAgB;AAAA,KACjE;AAEF;","names":[]}
|
package/dist/notra-reader.cjs
CHANGED
|
@@ -31,7 +31,6 @@ var import_languages = require("./lib/languages");
|
|
|
31
31
|
var import_markdown_to_json = require("./utils/markdown-to-json");
|
|
32
32
|
function NotraReader({
|
|
33
33
|
content,
|
|
34
|
-
className,
|
|
35
34
|
lowlight = import_code_block.defaultLowlight
|
|
36
35
|
}) {
|
|
37
36
|
const json = (0, import_markdown_to_json.markdownToJSON)(content);
|
|
@@ -66,8 +65,7 @@ function NotraReader({
|
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
});
|
|
69
|
-
|
|
70
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: classNames, children: rendered });
|
|
68
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("article", { className: "notra notra-prose", children: rendered });
|
|
71
69
|
}
|
|
72
70
|
// Annotate the CommonJS export names for ESM import in node:
|
|
73
71
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/notra-reader.tsx"],"sourcesContent":["import { renderToReactElement } from '@tiptap/static-renderer/pm/react';\nimport { type createLowlight } from 'lowlight';\n\nimport { CodeBlockShell } from './components/code-block-view/code-block-shell';\nimport { sharedExtensions } from './extensions';\nimport { defaultLowlight } from './extensions/code-block';\nimport { highlightCodeToHtml } from './lib/highlight-code-to-html';\nimport { getLanguageLabel } from './lib/languages';\nimport { markdownToJSON } from './utils/markdown-to-json';\n\ntype Lowlight = ReturnType<typeof createLowlight>;\n\nexport interface NotraReaderProps {\n\t/** Markdown content to render */\n\tcontent: string;\n\t
|
|
1
|
+
{"version":3,"sources":["../src/notra-reader.tsx"],"sourcesContent":["import { renderToReactElement } from '@tiptap/static-renderer/pm/react';\nimport { type createLowlight } from 'lowlight';\n\nimport { CodeBlockShell } from './components/code-block-view/code-block-shell';\nimport { sharedExtensions } from './extensions';\nimport { defaultLowlight } from './extensions/code-block';\nimport { highlightCodeToHtml } from './lib/highlight-code-to-html';\nimport { getLanguageLabel } from './lib/languages';\nimport { markdownToJSON } from './utils/markdown-to-json';\n\ntype Lowlight = ReturnType<typeof createLowlight>;\n\nexport interface NotraReaderProps {\n\t/** Markdown content to render */\n\tcontent: string;\n\t/**\n\t * Optional lowlight instance for syntax highlighting. Defaults to the same\n\t * `defaultLowlight` (createLowlight(common)) used by `CodeBlockExtension`.\n\t * Pass a custom instance if you configured the editor with\n\t * `createCodeBlockExtension(myLowlight)` and want the reader to highlight\n\t * the same superset of languages.\n\t */\n\tlowlight?: Lowlight;\n}\n\nexport function NotraReader({\n\tcontent,\n\tlowlight = defaultLowlight\n}: NotraReaderProps) {\n\tconst json = markdownToJSON(content);\n\n\tconst rendered = renderToReactElement({\n\t\textensions: sharedExtensions,\n\t\tcontent: json,\n\t\toptions: {\n\t\t\tnodeMapping: {\n\t\t\t\tcodeBlock: ({ node }) => {\n\t\t\t\t\tconst language = (node.attrs.language as string) ?? '';\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<CodeBlockShell\n\t\t\t\t\t\t\tlanguageSlot={<span>{getLanguageLabel(language)}</span>}\n\t\t\t\t\t\t\tvalue={node.textContent}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<code\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t__html: highlightCodeToHtml(\n\t\t\t\t\t\t\t\t\t\tnode.textContent,\n\t\t\t\t\t\t\t\t\t\tlanguage,\n\t\t\t\t\t\t\t\t\t\tlowlight\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tclassName=\"hljs\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</CodeBlockShell>\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\treturn <article className=\"notra notra-prose\">{rendered}</article>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCqB;AAzCrB,mBAAqC;AAGrC,8BAA+B;AAC/B,wBAAiC;AACjC,wBAAgC;AAChC,oCAAoC;AACpC,uBAAiC;AACjC,8BAA+B;AAiBxB,SAAS,YAAY;AAAA,EAC3B;AAAA,EACA,WAAW;AACZ,GAAqB;AACpB,QAAM,WAAO,wCAAe,OAAO;AAEnC,QAAM,eAAW,mCAAqB;AAAA,IACrC,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,SAAS;AAAA,MACR,aAAa;AAAA,QACZ,WAAW,CAAC,EAAE,KAAK,MAAM;AACxB,gBAAM,WAAY,KAAK,MAAM,YAAuB;AAEpD,iBACC;AAAA,YAAC;AAAA;AAAA,cACA,cAAc,4CAAC,UAAM,iDAAiB,QAAQ,GAAE;AAAA,cAChD,OAAO,KAAK;AAAA,cAEZ;AAAA,gBAAC;AAAA;AAAA,kBACA,yBAAyB;AAAA,oBACxB,YAAQ;AAAA,sBACP,KAAK;AAAA,sBACL;AAAA,sBACA;AAAA,oBACD;AAAA,kBACD;AAAA,kBACA,WAAU;AAAA;AAAA,cACX;AAAA;AAAA,UACD;AAAA,QAEF;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO,4CAAC,aAAQ,WAAU,qBAAqB,oBAAS;AACzD;","names":[]}
|
package/dist/notra-reader.d.cts
CHANGED
|
@@ -5,8 +5,6 @@ type Lowlight = ReturnType<typeof createLowlight>;
|
|
|
5
5
|
interface NotraReaderProps {
|
|
6
6
|
/** Markdown content to render */
|
|
7
7
|
content: string;
|
|
8
|
-
/** Additional CSS class on the wrapper element */
|
|
9
|
-
className?: string;
|
|
10
8
|
/**
|
|
11
9
|
* Optional lowlight instance for syntax highlighting. Defaults to the same
|
|
12
10
|
* `defaultLowlight` (createLowlight(common)) used by `CodeBlockExtension`.
|
|
@@ -16,6 +14,6 @@ interface NotraReaderProps {
|
|
|
16
14
|
*/
|
|
17
15
|
lowlight?: Lowlight;
|
|
18
16
|
}
|
|
19
|
-
declare function NotraReader({ content,
|
|
17
|
+
declare function NotraReader({ content, lowlight }: NotraReaderProps): react_jsx_runtime.JSX.Element;
|
|
20
18
|
|
|
21
19
|
export { NotraReader, type NotraReaderProps };
|
package/dist/notra-reader.d.ts
CHANGED
|
@@ -5,8 +5,6 @@ type Lowlight = ReturnType<typeof createLowlight>;
|
|
|
5
5
|
interface NotraReaderProps {
|
|
6
6
|
/** Markdown content to render */
|
|
7
7
|
content: string;
|
|
8
|
-
/** Additional CSS class on the wrapper element */
|
|
9
|
-
className?: string;
|
|
10
8
|
/**
|
|
11
9
|
* Optional lowlight instance for syntax highlighting. Defaults to the same
|
|
12
10
|
* `defaultLowlight` (createLowlight(common)) used by `CodeBlockExtension`.
|
|
@@ -16,6 +14,6 @@ interface NotraReaderProps {
|
|
|
16
14
|
*/
|
|
17
15
|
lowlight?: Lowlight;
|
|
18
16
|
}
|
|
19
|
-
declare function NotraReader({ content,
|
|
17
|
+
declare function NotraReader({ content, lowlight }: NotraReaderProps): react_jsx_runtime.JSX.Element;
|
|
20
18
|
|
|
21
19
|
export { NotraReader, type NotraReaderProps };
|
package/dist/notra-reader.mjs
CHANGED
|
@@ -8,7 +8,6 @@ import { getLanguageLabel } from "./lib/languages";
|
|
|
8
8
|
import { markdownToJSON } from "./utils/markdown-to-json";
|
|
9
9
|
function NotraReader({
|
|
10
10
|
content,
|
|
11
|
-
className,
|
|
12
11
|
lowlight = defaultLowlight
|
|
13
12
|
}) {
|
|
14
13
|
const json = markdownToJSON(content);
|
|
@@ -43,8 +42,7 @@ function NotraReader({
|
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
44
|
});
|
|
46
|
-
|
|
47
|
-
return /* @__PURE__ */ jsx("div", { className: classNames, children: rendered });
|
|
45
|
+
return /* @__PURE__ */ jsx("article", { className: "notra notra-prose", children: rendered });
|
|
48
46
|
}
|
|
49
47
|
export {
|
|
50
48
|
NotraReader
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/notra-reader.tsx"],"sourcesContent":["import { renderToReactElement } from '@tiptap/static-renderer/pm/react';\nimport { type createLowlight } from 'lowlight';\n\nimport { CodeBlockShell } from './components/code-block-view/code-block-shell';\nimport { sharedExtensions } from './extensions';\nimport { defaultLowlight } from './extensions/code-block';\nimport { highlightCodeToHtml } from './lib/highlight-code-to-html';\nimport { getLanguageLabel } from './lib/languages';\nimport { markdownToJSON } from './utils/markdown-to-json';\n\ntype Lowlight = ReturnType<typeof createLowlight>;\n\nexport interface NotraReaderProps {\n\t/** Markdown content to render */\n\tcontent: string;\n\t
|
|
1
|
+
{"version":3,"sources":["../src/notra-reader.tsx"],"sourcesContent":["import { renderToReactElement } from '@tiptap/static-renderer/pm/react';\nimport { type createLowlight } from 'lowlight';\n\nimport { CodeBlockShell } from './components/code-block-view/code-block-shell';\nimport { sharedExtensions } from './extensions';\nimport { defaultLowlight } from './extensions/code-block';\nimport { highlightCodeToHtml } from './lib/highlight-code-to-html';\nimport { getLanguageLabel } from './lib/languages';\nimport { markdownToJSON } from './utils/markdown-to-json';\n\ntype Lowlight = ReturnType<typeof createLowlight>;\n\nexport interface NotraReaderProps {\n\t/** Markdown content to render */\n\tcontent: string;\n\t/**\n\t * Optional lowlight instance for syntax highlighting. Defaults to the same\n\t * `defaultLowlight` (createLowlight(common)) used by `CodeBlockExtension`.\n\t * Pass a custom instance if you configured the editor with\n\t * `createCodeBlockExtension(myLowlight)` and want the reader to highlight\n\t * the same superset of languages.\n\t */\n\tlowlight?: Lowlight;\n}\n\nexport function NotraReader({\n\tcontent,\n\tlowlight = defaultLowlight\n}: NotraReaderProps) {\n\tconst json = markdownToJSON(content);\n\n\tconst rendered = renderToReactElement({\n\t\textensions: sharedExtensions,\n\t\tcontent: json,\n\t\toptions: {\n\t\t\tnodeMapping: {\n\t\t\t\tcodeBlock: ({ node }) => {\n\t\t\t\t\tconst language = (node.attrs.language as string) ?? '';\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<CodeBlockShell\n\t\t\t\t\t\t\tlanguageSlot={<span>{getLanguageLabel(language)}</span>}\n\t\t\t\t\t\t\tvalue={node.textContent}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<code\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t__html: highlightCodeToHtml(\n\t\t\t\t\t\t\t\t\t\tnode.textContent,\n\t\t\t\t\t\t\t\t\t\tlanguage,\n\t\t\t\t\t\t\t\t\t\tlowlight\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tclassName=\"hljs\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</CodeBlockShell>\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\treturn <article className=\"notra notra-prose\">{rendered}</article>;\n}\n"],"mappings":"AAyCqB;AAzCrB,SAAS,4BAA4B;AAGrC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAiBxB,SAAS,YAAY;AAAA,EAC3B;AAAA,EACA,WAAW;AACZ,GAAqB;AACpB,QAAM,OAAO,eAAe,OAAO;AAEnC,QAAM,WAAW,qBAAqB;AAAA,IACrC,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,SAAS;AAAA,MACR,aAAa;AAAA,QACZ,WAAW,CAAC,EAAE,KAAK,MAAM;AACxB,gBAAM,WAAY,KAAK,MAAM,YAAuB;AAEpD,iBACC;AAAA,YAAC;AAAA;AAAA,cACA,cAAc,oBAAC,UAAM,2BAAiB,QAAQ,GAAE;AAAA,cAChD,OAAO,KAAK;AAAA,cAEZ;AAAA,gBAAC;AAAA;AAAA,kBACA,yBAAyB;AAAA,oBACxB,QAAQ;AAAA,sBACP,KAAK;AAAA,sBACL;AAAA,sBACA;AAAA,oBACD;AAAA,kBACD;AAAA,kBACA,WAAU;AAAA;AAAA,cACX;AAAA;AAAA,UACD;AAAA,QAEF;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AAED,SAAO,oBAAC,aAAQ,WAAU,qBAAqB,oBAAS;AACzD;","names":[]}
|
package/dist/styles/globals.css
CHANGED
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
--nt-text-base--line-height: calc(1.5 / 1);
|
|
15
15
|
--nt-font-weight-medium: 500;
|
|
16
16
|
--nt-tracking-widest: 0.1em;
|
|
17
|
-
--nt-radius-lg: var(--nt-radius);
|
|
18
17
|
--nt-blur-xs: 4px;
|
|
19
18
|
--nt-default-transition-duration: 150ms;
|
|
20
19
|
--nt-default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -397,6 +396,9 @@
|
|
|
397
396
|
.nt\:flex-col-reverse {
|
|
398
397
|
flex-direction: column-reverse;
|
|
399
398
|
}
|
|
399
|
+
.nt\:flex-row {
|
|
400
|
+
flex-direction: row;
|
|
401
|
+
}
|
|
400
402
|
.nt\:items-center {
|
|
401
403
|
align-items: center;
|
|
402
404
|
}
|