neuphlo-editor 0.2.0

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/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # neuphlo-editor
2
+
3
+ A lightweight Tiptap preset with a React wrapper.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm i neuphlo-editor
9
+ ```
10
+
11
+ Requires `react` and `react-dom` 18+ in your app.
12
+
13
+ ## Usage (React)
14
+
15
+ ```tsx
16
+ import { Editor } from "neuphlo-editor/react"
17
+
18
+ export default function Page() {
19
+ return <Editor content="<p>Hello</p>" />
20
+ }
21
+ ```
22
+
23
+ The React Editor includes the Neuphlo preset by default. Add more TipTap extensions when needed:
24
+
25
+ ```tsx
26
+ import Placeholder from "@tiptap/extension-placeholder"
27
+
28
+ <Editor
29
+ content="<p>Hello</p>"
30
+ extensions={[Placeholder.configure({ placeholder: "Write something…" })]}
31
+ />
32
+ ```
33
+
34
+ ### Styling
35
+
36
+ - Default behavior:
37
+
38
+ - The component adds the `nph-editor` class by default.
39
+ - Import our minimal stylesheet in your app to activate defaults: `import 'neuphlo-editor/styles.css'` (or `@import 'neuphlo-editor/styles.css';`).
40
+ - Next.js App Router: `app/layout.tsx` or `app/globals.css`
41
+ - Vite/CRA: `src/main.tsx`/`src/index.tsx`
42
+ - The base CSS does not add a border or background; add your own if desired.
43
+
44
+ - Opt out per instance:
45
+
46
+ - `<Editor styled={false} />`
47
+
48
+ - Bring your own styles (Tailwind or CSS):
49
+ - Use `className` to style the content container; use `editorContainerProps` for other DOM props (e.g., `id`, `role`). No styles are injected by the package.
50
+ - You can combine your own classes with the optional stylesheet if you want.
51
+
52
+ Examples:
53
+
54
+ ```tsx
55
+ // Default stylesheet (minimal — no border/background by default)
56
+ import 'neuphlo-editor/styles.css'
57
+
58
+ <Editor />
59
+
60
+ // Tailwind utilities
61
+ <Editor className="min-h-[200px] border rounded-md p-3 outline-none" />
62
+
63
+ // Plain CSS
64
+ <Editor className="my-editor" />
65
+
66
+ /* then in your CSS */
67
+ .my-editor { min-height: 200px; border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; outline: none; }
68
+ .my-editor:focus-within { border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37,99,235,0.15); }
69
+ ```
70
+
71
+ Advanced: pass TipTap options directly (everything maps to TipTap’s `EditorProvider`). Use `className` to style the content container, and `editorContainerProps` for additional DOM attributes:
72
+
73
+ ```tsx
74
+ <Editor
75
+ autofocus
76
+ editable={false}
77
+ editorProps={{ attributes: { spellcheck: 'true' } }}
78
+ editorContainerProps={{ id: 'editor', role: 'textbox' }}
79
+ />
80
+
81
+ // Alternatively, add the class manually via props
82
+ <Editor className="nph-editor" />
83
+ ```
84
+
85
+ ### Editable
86
+
87
+ Control whether the editor is editable (matches TipTap’s `editable` option). When not editable, helpful attributes are added for styling.
88
+
89
+ ```tsx
90
+ <Editor editable={false} />
91
+
92
+
93
+ // With default stylesheet + a visual cue
94
+ import 'neuphlo-editor/styles.css'
95
+
96
+ <Editor editable={false} className="opacity-60" />
97
+
98
+ // You can target the state in CSS if you prefer
99
+ .nph-editor[data-disabled="true"] {
100
+ /_ e.g., make it look disabled _/
101
+ opacity: 0.6;
102
+ }
103
+ ```
104
+
105
+ Notes:
106
+
107
+ - `editable` is forwarded to TipTap.
108
+ - When `editable={false}`, the content element receives `aria-disabled="true"` and `data-disabled="true"`.
109
+
110
+ ## Usage (Core/Headless)
111
+
112
+ Using TipTap core directly? Compose your editor with the preset, then add your own extensions on top:
113
+
114
+ ```ts
115
+ import { Editor } from "@tiptap/core"
116
+ import { NeuphloPreset } from "neuphlo-editor"
117
+ import Placeholder from "@tiptap/extension-placeholder"
118
+
119
+ const editor = new Editor({
120
+ content: "<p>Hello</p>",
121
+ extensions: [
122
+ ...NeuphloPreset,
123
+ Placeholder.configure({ placeholder: "Write something…" }),
124
+ ],
125
+ })
126
+ ```
@@ -0,0 +1,14 @@
1
+ import StarterKit from '@tiptap/starter-kit';
2
+
3
+ // src/preset.ts
4
+ var Preset = [
5
+ StarterKit.configure({
6
+ bulletList: { keepMarks: true },
7
+ orderedList: { keepMarks: true },
8
+ heading: { levels: [1, 2, 3, 4] }
9
+ })
10
+ ];
11
+
12
+ export { Preset };
13
+ //# sourceMappingURL=chunk-XABVYDNO.js.map
14
+ //# sourceMappingURL=chunk-XABVYDNO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/preset.ts"],"names":[],"mappings":";;;AAGO,IAAM,MAAA,GAAsB;AAAA,EACjC,WAAW,SAAA,CAAU;AAAA,IACnB,UAAA,EAAY,EAAE,SAAA,EAAW,IAAA,EAAK;AAAA,IAC9B,WAAA,EAAa,EAAE,SAAA,EAAW,IAAA,EAAK;AAAA,IAC/B,OAAA,EAAS,EAAE,MAAA,EAAQ,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAE,GACjC;AACH","file":"chunk-XABVYDNO.js","sourcesContent":["import type { Extension } from \"@tiptap/core\"\nimport StarterKit from \"@tiptap/starter-kit\"\n\nexport const Preset: Extension[] = [\n StarterKit.configure({\n bulletList: { keepMarks: true },\n orderedList: { keepMarks: true },\n heading: { levels: [1, 2, 3, 4] },\n }),\n]\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var StarterKit = require('@tiptap/starter-kit');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var StarterKit__default = /*#__PURE__*/_interopDefault(StarterKit);
8
+
9
+ // src/preset.ts
10
+ var Preset = [
11
+ StarterKit__default.default.configure({
12
+ bulletList: { keepMarks: true },
13
+ orderedList: { keepMarks: true },
14
+ heading: { levels: [1, 2, 3, 4] }
15
+ })
16
+ ];
17
+
18
+ exports.Preset = Preset;
19
+ //# sourceMappingURL=index.cjs.map
20
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/preset.ts"],"names":["StarterKit"],"mappings":";;;;;;;;;AAGO,IAAM,MAAA,GAAsB;AAAA,EACjCA,4BAAW,SAAA,CAAU;AAAA,IACnB,UAAA,EAAY,EAAE,SAAA,EAAW,IAAA,EAAK;AAAA,IAC9B,WAAA,EAAa,EAAE,SAAA,EAAW,IAAA,EAAK;AAAA,IAC/B,OAAA,EAAS,EAAE,MAAA,EAAQ,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAE,GACjC;AACH","file":"index.cjs","sourcesContent":["import type { Extension } from \"@tiptap/core\"\nimport StarterKit from \"@tiptap/starter-kit\"\n\nexport const Preset: Extension[] = [\n StarterKit.configure({\n bulletList: { keepMarks: true },\n orderedList: { keepMarks: true },\n heading: { levels: [1, 2, 3, 4] },\n }),\n]\n"]}
@@ -0,0 +1,5 @@
1
+ import { Extension } from '@tiptap/core';
2
+
3
+ declare const Preset: Extension[];
4
+
5
+ export { Preset };
@@ -0,0 +1,5 @@
1
+ import { Extension } from '@tiptap/core';
2
+
3
+ declare const Preset: Extension[];
4
+
5
+ export { Preset };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Preset } from './chunk-XABVYDNO.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ var react = require('@tiptap/react');
4
+ var StarterKit = require('@tiptap/starter-kit');
5
+ var clsx = require('clsx');
6
+ var tailwindMerge = require('tailwind-merge');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
+
11
+ var StarterKit__default = /*#__PURE__*/_interopDefault(StarterKit);
12
+
13
+ // src/react/Editor.tsx
14
+ var Preset = [
15
+ StarterKit__default.default.configure({
16
+ bulletList: { keepMarks: true },
17
+ orderedList: { keepMarks: true },
18
+ heading: { levels: [1, 2, 3, 4] }
19
+ })
20
+ ];
21
+ function cn(...inputs) {
22
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
23
+ }
24
+ function Editor({
25
+ styled = true,
26
+ className,
27
+ editorContainerProps,
28
+ extensions = [],
29
+ content,
30
+ onUpdate,
31
+ editorProps,
32
+ editable = true,
33
+ children,
34
+ ...rest
35
+ }) {
36
+ const mergedContainerProps = {
37
+ ...editorContainerProps,
38
+ className: cn(styled && "nph-editor", className)
39
+ };
40
+ const mergedEditorProps = {
41
+ ...editorProps,
42
+ attributes: {
43
+ ...editorProps?.attributes,
44
+ ...!editable ? { "aria-disabled": "true", "data-disabled": "true" } : {}
45
+ }
46
+ };
47
+ return /* @__PURE__ */ jsxRuntime.jsx(
48
+ react.EditorProvider,
49
+ {
50
+ content,
51
+ extensions: [...Preset, ...extensions ?? []],
52
+ onUpdate,
53
+ editorProps: mergedEditorProps,
54
+ editable,
55
+ editorContainerProps: mergedContainerProps,
56
+ ...rest,
57
+ children
58
+ }
59
+ );
60
+ }
61
+
62
+ exports.Editor = Editor;
63
+ //# sourceMappingURL=index.cjs.map
64
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/preset.ts","../../src/react/utils/cn.ts","../../src/react/Editor.tsx"],"names":["StarterKit","twMerge","clsx","jsx","EditorProvider"],"mappings":";;;;;;;;;;;;;AAGO,IAAM,MAAA,GAAsB;AAAA,EACjCA,4BAAW,SAAA,CAAU;AAAA,IACnB,UAAA,EAAY,EAAE,SAAA,EAAW,IAAA,EAAK;AAAA,IAC9B,WAAA,EAAa,EAAE,SAAA,EAAW,IAAA,EAAK;AAAA,IAC/B,OAAA,EAAS,EAAE,MAAA,EAAQ,CAAC,GAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAE,GACjC;AACH,CAAA;ACNO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOC,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACWO,SAAS,MAAA,CAAO;AAAA,EACrB,MAAA,GAAS,IAAA;AAAA,EACT,SAAA;AAAA,EACA,oBAAA;AAAA,EACA,aAAa,EAAC;AAAA,EACd,OAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,MAAM,oBAAA,GAAuB;AAAA,IAC3B,GAAG,oBAAA;AAAA,IACH,SAAA,EAAW,EAAA,CAAG,MAAA,IAAU,YAAA,EAAc,SAAS;AAAA,GACjD;AAEA,EAAA,MAAM,iBAAA,GAAoB;AAAA,IACxB,GAAG,WAAA;AAAA,IACH,UAAA,EAAY;AAAA,MACV,GAAG,WAAA,EAAa,UAAA;AAAA,MAChB,GAAI,CAAC,QAAA,GACD,EAAE,iBAAiB,MAAA,EAAQ,eAAA,EAAiB,MAAA,EAAO,GACnD;AAAC;AACP,GACF;AAEA,EAAA,uBACEC,cAAA;AAAA,IAACC,oBAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,YAAY,CAAC,GAAG,QAAQ,GAAI,UAAA,IAAc,EAAG,CAAA;AAAA,MAC7C,QAAA;AAAA,MACA,WAAA,EAAa,iBAAA;AAAA,MACb,QAAA;AAAA,MACA,oBAAA,EAAsB,oBAAA;AAAA,MACrB,GAAG,IAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ","file":"index.cjs","sourcesContent":["import type { Extension } from \"@tiptap/core\"\nimport StarterKit from \"@tiptap/starter-kit\"\n\nexport const Preset: Extension[] = [\n StarterKit.configure({\n bulletList: { keepMarks: true },\n orderedList: { keepMarks: true },\n heading: { levels: [1, 2, 3, 4] },\n }),\n]\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n","import * as React from \"react\"\nimport { EditorProvider } from \"@tiptap/react\"\nimport type { EditorProviderProps } from \"@tiptap/react\"\nimport { Preset } from \"../preset\"\nimport { cn } from \"./utils/cn\"\n\nexport type EditorProps = Omit<\n EditorProviderProps,\n \"children\" | \"slotBefore\" | \"slotAfter\" | \"editorContainerProps\"\n> & {\n styled?: boolean\n className?: string\n editorContainerProps?: Omit<React.HTMLAttributes<HTMLDivElement>, \"className\">\n children?: React.ReactNode\n}\n\nexport function Editor({\n styled = true,\n className,\n editorContainerProps,\n extensions = [],\n content,\n onUpdate,\n editorProps,\n editable = true,\n children,\n ...rest\n}: EditorProps) {\n const mergedContainerProps = {\n ...editorContainerProps,\n className: cn(styled && \"nph-editor\", className),\n }\n\n const mergedEditorProps = {\n ...editorProps,\n attributes: {\n ...editorProps?.attributes,\n ...(!editable\n ? { \"aria-disabled\": \"true\", \"data-disabled\": \"true\" }\n : {}),\n } as Record<string, string>,\n }\n\n return (\n <EditorProvider\n content={content}\n extensions={[...Preset, ...(extensions ?? [])]}\n onUpdate={onUpdate}\n editorProps={mergedEditorProps}\n editable={editable}\n editorContainerProps={mergedContainerProps}\n {...rest}\n >\n {children}\n </EditorProvider>\n )\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { EditorProviderProps } from '@tiptap/react';
4
+
5
+ type EditorProps = Omit<EditorProviderProps, "children" | "slotBefore" | "slotAfter" | "editorContainerProps"> & {
6
+ styled?: boolean;
7
+ className?: string;
8
+ editorContainerProps?: Omit<React.HTMLAttributes<HTMLDivElement>, "className">;
9
+ children?: React.ReactNode;
10
+ };
11
+ declare function Editor({ styled, className, editorContainerProps, extensions, content, onUpdate, editorProps, editable, children, ...rest }: EditorProps): react_jsx_runtime.JSX.Element;
12
+
13
+ export { Editor, type EditorProps };
@@ -0,0 +1,13 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { EditorProviderProps } from '@tiptap/react';
4
+
5
+ type EditorProps = Omit<EditorProviderProps, "children" | "slotBefore" | "slotAfter" | "editorContainerProps"> & {
6
+ styled?: boolean;
7
+ className?: string;
8
+ editorContainerProps?: Omit<React.HTMLAttributes<HTMLDivElement>, "className">;
9
+ children?: React.ReactNode;
10
+ };
11
+ declare function Editor({ styled, className, editorContainerProps, extensions, content, onUpdate, editorProps, editable, children, ...rest }: EditorProps): react_jsx_runtime.JSX.Element;
12
+
13
+ export { Editor, type EditorProps };
@@ -0,0 +1,50 @@
1
+ import { Preset } from '../chunk-XABVYDNO.js';
2
+ import { EditorProvider } from '@tiptap/react';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+ function Editor({
11
+ styled = true,
12
+ className,
13
+ editorContainerProps,
14
+ extensions = [],
15
+ content,
16
+ onUpdate,
17
+ editorProps,
18
+ editable = true,
19
+ children,
20
+ ...rest
21
+ }) {
22
+ const mergedContainerProps = {
23
+ ...editorContainerProps,
24
+ className: cn(styled && "nph-editor", className)
25
+ };
26
+ const mergedEditorProps = {
27
+ ...editorProps,
28
+ attributes: {
29
+ ...editorProps?.attributes,
30
+ ...!editable ? { "aria-disabled": "true", "data-disabled": "true" } : {}
31
+ }
32
+ };
33
+ return /* @__PURE__ */ jsx(
34
+ EditorProvider,
35
+ {
36
+ content,
37
+ extensions: [...Preset, ...extensions ?? []],
38
+ onUpdate,
39
+ editorProps: mergedEditorProps,
40
+ editable,
41
+ editorContainerProps: mergedContainerProps,
42
+ ...rest,
43
+ children
44
+ }
45
+ );
46
+ }
47
+
48
+ export { Editor };
49
+ //# sourceMappingURL=index.js.map
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/utils/cn.ts","../../src/react/Editor.tsx"],"names":[],"mappings":";;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACWO,SAAS,MAAA,CAAO;AAAA,EACrB,MAAA,GAAS,IAAA;AAAA,EACT,SAAA;AAAA,EACA,oBAAA;AAAA,EACA,aAAa,EAAC;AAAA,EACd,OAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAgB;AACd,EAAA,MAAM,oBAAA,GAAuB;AAAA,IAC3B,GAAG,oBAAA;AAAA,IACH,SAAA,EAAW,EAAA,CAAG,MAAA,IAAU,YAAA,EAAc,SAAS;AAAA,GACjD;AAEA,EAAA,MAAM,iBAAA,GAAoB;AAAA,IACxB,GAAG,WAAA;AAAA,IACH,UAAA,EAAY;AAAA,MACV,GAAG,WAAA,EAAa,UAAA;AAAA,MAChB,GAAI,CAAC,QAAA,GACD,EAAE,iBAAiB,MAAA,EAAQ,eAAA,EAAiB,MAAA,EAAO,GACnD;AAAC;AACP,GACF;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,OAAA;AAAA,MACA,YAAY,CAAC,GAAG,QAAQ,GAAI,UAAA,IAAc,EAAG,CAAA;AAAA,MAC7C,QAAA;AAAA,MACA,WAAA,EAAa,iBAAA;AAAA,MACb,QAAA;AAAA,MACA,oBAAA,EAAsB,oBAAA;AAAA,MACrB,GAAG,IAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ","file":"index.js","sourcesContent":["import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n","import * as React from \"react\"\nimport { EditorProvider } from \"@tiptap/react\"\nimport type { EditorProviderProps } from \"@tiptap/react\"\nimport { Preset } from \"../preset\"\nimport { cn } from \"./utils/cn\"\n\nexport type EditorProps = Omit<\n EditorProviderProps,\n \"children\" | \"slotBefore\" | \"slotAfter\" | \"editorContainerProps\"\n> & {\n styled?: boolean\n className?: string\n editorContainerProps?: Omit<React.HTMLAttributes<HTMLDivElement>, \"className\">\n children?: React.ReactNode\n}\n\nexport function Editor({\n styled = true,\n className,\n editorContainerProps,\n extensions = [],\n content,\n onUpdate,\n editorProps,\n editable = true,\n children,\n ...rest\n}: EditorProps) {\n const mergedContainerProps = {\n ...editorContainerProps,\n className: cn(styled && \"nph-editor\", className),\n }\n\n const mergedEditorProps = {\n ...editorProps,\n attributes: {\n ...editorProps?.attributes,\n ...(!editable\n ? { \"aria-disabled\": \"true\", \"data-disabled\": \"true\" }\n : {}),\n } as Record<string, string>,\n }\n\n return (\n <EditorProvider\n content={content}\n extensions={[...Preset, ...(extensions ?? [])]}\n onUpdate={onUpdate}\n editorProps={mergedEditorProps}\n editable={editable}\n editorContainerProps={mergedContainerProps}\n {...rest}\n >\n {children}\n </EditorProvider>\n )\n}\n"]}
@@ -0,0 +1,119 @@
1
+ .nph-editor {
2
+ --nph-radius: 8px;
3
+ --nph-text: #111827;
4
+ --nph-text-muted: #6b7280;
5
+ --nph-accent: #2563eb;
6
+
7
+ min-height: 160px;
8
+ border-radius: var(--nph-radius);
9
+ color: var(--nph-text);
10
+ padding: 12px;
11
+ }
12
+
13
+ @media (prefers-color-scheme: dark) {
14
+ .nph-editor {
15
+ --nph-text: #fafafa;
16
+ --nph-text-muted: #a3a3a3;
17
+ --nph-accent: #60a5fa;
18
+ }
19
+ }
20
+
21
+ /* Typography */
22
+ .nph-editor p {
23
+ margin: 0.75em 0;
24
+ }
25
+ .nph-editor h1,
26
+ .nph-editor h2,
27
+ .nph-editor h3,
28
+ .nph-editor h4 {
29
+ margin: 1.2em 0 0.5em;
30
+ line-height: 1.2;
31
+ }
32
+ .nph-editor h1 {
33
+ font-size: 1.875rem;
34
+ font-weight: 700;
35
+ }
36
+ .nph-editor h2 {
37
+ font-size: 1.5rem;
38
+ font-weight: 700;
39
+ }
40
+ .nph-editor h3 {
41
+ font-size: 1.25rem;
42
+ font-weight: 600;
43
+ }
44
+ .nph-editor h4 {
45
+ font-size: 1.125rem;
46
+ font-weight: 600;
47
+ }
48
+
49
+ .nph-editor ul,
50
+ .nph-editor ol {
51
+ padding-left: 1.25rem;
52
+ margin: 0.75em 0;
53
+ }
54
+ .nph-editor ul {
55
+ list-style: disc;
56
+ }
57
+ .nph-editor ol {
58
+ list-style: decimal;
59
+ }
60
+ .nph-editor li {
61
+ margin: 0.25em 0;
62
+ }
63
+
64
+ .nph-editor a {
65
+ color: var(--nph-accent);
66
+ text-decoration: underline;
67
+ }
68
+ .nph-editor strong {
69
+ font-weight: 600;
70
+ }
71
+ .nph-editor em {
72
+ font-style: italic;
73
+ }
74
+
75
+ .nph-editor blockquote {
76
+ margin: 1em 0;
77
+ padding: 0.75em 1em;
78
+ color: var(--nph-text-muted);
79
+ }
80
+
81
+ .nph-editor code {
82
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
83
+ "Liberation Mono", "Courier New", monospace;
84
+ font-size: 0.95em;
85
+ padding: 0.15em 0.35em;
86
+ border-radius: 4px;
87
+ }
88
+ .nph-editor pre {
89
+ padding: 0.75em 1em;
90
+ border-radius: 6px;
91
+ overflow: auto;
92
+ }
93
+ .nph-editor pre code {
94
+ padding: 0;
95
+ background: transparent;
96
+ }
97
+
98
+ .nph-editor hr {
99
+ border: none;
100
+ margin: 1.25em 0;
101
+ }
102
+
103
+ .nph-editor table {
104
+ border-collapse: collapse;
105
+ width: 100%;
106
+ margin: 1em 0;
107
+ }
108
+ .nph-editor th,
109
+ .nph-editor td {
110
+ padding: 0.5em 0.75em;
111
+ text-align: left;
112
+ }
113
+ .nph-editor th {
114
+ }
115
+
116
+ .nph-editor img {
117
+ max-width: 100%;
118
+ height: auto;
119
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "neuphlo-editor",
3
+ "version": "0.2.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./react": {
16
+ "types": "./dist/react/index.d.ts",
17
+ "import": "./dist/react/index.js",
18
+ "require": "./dist/react/index.cjs"
19
+ },
20
+ "./styles.css": {
21
+ "default": "./dist/styles.css"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "sideEffects": [
28
+ "dist/styles.css"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsup src/index.ts src/react/index.ts --dts --format esm,cjs --clean && npm run build:css",
32
+ "build:css": "cp src/styles.css dist/styles.css",
33
+ "dev": "tsup --watch",
34
+ "publish:dry": "npm publish --dry-run",
35
+ "prepack": "npm run build",
36
+ "prepare": "npm run build"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/Neuphlo/neuphlo-editor.git"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/Neuphlo/neuphlo-editor/issues"
47
+ },
48
+ "homepage": "https://github.com/Neuphlo/neuphlo-editor#readme",
49
+ "peerDependencies": {
50
+ "react": ">=18",
51
+ "react-dom": ">=18"
52
+ },
53
+ "dependencies": {
54
+ "@tiptap/core": "^2.4.0",
55
+ "@tiptap/pm": "^2.4.0",
56
+ "@tiptap/react": "^2.4.0",
57
+ "@tiptap/starter-kit": "^2.4.0",
58
+ "clsx": "^2.1.1",
59
+ "tailwind-merge": "^3.3.1"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^22.0.0",
63
+ "@types/react": "^19.1.12",
64
+ "@types/react-dom": "^19.1.9",
65
+ "react": "^18.3.1",
66
+ "react-dom": "^18.3.1",
67
+ "tsup": "^8.1.0",
68
+ "typescript": "^5.6.2"
69
+ }
70
+ }