@melv1c/rich-text-editor 1.0.0 → 1.0.2

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/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { Editor, EditorContent, useEditor } from "@tiptap/react";
2
- import { Button, ButtonGroup, Select, SelectContent, SelectTrigger, ToggleGroup, ToggleGroupItem } from "@melv1c/ui-core";
3
1
  import * as react from "react";
4
2
  import { ComponentProps, HTMLAttributes } from "react";
3
+ import { Button, Toggle } from "@melv1c/ui-core";
4
+ import { Editor, EditorContent, useEditor } from "@tiptap/react";
5
5
  import * as react_jsx_runtime0 from "react/jsx-runtime";
6
6
  import StarterKit from "@tiptap/starter-kit";
7
7
 
@@ -28,13 +28,6 @@ declare function RichTextEditorContent({
28
28
  ...props
29
29
  }: RichTextEditorContentProps): react_jsx_runtime0.JSX.Element;
30
30
  //#endregion
31
- //#region src/context.d.ts
32
- type RichTextEditorContextValue = {
33
- editor: Editor | null;
34
- };
35
- declare const RichTextEditorContext: react.Context<RichTextEditorContextValue | null>;
36
- declare function useRichTextEditor(): RichTextEditorContextValue;
37
- //#endregion
38
31
  //#region src/editor.d.ts
39
32
  type RichTextEditorProps = HTMLAttributes<HTMLDivElement> & {
40
33
  value?: string;
@@ -56,147 +49,6 @@ declare function RichTextEditor({
56
49
  ...props
57
50
  }: RichTextEditorProps): react_jsx_runtime0.JSX.Element;
58
51
  //#endregion
59
- //#region src/groups/formatting-group.d.ts
60
- type RichTextEditorToggleButtonProps$2 = Omit<ComponentProps<typeof ToggleGroupItem>, 'value'>;
61
- type RichTextEditorFormattingItem = 'bold' | 'italic' | 'strike' | 'code';
62
- type RichTextEditorFormattingValue = RichTextEditorFormattingItem[];
63
- declare function BoldButton({
64
- className,
65
- ...props
66
- }: RichTextEditorToggleButtonProps$2): react_jsx_runtime0.JSX.Element;
67
- declare function ItalicButton({
68
- className,
69
- ...props
70
- }: RichTextEditorToggleButtonProps$2): react_jsx_runtime0.JSX.Element;
71
- declare function StrikethroughButton({
72
- className,
73
- ...props
74
- }: RichTextEditorToggleButtonProps$2): react_jsx_runtime0.JSX.Element;
75
- declare function CodeButton({
76
- className,
77
- ...props
78
- }: RichTextEditorToggleButtonProps$2): react_jsx_runtime0.JSX.Element;
79
- type RichTextEditorToggleGroupProps$2 = Omit<ComponentProps<typeof ToggleGroup>, 'type' | 'value' | 'onValueChange'>;
80
- type RichTextEditorFormattingGroupProps = RichTextEditorToggleGroupProps$2 & {
81
- boldProps?: ComponentProps<typeof BoldButton>;
82
- italicProps?: ComponentProps<typeof ItalicButton>;
83
- strikethroughProps?: ComponentProps<typeof StrikethroughButton>;
84
- codeProps?: ComponentProps<typeof CodeButton>;
85
- items?: RichTextEditorFormattingItem[];
86
- defaultValue?: RichTextEditorFormattingValue;
87
- };
88
- declare function RichTextEditorFormattingGroup({
89
- boldProps,
90
- italicProps,
91
- strikethroughProps,
92
- codeProps,
93
- items,
94
- variant,
95
- size,
96
- ...props
97
- }: RichTextEditorFormattingGroupProps): react_jsx_runtime0.JSX.Element;
98
- //#endregion
99
- //#region src/groups/heading-group.d.ts
100
- type RichTextEditorToggleButtonProps$1 = Omit<ComponentProps<typeof ToggleGroupItem>, 'value'>;
101
- type RichTextEditorHeadingLevel = 1 | 2 | 3;
102
- type RichTextEditorHeadingMode = 'toggle' | 'select';
103
- type RichTextEditorHeadingValue = `heading-${RichTextEditorHeadingLevel}` | '';
104
- declare function Heading1Button({
105
- className,
106
- ...props
107
- }: RichTextEditorToggleButtonProps$1): react_jsx_runtime0.JSX.Element;
108
- declare function Heading2Button({
109
- className,
110
- ...props
111
- }: RichTextEditorToggleButtonProps$1): react_jsx_runtime0.JSX.Element;
112
- declare function Heading3Button({
113
- className,
114
- ...props
115
- }: RichTextEditorToggleButtonProps$1): react_jsx_runtime0.JSX.Element;
116
- type RichTextEditorToggleGroupProps$1 = Omit<ComponentProps<typeof ToggleGroup>, 'type' | 'value' | 'onValueChange'>;
117
- type RichTextEditorHeadingSelectProps = Omit<ComponentProps<typeof Select>, 'value' | 'onValueChange'>;
118
- type RichTextEditorHeadingGroupProps = RichTextEditorToggleGroupProps$1 & {
119
- mode?: RichTextEditorHeadingMode;
120
- levels?: RichTextEditorHeadingLevel[];
121
- heading1Props?: ComponentProps<typeof Heading1Button>;
122
- heading2Props?: ComponentProps<typeof Heading2Button>;
123
- heading3Props?: ComponentProps<typeof Heading3Button>;
124
- includeParagraphOption?: boolean;
125
- paragraphLabel?: string;
126
- selectPlaceholder?: string;
127
- selectProps?: RichTextEditorHeadingSelectProps;
128
- selectTriggerProps?: Omit<ComponentProps<typeof SelectTrigger>, 'children'>;
129
- selectContentProps?: ComponentProps<typeof SelectContent>;
130
- defaultValue?: RichTextEditorHeadingValue;
131
- };
132
- declare function RichTextEditorHeadingGroup({
133
- mode,
134
- levels,
135
- heading1Props,
136
- heading2Props,
137
- heading3Props,
138
- includeParagraphOption,
139
- paragraphLabel,
140
- selectPlaceholder,
141
- selectProps,
142
- selectTriggerProps,
143
- selectContentProps,
144
- variant,
145
- size,
146
- ...props
147
- }: RichTextEditorHeadingGroupProps): react_jsx_runtime0.JSX.Element;
148
- //#endregion
149
- //#region src/groups/history-group.d.ts
150
- type RichTextEditorActionButtonProps = ComponentProps<typeof Button>;
151
- type RichTextEditorHistoryItem = 'undo' | 'redo';
152
- declare function UndoButton({
153
- className,
154
- ...props
155
- }: RichTextEditorActionButtonProps): react_jsx_runtime0.JSX.Element;
156
- declare function RedoButton({
157
- className,
158
- ...props
159
- }: RichTextEditorActionButtonProps): react_jsx_runtime0.JSX.Element;
160
- type RichTextEditorHistoryGroupProps = ComponentProps<typeof ButtonGroup> & {
161
- undoProps?: ComponentProps<typeof UndoButton>;
162
- redoProps?: ComponentProps<typeof RedoButton>;
163
- items?: RichTextEditorHistoryItem[];
164
- };
165
- declare function RichTextEditorHistoryGroup({
166
- undoProps,
167
- redoProps,
168
- items,
169
- ...props
170
- }: RichTextEditorHistoryGroupProps): react_jsx_runtime0.JSX.Element;
171
- //#endregion
172
- //#region src/groups/list-group.d.ts
173
- type RichTextEditorToggleButtonProps = Omit<ComponentProps<typeof ToggleGroupItem>, 'value'>;
174
- type RichTextEditorListValue = 'bullet-list' | 'ordered-list' | '';
175
- type RichTextEditorListItem = Exclude<RichTextEditorListValue, ''>;
176
- declare function BulletListButton({
177
- className,
178
- ...props
179
- }: RichTextEditorToggleButtonProps): react_jsx_runtime0.JSX.Element;
180
- declare function OrderedListButton({
181
- className,
182
- ...props
183
- }: RichTextEditorToggleButtonProps): react_jsx_runtime0.JSX.Element;
184
- type RichTextEditorToggleGroupProps = Omit<ComponentProps<typeof ToggleGroup>, 'type' | 'value' | 'onValueChange'>;
185
- type RichTextEditorListGroupProps = RichTextEditorToggleGroupProps & {
186
- bulletListProps?: ComponentProps<typeof BulletListButton>;
187
- orderedListProps?: ComponentProps<typeof OrderedListButton>;
188
- items?: RichTextEditorListItem[];
189
- defaultValue?: RichTextEditorListValue;
190
- };
191
- declare function RichTextEditorListGroup({
192
- bulletListProps,
193
- orderedListProps,
194
- items,
195
- variant,
196
- size,
197
- ...props
198
- }: RichTextEditorListGroupProps): react_jsx_runtime0.JSX.Element;
199
- //#endregion
200
52
  //#region src/built-in.d.ts
201
53
  /**
202
54
  * Built-in editor presets:
@@ -243,11 +95,96 @@ declare const RichTextEditorSimple: typeof RichTextEditorBuiltIn;
243
95
  /** @deprecated Use `RichTextEditorBuiltInProps` instead. */
244
96
  type RichTextEditorSimpleProps = RichTextEditorBuiltInProps;
245
97
  //#endregion
246
- //#region src/toolbar.d.ts
98
+ //#region src/context.d.ts
99
+ type RichTextEditorContextValue = {
100
+ editor: Editor | null;
101
+ };
102
+ declare const RichTextEditorContext: react.Context<RichTextEditorContextValue | null>;
103
+ declare function useRichTextEditor(): RichTextEditorContextValue;
104
+ //#endregion
105
+ //#region src/toolbar/formatting-buttons.d.ts
106
+ type FormattingButtonProps = Omit<ComponentProps<typeof Toggle>, 'pressed' | 'defaultPressed' | 'onPressedChange'>;
107
+ declare function BoldButton({
108
+ children,
109
+ className,
110
+ variant,
111
+ ...props
112
+ }: FormattingButtonProps): react_jsx_runtime0.JSX.Element;
113
+ declare function ItalicButton({
114
+ children,
115
+ className,
116
+ variant,
117
+ ...props
118
+ }: FormattingButtonProps): react_jsx_runtime0.JSX.Element;
119
+ declare function StrikethroughButton({
120
+ children,
121
+ className,
122
+ variant,
123
+ ...props
124
+ }: FormattingButtonProps): react_jsx_runtime0.JSX.Element;
125
+ declare function CodeButton({
126
+ children,
127
+ className,
128
+ variant,
129
+ ...props
130
+ }: FormattingButtonProps): react_jsx_runtime0.JSX.Element;
131
+ //#endregion
132
+ //#region src/toolbar/heading-buttons.d.ts
133
+ type HeadingButtonProps = Omit<ComponentProps<typeof Toggle>, 'pressed' | 'defaultPressed' | 'onPressedChange'>;
134
+ type RichTextEditorHeadingLevel = 1 | 2 | 3;
135
+ declare function Heading1Button(props: HeadingButtonProps): react_jsx_runtime0.JSX.Element;
136
+ declare function Heading2Button(props: HeadingButtonProps): react_jsx_runtime0.JSX.Element;
137
+ declare function Heading3Button(props: HeadingButtonProps): react_jsx_runtime0.JSX.Element;
138
+ type RichTextEditorHeadingSelectProps = {
139
+ levels?: RichTextEditorHeadingLevel[];
140
+ includeParagraphOption?: boolean;
141
+ paragraphLabel?: string;
142
+ selectPlaceholder?: string;
143
+ };
144
+ declare function RichTextEditorHeadingSelect({
145
+ levels,
146
+ includeParagraphOption,
147
+ paragraphLabel,
148
+ selectPlaceholder
149
+ }: RichTextEditorHeadingSelectProps): react_jsx_runtime0.JSX.Element;
150
+ //#endregion
151
+ //#region src/toolbar/history-buttons.d.ts
152
+ type HistoryButtonProps = ComponentProps<typeof Button>;
153
+ declare function UndoButton({
154
+ children,
155
+ className,
156
+ variant,
157
+ size,
158
+ ...props
159
+ }: HistoryButtonProps): react_jsx_runtime0.JSX.Element;
160
+ declare function RedoButton({
161
+ children,
162
+ className,
163
+ variant,
164
+ size,
165
+ ...props
166
+ }: HistoryButtonProps): react_jsx_runtime0.JSX.Element;
167
+ //#endregion
168
+ //#region src/toolbar/list-buttons.d.ts
169
+ type ListButtonProps = Omit<ComponentProps<typeof Toggle>, 'pressed' | 'defaultPressed' | 'onPressedChange'>;
170
+ declare function BulletListButton({
171
+ children,
172
+ className,
173
+ variant,
174
+ ...props
175
+ }: ListButtonProps): react_jsx_runtime0.JSX.Element;
176
+ declare function OrderedListButton({
177
+ children,
178
+ className,
179
+ variant,
180
+ ...props
181
+ }: ListButtonProps): react_jsx_runtime0.JSX.Element;
182
+ //#endregion
183
+ //#region src/toolbar/toolbar.d.ts
247
184
  type RichTextEditorToolbarProps = HTMLAttributes<HTMLDivElement>;
248
185
  declare function RichTextEditorToolbar({
249
186
  className,
250
187
  ...props
251
188
  }: RichTextEditorToolbarProps): react_jsx_runtime0.JSX.Element;
252
189
  //#endregion
253
- export { RichTextEditor, RichTextEditorBuiltIn, RichTextEditorBuiltInProps, RichTextEditorContent, RichTextEditorContentProps, RichTextEditorContext, RichTextEditorContextValue, RichTextEditorFormattingGroup, RichTextEditorFormattingGroupProps, RichTextEditorHeadingGroup, RichTextEditorHeadingGroupProps, RichTextEditorHistoryGroup, RichTextEditorHistoryGroupProps, RichTextEditorListGroup, RichTextEditorListGroupProps, RichTextEditorPreset, RichTextEditorProps, RichTextEditorSimple, RichTextEditorSimpleProps, RichTextEditorToolbar, RichTextEditorToolbarProps, useRichTextEditor };
190
+ export { BoldButton, BulletListButton, CodeButton, FormattingButtonProps, Heading1Button, Heading2Button, Heading3Button, HeadingButtonProps, HistoryButtonProps, ItalicButton, ListButtonProps, OrderedListButton, RedoButton, RichTextEditor, RichTextEditorBuiltIn, RichTextEditorBuiltInProps, RichTextEditorContent, RichTextEditorContentProps, RichTextEditorContext, RichTextEditorContextValue, RichTextEditorHeadingLevel, RichTextEditorHeadingSelect, RichTextEditorHeadingSelectProps, RichTextEditorPreset, RichTextEditorProps, RichTextEditorSimple, RichTextEditorSimpleProps, RichTextEditorToolbar, RichTextEditorToolbarProps, StrikethroughButton, UndoButton, useRichTextEditor };
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { EditorContent, useEditor, useEditorState } from "@tiptap/react";
2
- import { Button, ButtonGroup, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, ToggleGroup, ToggleGroupItem, cn } from "@melv1c/ui-core";
1
+ import { Extension } from "@tiptap/core";
3
2
  import { createContext, useContext, useEffect, useMemo } from "react";
3
+ import { Button, ButtonGroup, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Toggle, cn } from "@melv1c/ui-core";
4
+ import { EditorContent, useEditor, useEditorState } from "@tiptap/react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import StarterKit from "@tiptap/starter-kit";
6
7
  import { Bold, Code, Heading1, Heading2, Heading3, Italic, List, ListOrdered, Redo2, Strikethrough, Undo2 } from "lucide-react";
7
- import { Extension } from "@tiptap/core";
8
8
 
9
9
  //#region src/context.tsx
10
10
  const RichTextEditorContext = createContext(null);
@@ -69,93 +69,78 @@ function RichTextEditor({ children, className, value, defaultValue, onValueChang
69
69
  }
70
70
 
71
71
  //#endregion
72
- //#region src/groups/formatting-group.tsx
73
- const ALL_FORMATTING_ITEMS = [
74
- "bold",
75
- "italic",
76
- "strike",
77
- "code"
78
- ];
79
- function BoldButton({ className, ...props }) {
72
+ //#region src/toolbar/formatting-buttons.tsx
73
+ function BoldButton({ children, className, variant = "outline", ...props }) {
80
74
  const { editor } = useRichTextEditor();
81
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
82
- "data-slot": "rich-text-editor-toggle-button",
83
- value: "bold",
75
+ const isActive = useEditorState({
76
+ editor,
77
+ selector: ({ editor: e }) => e?.isActive("bold") ?? false
78
+ });
79
+ return /* @__PURE__ */ jsx(Toggle, {
84
80
  "aria-label": "Bold",
81
+ pressed: !!isActive,
85
82
  disabled: editor ? !editor.can().chain().focus().toggleBold().run() : true,
86
- onClick: () => editor?.chain().focus().toggleBold().run(),
83
+ onPressedChange: () => editor?.chain().focus().toggleBold().run(),
84
+ variant,
87
85
  className: cn("shadow-none", className),
88
86
  ...props,
89
- children: props.children ?? /* @__PURE__ */ jsx(Bold, {})
87
+ children: children ?? /* @__PURE__ */ jsx(Bold, {})
90
88
  });
91
89
  }
92
- function ItalicButton({ className, ...props }) {
90
+ function ItalicButton({ children, className, variant = "outline", ...props }) {
93
91
  const { editor } = useRichTextEditor();
94
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
95
- "data-slot": "rich-text-editor-toggle-button",
96
- value: "italic",
92
+ const isActive = useEditorState({
93
+ editor,
94
+ selector: ({ editor: e }) => e?.isActive("italic") ?? false
95
+ });
96
+ return /* @__PURE__ */ jsx(Toggle, {
97
97
  "aria-label": "Italic",
98
+ pressed: !!isActive,
98
99
  disabled: editor ? !editor.can().chain().focus().toggleItalic().run() : true,
99
- onClick: () => editor?.chain().focus().toggleItalic().run(),
100
+ onPressedChange: () => editor?.chain().focus().toggleItalic().run(),
101
+ variant,
100
102
  className: cn("shadow-none", className),
101
103
  ...props,
102
- children: props.children ?? /* @__PURE__ */ jsx(Italic, {})
104
+ children: children ?? /* @__PURE__ */ jsx(Italic, {})
103
105
  });
104
106
  }
105
- function StrikethroughButton({ className, ...props }) {
107
+ function StrikethroughButton({ children, className, variant = "outline", ...props }) {
106
108
  const { editor } = useRichTextEditor();
107
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
108
- "data-slot": "rich-text-editor-toggle-button",
109
- value: "strike",
109
+ const isActive = useEditorState({
110
+ editor,
111
+ selector: ({ editor: e }) => e?.isActive("strike") ?? false
112
+ });
113
+ return /* @__PURE__ */ jsx(Toggle, {
110
114
  "aria-label": "Strikethrough",
115
+ pressed: !!isActive,
111
116
  disabled: editor ? !editor.can().chain().focus().toggleStrike().run() : true,
112
- onClick: () => editor?.chain().focus().toggleStrike().run(),
113
- className: cn("shadow-none", className),
114
- ...props,
115
- children: props.children ?? /* @__PURE__ */ jsx(Strikethrough, {})
116
- });
117
- }
118
- function CodeButton({ className, ...props }) {
119
- const { editor } = useRichTextEditor();
120
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
121
- "data-slot": "rich-text-editor-toggle-button",
122
- value: "code",
123
- "aria-label": "Inline code",
124
- disabled: editor ? !editor.can().chain().focus().toggleCode().run() : true,
125
- onClick: () => editor?.chain().focus().toggleCode().run(),
117
+ onPressedChange: () => editor?.chain().focus().toggleStrike().run(),
118
+ variant,
126
119
  className: cn("shadow-none", className),
127
120
  ...props,
128
- children: props.children ?? /* @__PURE__ */ jsx(Code, {})
121
+ children: children ?? /* @__PURE__ */ jsx(Strikethrough, {})
129
122
  });
130
123
  }
131
- function RichTextEditorFormattingGroup({ boldProps, italicProps, strikethroughProps, codeProps, items = ALL_FORMATTING_ITEMS, variant = "outline", size = "sm", ...props }) {
124
+ function CodeButton({ children, className, variant = "outline", ...props }) {
132
125
  const { editor } = useRichTextEditor();
133
- const visibleItems = new Set(items);
134
- const activeValue = useEditorState({
126
+ const isActive = useEditorState({
135
127
  editor,
136
- selector: ({ editor: currentEditor }) => {
137
- if (!currentEditor) return [];
138
- return ALL_FORMATTING_ITEMS.filter((format) => visibleItems.has(format) && currentEditor.isActive(format));
139
- }
128
+ selector: ({ editor: e }) => e?.isActive("code") ?? false
140
129
  });
141
- return /* @__PURE__ */ jsxs(ToggleGroup, {
142
- type: "multiple",
130
+ return /* @__PURE__ */ jsx(Toggle, {
131
+ "aria-label": "Inline code",
132
+ pressed: !!isActive,
133
+ disabled: editor ? !editor.can().chain().focus().toggleCode().run() : true,
134
+ onPressedChange: () => editor?.chain().focus().toggleCode().run(),
143
135
  variant,
144
- size,
145
- "aria-label": "Inline formatting",
146
- value: activeValue ?? [],
136
+ className: cn("shadow-none", className),
147
137
  ...props,
148
- children: [
149
- visibleItems.has("bold") && /* @__PURE__ */ jsx(BoldButton, { ...boldProps }),
150
- visibleItems.has("italic") && /* @__PURE__ */ jsx(ItalicButton, { ...italicProps }),
151
- visibleItems.has("strike") && /* @__PURE__ */ jsx(StrikethroughButton, { ...strikethroughProps }),
152
- visibleItems.has("code") && /* @__PURE__ */ jsx(CodeButton, { ...codeProps })
153
- ]
138
+ children: children ?? /* @__PURE__ */ jsx(Code, {})
154
139
  });
155
140
  }
156
141
 
157
142
  //#endregion
158
- //#region src/groups/heading-group.tsx
143
+ //#region src/toolbar/heading-buttons.tsx
159
144
  const ALL_HEADING_LEVELS = [
160
145
  1,
161
146
  2,
@@ -166,43 +151,71 @@ const HEADING_ICONS = {
166
151
  2: Heading2,
167
152
  3: Heading3
168
153
  };
169
- function HeadingButton({ className, level, ...props }) {
154
+ const HEADING_LABELS = {
155
+ 1: "Heading 1",
156
+ 2: "Heading 2",
157
+ 3: "Heading 3"
158
+ };
159
+ function HeadingButton({ level, children, className, variant = "outline", ...props }) {
170
160
  const { editor } = useRichTextEditor();
171
161
  const Icon = HEADING_ICONS[level];
172
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
173
- "data-slot": "rich-text-editor-toggle-button",
174
- value: `heading-${level}`,
162
+ const isActive = useEditorState({
163
+ editor,
164
+ selector: ({ editor: e }) => e?.isActive("heading", { level }) ?? false
165
+ });
166
+ return /* @__PURE__ */ jsx(Toggle, {
175
167
  "aria-label": `Heading ${level}`,
168
+ pressed: !!isActive,
176
169
  disabled: editor ? !editor.can().chain().focus().toggleHeading({ level }).run() : true,
177
- onClick: () => editor?.chain().focus().toggleHeading({ level }).run(),
170
+ onPressedChange: () => editor?.chain().focus().toggleHeading({ level }).run(),
171
+ variant,
178
172
  className: cn("shadow-none", className),
179
173
  ...props,
180
- children: props.children ?? /* @__PURE__ */ jsx(Icon, {})
174
+ children: children ?? /* @__PURE__ */ jsx(Icon, {})
181
175
  });
182
176
  }
183
- const headingItemLabelMap = {
184
- 1: "Heading 1",
185
- 2: "Heading 2",
186
- 3: "Heading 3"
187
- };
188
- function RichTextEditorHeadingGroup({ mode = "select", levels, heading1Props, heading2Props, heading3Props, includeParagraphOption = true, paragraphLabel = "Paragraph", selectPlaceholder = "Select heading", selectProps, selectTriggerProps, selectContentProps, variant = "outline", size = "sm", ...props }) {
177
+ function Heading1Button(props) {
178
+ return /* @__PURE__ */ jsx(HeadingButton, {
179
+ level: 1,
180
+ ...props
181
+ });
182
+ }
183
+ function Heading2Button(props) {
184
+ return /* @__PURE__ */ jsx(HeadingButton, {
185
+ level: 2,
186
+ ...props
187
+ });
188
+ }
189
+ function Heading3Button(props) {
190
+ return /* @__PURE__ */ jsx(HeadingButton, {
191
+ level: 3,
192
+ ...props
193
+ });
194
+ }
195
+ function RichTextEditorHeadingSelect({ levels, includeParagraphOption = true, paragraphLabel = "Paragraph", selectPlaceholder = "Select heading" }) {
189
196
  const { editor } = useRichTextEditor();
190
197
  const resolvedLevels = levels ?? ALL_HEADING_LEVELS;
191
198
  const visibleLevels = new Set(resolvedLevels);
192
- const headingPropsByLevel = {
193
- 1: heading1Props,
194
- 2: heading2Props,
195
- 3: heading3Props
196
- };
197
199
  const activeValue = useEditorState({
198
200
  editor,
199
- selector: ({ editor: currentEditor }) => {
200
- if (!currentEditor) return "";
201
- for (const level of ALL_HEADING_LEVELS) if (currentEditor.isActive("heading", { level })) return `heading-${level}`;
201
+ selector: ({ editor: e }) => {
202
+ if (!e) return "";
203
+ for (const level of ALL_HEADING_LEVELS) if (e.isActive("heading", { level })) return `heading-${level}`;
202
204
  return "";
203
205
  }
204
206
  });
205
- if (mode === "select") return /* @__PURE__ */ jsxs(Select, {
207
+ const paragraphItem = includeParagraphOption ? {
208
+ value: "paragraph",
209
+ label: paragraphLabel,
210
+ disabled: editor ? !editor.can().chain().focus().setParagraph().run() : true
211
+ } : null;
212
+ const headingItems = ALL_HEADING_LEVELS.filter((level) => visibleLevels.has(level)).map((level) => ({
213
+ value: `heading-${level}`,
214
+ label: HEADING_LABELS[level],
215
+ disabled: editor ? !editor.can().chain().focus().setHeading({ level }).run() : true
216
+ }));
217
+ const items = [...paragraphItem ? [paragraphItem] : [], ...headingItems];
218
+ return /* @__PURE__ */ jsxs(Select, {
206
219
  value: activeValue || (includeParagraphOption ? "paragraph" : void 0),
207
220
  onValueChange: (value) => {
208
221
  if (!editor) return;
@@ -213,132 +226,87 @@ function RichTextEditorHeadingGroup({ mode = "select", levels, heading1Props, he
213
226
  const level = Number(value.replace("heading-", ""));
214
227
  editor.chain().focus().setHeading({ level }).run();
215
228
  },
216
- ...selectProps,
217
229
  children: [/* @__PURE__ */ jsx(SelectTrigger, {
218
230
  "aria-label": "Heading levels",
219
- size: "sm",
220
231
  disabled: !editor,
221
232
  className: "shadow-none",
222
- ...selectTriggerProps,
223
233
  children: /* @__PURE__ */ jsx(SelectValue, { placeholder: selectPlaceholder })
224
- }), /* @__PURE__ */ jsxs(SelectContent, {
225
- ...selectContentProps,
226
- children: [includeParagraphOption && /* @__PURE__ */ jsx(SelectItem, {
227
- value: "paragraph",
228
- disabled: editor ? !editor.can().chain().focus().setParagraph().run() : true,
229
- children: paragraphLabel
230
- }), ALL_HEADING_LEVELS.filter((level) => visibleLevels.has(level)).map((level) => /* @__PURE__ */ jsx(SelectItem, {
231
- value: `heading-${level}`,
232
- disabled: editor ? !editor.can().chain().focus().setHeading({ level }).run() : true,
233
- children: headingItemLabelMap[level]
234
- }, level))]
235
- })]
236
- });
237
- return /* @__PURE__ */ jsx(ToggleGroup, {
238
- type: "single",
239
- variant,
240
- size,
241
- "aria-label": "Heading levels",
242
- value: activeValue ?? "",
243
- ...props,
244
- children: ALL_HEADING_LEVELS.filter((level) => visibleLevels.has(level)).map((level) => /* @__PURE__ */ jsx(HeadingButton, {
245
- level,
246
- ...headingPropsByLevel[level]
247
- }, level))
234
+ }), /* @__PURE__ */ jsx(SelectContent, { children: items.map((item) => /* @__PURE__ */ jsx(SelectItem, {
235
+ value: item.value,
236
+ disabled: item.disabled,
237
+ children: item.label
238
+ }, item.value)) })]
248
239
  });
249
240
  }
250
241
 
251
242
  //#endregion
252
- //#region src/groups/history-group.tsx
253
- function UndoButton({ className, ...props }) {
243
+ //#region src/toolbar/history-buttons.tsx
244
+ function UndoButton({ children, className, variant = "outline", size = "icon", ...props }) {
254
245
  const { editor } = useRichTextEditor();
255
246
  return /* @__PURE__ */ jsx(Button, {
256
- "data-slot": "rich-text-editor-action-button",
257
247
  "aria-label": "Undo",
258
- variant: "outline",
259
- size: "icon-sm",
248
+ variant,
249
+ size,
260
250
  disabled: editor ? !editor.can().chain().focus().undo().run() : true,
261
251
  onClick: () => editor?.chain().focus().undo().run(),
262
252
  className: cn("shadow-none", className),
263
253
  ...props,
264
- children: props.children ?? /* @__PURE__ */ jsx(Undo2, {})
254
+ children: children ?? /* @__PURE__ */ jsx(Undo2, {})
265
255
  });
266
256
  }
267
- function RedoButton({ className, ...props }) {
257
+ function RedoButton({ children, className, variant = "outline", size = "icon", ...props }) {
268
258
  const { editor } = useRichTextEditor();
269
259
  return /* @__PURE__ */ jsx(Button, {
270
- "data-slot": "rich-text-editor-action-button",
271
260
  "aria-label": "Redo",
272
- variant: "outline",
273
- size: "icon-sm",
261
+ variant,
262
+ size,
274
263
  disabled: editor ? !editor.can().chain().focus().redo().run() : true,
275
264
  onClick: () => editor?.chain().focus().redo().run(),
276
265
  className: cn("shadow-none", className),
277
266
  ...props,
278
- children: props.children ?? /* @__PURE__ */ jsx(Redo2, {})
279
- });
280
- }
281
- function RichTextEditorHistoryGroup({ undoProps, redoProps, items = ["undo", "redo"], ...props }) {
282
- const visibleItems = new Set(items);
283
- return /* @__PURE__ */ jsxs(ButtonGroup, {
284
- ...props,
285
- children: [visibleItems.has("undo") && /* @__PURE__ */ jsx(UndoButton, { ...undoProps }), visibleItems.has("redo") && /* @__PURE__ */ jsx(RedoButton, { ...redoProps })]
267
+ children: children ?? /* @__PURE__ */ jsx(Redo2, {})
286
268
  });
287
269
  }
288
270
 
289
271
  //#endregion
290
- //#region src/groups/list-group.tsx
291
- function BulletListButton({ className, ...props }) {
272
+ //#region src/toolbar/list-buttons.tsx
273
+ function BulletListButton({ children, className, variant = "outline", ...props }) {
292
274
  const { editor } = useRichTextEditor();
293
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
294
- "data-slot": "rich-text-editor-toggle-button",
295
- value: "bullet-list",
275
+ const isActive = useEditorState({
276
+ editor,
277
+ selector: ({ editor: e }) => e?.isActive("bulletList") ?? false
278
+ });
279
+ return /* @__PURE__ */ jsx(Toggle, {
296
280
  "aria-label": "Bullet list",
281
+ pressed: !!isActive,
297
282
  disabled: editor ? !editor.can().chain().focus().toggleBulletList().run() : true,
298
- onClick: () => editor?.chain().focus().toggleBulletList().run(),
299
- className: cn("shadow-none", className),
300
- ...props,
301
- children: props.children ?? /* @__PURE__ */ jsx(List, {})
302
- });
303
- }
304
- function OrderedListButton({ className, ...props }) {
305
- const { editor } = useRichTextEditor();
306
- return /* @__PURE__ */ jsx(ToggleGroupItem, {
307
- "data-slot": "rich-text-editor-toggle-button",
308
- value: "ordered-list",
309
- "aria-label": "Ordered list",
310
- disabled: editor ? !editor.can().chain().focus().toggleOrderedList().run() : true,
311
- onClick: () => editor?.chain().focus().toggleOrderedList().run(),
283
+ onPressedChange: () => editor?.chain().focus().toggleBulletList().run(),
284
+ variant,
312
285
  className: cn("shadow-none", className),
313
286
  ...props,
314
- children: props.children ?? /* @__PURE__ */ jsx(ListOrdered, {})
287
+ children: children ?? /* @__PURE__ */ jsx(List, {})
315
288
  });
316
289
  }
317
- function RichTextEditorListGroup({ bulletListProps, orderedListProps, items = ["bullet-list", "ordered-list"], variant = "outline", size = "sm", ...props }) {
290
+ function OrderedListButton({ children, className, variant = "outline", ...props }) {
318
291
  const { editor } = useRichTextEditor();
319
- const visibleItems = new Set(items);
320
- const activeValue = useEditorState({
292
+ const isActive = useEditorState({
321
293
  editor,
322
- selector: ({ editor: currentEditor }) => {
323
- if (!currentEditor) return "";
324
- if (currentEditor.isActive("bulletList")) return "bullet-list";
325
- if (currentEditor.isActive("orderedList")) return "ordered-list";
326
- return "";
327
- }
294
+ selector: ({ editor: e }) => e?.isActive("orderedList") ?? false
328
295
  });
329
- return /* @__PURE__ */ jsxs(ToggleGroup, {
330
- type: "single",
296
+ return /* @__PURE__ */ jsx(Toggle, {
297
+ "aria-label": "Ordered list",
298
+ pressed: !!isActive,
299
+ disabled: editor ? !editor.can().chain().focus().toggleOrderedList().run() : true,
300
+ onPressedChange: () => editor?.chain().focus().toggleOrderedList().run(),
331
301
  variant,
332
- size,
333
- "aria-label": "List type",
334
- value: activeValue ?? "",
302
+ className: cn("shadow-none", className),
335
303
  ...props,
336
- children: [visibleItems.has("bullet-list") && /* @__PURE__ */ jsx(BulletListButton, { ...bulletListProps }), visibleItems.has("ordered-list") && /* @__PURE__ */ jsx(OrderedListButton, { ...orderedListProps })]
304
+ children: children ?? /* @__PURE__ */ jsx(ListOrdered, {})
337
305
  });
338
306
  }
339
307
 
340
308
  //#endregion
341
- //#region src/toolbar.tsx
309
+ //#region src/toolbar/toolbar.tsx
342
310
  function RichTextEditorToolbar({ className, ...props }) {
343
311
  return /* @__PURE__ */ jsx("div", {
344
312
  "data-slot": "rich-text-editor-toolbar",
@@ -369,10 +337,15 @@ function RichTextEditorBuiltIn({ className, contentClassName, toolbarClassName,
369
337
  children: [/* @__PURE__ */ jsxs(RichTextEditorToolbar, {
370
338
  className: toolbarClassName,
371
339
  children: [
372
- (preset === "complete" || preset === "simple") && /* @__PURE__ */ jsx(RichTextEditorHistoryGroup, {}),
373
- preset !== "oneline" && /* @__PURE__ */ jsx(RichTextEditorHeadingGroup, { mode: "select" }),
374
- /* @__PURE__ */ jsx(RichTextEditorFormattingGroup, {}),
375
- preset === "complete" && /* @__PURE__ */ jsx(RichTextEditorListGroup, {})
340
+ (preset === "complete" || preset === "simple") && /* @__PURE__ */ jsxs(ButtonGroup, { children: [/* @__PURE__ */ jsx(UndoButton, {}), /* @__PURE__ */ jsx(RedoButton, {})] }),
341
+ (preset === "complete" || preset === "simple") && /* @__PURE__ */ jsx(RichTextEditorHeadingSelect, {}),
342
+ /* @__PURE__ */ jsxs(ButtonGroup, { children: [
343
+ /* @__PURE__ */ jsx(BoldButton, {}),
344
+ /* @__PURE__ */ jsx(ItalicButton, {}),
345
+ /* @__PURE__ */ jsx(StrikethroughButton, {}),
346
+ preset === "complete" && /* @__PURE__ */ jsx(CodeButton, {})
347
+ ] }),
348
+ preset === "complete" && /* @__PURE__ */ jsxs(ButtonGroup, { children: [/* @__PURE__ */ jsx(BulletListButton, {}), /* @__PURE__ */ jsx(OrderedListButton, {})] })
376
349
  ]
377
350
  }), /* @__PURE__ */ jsx(RichTextEditorContent, {
378
351
  className: contentClassName,
@@ -385,4 +358,4 @@ function RichTextEditorBuiltIn({ className, contentClassName, toolbarClassName,
385
358
  const RichTextEditorSimple = RichTextEditorBuiltIn;
386
359
 
387
360
  //#endregion
388
- export { RichTextEditor, RichTextEditorBuiltIn, RichTextEditorContent, RichTextEditorContext, RichTextEditorFormattingGroup, RichTextEditorHeadingGroup, RichTextEditorHistoryGroup, RichTextEditorListGroup, RichTextEditorSimple, RichTextEditorToolbar, useRichTextEditor };
361
+ export { BoldButton, BulletListButton, CodeButton, Heading1Button, Heading2Button, Heading3Button, ItalicButton, OrderedListButton, RedoButton, RichTextEditor, RichTextEditorBuiltIn, RichTextEditorContent, RichTextEditorContext, RichTextEditorHeadingSelect, RichTextEditorSimple, RichTextEditorToolbar, StrikethroughButton, UndoButton, useRichTextEditor };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melv1c/rich-text-editor",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A rich text editor component for React, built with TipTap and styled with Tailwind CSS.",
5
5
  "repository": {
6
6
  "type": "git",