playbook_ui 18.2.0.pre.rc.2 → 18.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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_background/_background.tsx +3 -1
- data/app/pb_kits/playbook/pb_background/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_caption/_caption.tsx +3 -1
- data/app/pb_kits/playbook/pb_caption/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_container/_container.tsx +3 -1
- data/app/pb_kits/playbook/pb_container/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_currency/_currency.tsx +3 -1
- data/app/pb_kits/playbook/pb_currency/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_dashboard_value/_dashboard_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_dashboard_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_detail/_detail.tsx +3 -1
- data/app/pb_kits/playbook/pb_detail/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_dropdown/_dropdown.tsx +6 -5
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_custom.md +7 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_custom_rails.md +7 -2
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.html.erb +33 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.jsx +42 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_quickpick_enable_time.md +24 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_highlight.jsx +101 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/_dropdown_with_highlight.md +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_dropdown/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_dropdown/index.js +19 -10
- data/app/pb_kits/playbook/pb_dropdown/quickpick/index.ts +60 -18
- data/app/pb_kits/playbook/pb_dropdown/quickpick_helper.rb +92 -3
- data/app/pb_kits/playbook/pb_dropdown/utilities/index.ts +8 -1
- data/app/pb_kits/playbook/pb_dropdown/utilities/quickpickDateSync.ts +137 -0
- data/app/pb_kits/playbook/pb_filter/Filter/InteractiveFilter.tsx +1 -1
- data/app/pb_kits/playbook/pb_highlight/_highlight.tsx +3 -1
- data/app/pb_kits/playbook/pb_highlight/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_icon_value/_icon_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_icon_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_label_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_map/docs/_map_default.md +3 -3
- data/app/pb_kits/playbook/pb_message/_message.tsx +3 -1
- data/app/pb_kits/playbook/pb_message/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_multiple_users/_multiple_users.tsx +3 -1
- data/app/pb_kits/playbook/pb_multiple_users/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_multiple_users_stacked/_multiple_users_stacked.tsx +4 -2
- data/app/pb_kits/playbook/pb_multiple_users_stacked/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +10 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +16 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_attributes.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_default.md +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_focus.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_height.jsx +3 -13
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_inline.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_label.jsx +2 -3
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_markdown_support.jsx +1 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_min_height.jsx +3 -13
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_preview.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_required_indicator.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_simple.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_sticky.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_templates.jsx +1 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_more_extensions.jsx +3 -8
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_more_extensions.md +1 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +2 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.test.js +2 -1
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_advanced.test.js +7 -5
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +15 -4
- data/app/pb_kits/playbook/pb_stat_value/_stat_value.tsx +3 -1
- data/app/pb_kits/playbook/pb_stat_value/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_table/_table.tsx +70 -197
- data/app/pb_kits/playbook/pb_table/index.ts +53 -122
- data/app/pb_kits/playbook/pb_table/styles/_sticky_columns.scss +26 -3
- data/app/pb_kits/playbook/pb_table/utilities/stickyColumns.test.ts +266 -0
- data/app/pb_kits/playbook/pb_table/utilities/stickyColumns.ts +145 -0
- data/app/pb_kits/playbook/pb_title_count/_title_count.tsx +3 -1
- data/app/pb_kits/playbook/pb_title_count/kit.schema.json +1 -0
- data/app/pb_kits/playbook/pb_title_detail/_title_detail.tsx +3 -1
- data/app/pb_kits/playbook/pb_title_detail/kit.schema.json +1 -0
- data/app/pb_kits/playbook/utilities/test/globalProps/onClick.test.js +237 -0
- data/dist/ai/all-schemas.json +16 -0
- data/dist/ai/forms.json +1 -1
- data/dist/ai/index.json +2 -2
- data/dist/ai/kits/background.schema.json +1 -0
- data/dist/ai/kits/caption.schema.json +1 -0
- data/dist/ai/kits/container.schema.json +1 -0
- data/dist/ai/kits/currency.schema.json +1 -0
- data/dist/ai/kits/dashboard_value.schema.json +1 -0
- data/dist/ai/kits/detail.schema.json +1 -0
- data/dist/ai/kits/highlight.schema.json +1 -0
- data/dist/ai/kits/icon_stat_value.schema.json +1 -0
- data/dist/ai/kits/icon_value.schema.json +1 -0
- data/dist/ai/kits/label_value.schema.json +1 -0
- data/dist/ai/kits/message.schema.json +1 -0
- data/dist/ai/kits/multiple_users.schema.json +1 -0
- data/dist/ai/kits/multiple_users_stacked.schema.json +1 -0
- data/dist/ai/kits/stat_value.schema.json +1 -0
- data/dist/ai/kits/title_count.schema.json +1 -0
- data/dist/ai/kits/title_detail.schema.json +1 -0
- data/dist/ai/playgrounds/rich_text_editor.json +1 -1
- data/dist/chunks/{_detail-BqqzPTNr.js → _detail-Bsvl694i.js} +2 -2
- data/dist/chunks/{_pb_line_graph-BGyCJjgG.js → _pb_line_graph-Du7xE9vl.js} +1 -1
- data/dist/chunks/_table-Bf6LGyL9.js +1 -0
- data/dist/chunks/_typeahead-w6S5Vx4b.js +1 -0
- data/dist/chunks/{globalProps-K1DCn3il.js → globalProps-B120NbSJ.js} +1 -1
- data/dist/chunks/{lib-7vm9BMqp.js → lib-Buo6zHEw.js} +1 -1
- data/dist/chunks/quickpickDateSync-DLDx4zce.js +1 -0
- data/dist/chunks/{time_picker_helper-BZutIzB3.js → time_picker_helper-CYGg0UQ0.js} +1 -1
- data/dist/chunks/vendor.js +2 -2
- data/dist/playbook-rails-react-bindings.js +1 -1
- data/dist/playbook-rails.js +1 -1
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +19 -13
- data/dist/chunks/_table-CEZU0qUK.js +0 -1
- data/dist/chunks/_typeahead-C7iPR5ZF.js +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import classnames from 'classnames'
|
|
3
3
|
|
|
4
|
-
import { globalProps } from '../utilities/globalProps'
|
|
5
4
|
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from '../utilities/props'
|
|
5
|
+
import { globalProps } from '../utilities/globalProps'
|
|
6
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
6
7
|
|
|
7
8
|
import Avatar from '../pb_avatar/_avatar'
|
|
8
9
|
import Badge from '../pb_badge/_badge'
|
|
@@ -17,7 +18,7 @@ type MultipleUsersStackedProps = {
|
|
|
17
18
|
size?: "md" | "lg" | "sm" | "xl"
|
|
18
19
|
users: Array<{ [key: string]: string }>,
|
|
19
20
|
variant: "default" | "bubble",
|
|
20
|
-
}
|
|
21
|
+
} & GlobalEventProps
|
|
21
22
|
|
|
22
23
|
const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
|
|
23
24
|
const {
|
|
@@ -132,6 +133,7 @@ const MultipleUsersStacked = (props: MultipleUsersStackedProps) => {
|
|
|
132
133
|
{...ariaProps}
|
|
133
134
|
{...dataProps}
|
|
134
135
|
{...htmlProps}
|
|
136
|
+
{...globalEventProps(props)}
|
|
135
137
|
className={classes}
|
|
136
138
|
id={id}
|
|
137
139
|
>
|
|
@@ -54,9 +54,15 @@ const popoverReference = (
|
|
|
54
54
|
paddingTop={extensions.length > 1 ? "xs" : "none"}
|
|
55
55
|
variant="subtle"
|
|
56
56
|
>
|
|
57
|
-
{extensions && extensions.map(({ icon, text, onclick, isActive}: any, index: number) =>
|
|
57
|
+
{extensions && extensions.map(({ icon, text, onclick, isActive}: any, index: number) => {
|
|
58
|
+
// TipTap v3: host useEditor no longer re-renders on selection by default.
|
|
59
|
+
// Prefer isActive as a function so EditorToolbar's transaction subscription
|
|
60
|
+
// can refresh custom extension highlights without shouldRerenderOnTransaction.
|
|
61
|
+
const active = typeof isActive === "function" ? isActive() : !!isActive
|
|
62
|
+
|
|
63
|
+
return (
|
|
58
64
|
<NavItem
|
|
59
|
-
className={`pb_tiptap_toolbar_dropdown_list_item ${
|
|
65
|
+
className={`pb_tiptap_toolbar_dropdown_list_item ${active ? "is-active" : ""}`}
|
|
60
66
|
cursor="pointer"
|
|
61
67
|
iconLeft={icon}
|
|
62
68
|
key={`${text}_${index}`}
|
|
@@ -66,7 +72,8 @@ const popoverReference = (
|
|
|
66
72
|
paddingTop='xxs'
|
|
67
73
|
text={text}
|
|
68
74
|
/>
|
|
69
|
-
|
|
75
|
+
)
|
|
76
|
+
})}
|
|
70
77
|
</Nav>
|
|
71
78
|
</PbReactPopover>
|
|
72
79
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useLayoutEffect, useRef, useState } from "react";
|
|
1
|
+
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
2
2
|
import Background from "../../pb_background/_background";
|
|
3
3
|
import Flex from "../../pb_flex/_flex";
|
|
4
4
|
import SectionSeparator from "../../pb_section_separator/_section_separator";
|
|
@@ -72,6 +72,21 @@ const EditorToolbar = ({ editor, extensions, simple, sticky }: any): React.React
|
|
|
72
72
|
const toolbarInnerRef = useRef<HTMLDivElement>(null);
|
|
73
73
|
const stackedAtWidthRef = useRef(0);
|
|
74
74
|
const [toolsStacked, setToolsStacked] = useState(false);
|
|
75
|
+
// TipTap v3 defaults shouldRerenderOnTransaction to false; re-render active states locally.
|
|
76
|
+
const [, setEditorRenderTick] = useState(0);
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!editor) return;
|
|
80
|
+
|
|
81
|
+
const rerenderToolbar = () => setEditorRenderTick((tick) => tick + 1);
|
|
82
|
+
editor.on("selectionUpdate", rerenderToolbar);
|
|
83
|
+
editor.on("transaction", rerenderToolbar);
|
|
84
|
+
|
|
85
|
+
return () => {
|
|
86
|
+
editor.off("selectionUpdate", rerenderToolbar);
|
|
87
|
+
editor.off("transaction", rerenderToolbar);
|
|
88
|
+
};
|
|
89
|
+
}, [editor]);
|
|
75
90
|
|
|
76
91
|
useLayoutEffect(() => {
|
|
77
92
|
if (simple) return;
|
|
@@ -148,11 +148,10 @@
|
|
|
148
148
|
"label": "Advanced",
|
|
149
149
|
"template": "<RichTextEditor\n advancedEditor={editor}{{props}}\n>\n <EditorContent editor={editor} />\n</RichTextEditor>",
|
|
150
150
|
"children": "",
|
|
151
|
-
"wrapper": "const RichTextEditorPlayground = () => {\n const editor = useEditor({\n extensions: [StarterKit
|
|
151
|
+
"wrapper": "const RichTextEditorPlayground = () => {\n const editor = useEditor({\n extensions: [StarterKit.configure({ trailingNode: false })],\n content: 'Add your text here. You can format your text, add links, quotes, and bullets.',\n })\n\n if (!editor) return null\n\n return {{component}}\n}\n\n<RichTextEditorPlayground />",
|
|
152
152
|
"externalImports": [
|
|
153
153
|
"import { useEditor, EditorContent } from '@tiptap/react'",
|
|
154
|
-
"import StarterKit from '@tiptap/starter-kit'"
|
|
155
|
-
"import TipTapLink from '@tiptap/extension-link'"
|
|
154
|
+
"import StarterKit from '@tiptap/starter-kit'"
|
|
156
155
|
]
|
|
157
156
|
}
|
|
158
157
|
}
|
|
@@ -19,11 +19,10 @@
|
|
|
19
19
|
"label": "Advanced",
|
|
20
20
|
"template": "<RichTextEditor\n advancedEditor={editor}{{props}}\n>\n <EditorContent editor={editor} />\n</RichTextEditor>",
|
|
21
21
|
"children": "",
|
|
22
|
-
"wrapper": "const RichTextEditorPlayground = () => {\n const editor = useEditor({\n extensions: [StarterKit
|
|
22
|
+
"wrapper": "const RichTextEditorPlayground = () => {\n const editor = useEditor({\n extensions: [StarterKit.configure({ trailingNode: false })],\n content: 'Add your text here. You can format your text, add links, quotes, and bullets.',\n })\n\n if (!editor) return null\n\n return {{component}}\n}\n\n<RichTextEditorPlayground />",
|
|
23
23
|
"externalImports": [
|
|
24
24
|
"import { useEditor, EditorContent } from '@tiptap/react'",
|
|
25
|
-
"import StarterKit from '@tiptap/starter-kit'"
|
|
26
|
-
"import TipTapLink from '@tiptap/extension-link'"
|
|
25
|
+
"import StarterKit from '@tiptap/starter-kit'"
|
|
27
26
|
]
|
|
28
27
|
}
|
|
29
28
|
}
|
data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_attributes.jsx
CHANGED
|
@@ -2,16 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedAttributes = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [
|
|
12
|
-
StarterKit,
|
|
13
|
-
Link
|
|
14
|
-
],
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
15
11
|
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
|
16
12
|
})
|
|
17
13
|
if (!editor) {
|
|
@@ -2,16 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedDefault = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [
|
|
12
|
-
StarterKit,
|
|
13
|
-
Link
|
|
14
|
-
],
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
15
11
|
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
|
16
12
|
})
|
|
17
13
|
if (!editor) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
The advanced variant leverages Tiptap to unlock additional UI options (e.g., consolidated nav toolbar, styling, etc.) as well as several extensions (see [Tiptap docs](https://tiptap.dev/extensions) for more). To leverage this variant, Tiptap __must be installed__ in your project. Complete docs for using the library can be found [here](https://tiptap.dev/). To get started with this variant, see the Code Example below for required imports as well as the basic setup.
|
|
1
|
+
The advanced variant leverages Tiptap to unlock additional UI options (e.g., consolidated nav toolbar, styling, etc.) as well as several extensions (see [Tiptap docs](https://tiptap.dev/extensions) for more). To leverage this variant, Tiptap __must be installed__ in your project at `3.0.7` (same version as Nitro RTE). Complete docs for using the library can be found [here](https://tiptap.dev/). To get started with this variant, see the Code Example below for required imports as well as the basic setup.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
NOTE: Once the Tiptap editor is initialized as shown below, you must pass that instance to the kit via the `advancedEditor` prop.
|
|
3
|
+
NOTE: TipTap v3 StarterKit includes Link and Underline. Do not also register `@tiptap/extension-link` / `@tiptap/extension-underline` unless you disable them on StarterKit first. Prefer `StarterKit.configure({ trailingNode: false })` so saved HTML does not pick up TipTap’s synthetic trailing empty paragraph. Once the Tiptap editor is initialized as shown below, you must pass that instance to the kit via the `advancedEditor` prop.
|
|
@@ -2,15 +2,11 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedFocus = (props) => {
|
|
9
8
|
const editor = useEditor({
|
|
10
|
-
extensions: [
|
|
11
|
-
StarterKit,
|
|
12
|
-
Link
|
|
13
|
-
],
|
|
9
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
14
10
|
content:"Click inside to see the toolbar. Click outside to hide it."
|
|
15
11
|
})
|
|
16
12
|
|
|
@@ -2,33 +2,23 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
import { Caption } from "playbook-ui"
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
const RichTextEditorAdvancedHeight = (props) => {
|
|
10
9
|
|
|
11
10
|
const editor = useEditor({
|
|
12
|
-
extensions: [
|
|
13
|
-
StarterKit,
|
|
14
|
-
Link
|
|
15
|
-
],
|
|
11
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
16
12
|
content: "Add your text here. You can format your text, add links, quotes, and bullets."
|
|
17
13
|
})
|
|
18
14
|
|
|
19
15
|
const editor2 = useEditor({
|
|
20
|
-
extensions: [
|
|
21
|
-
StarterKit,
|
|
22
|
-
Link
|
|
23
|
-
],
|
|
16
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
24
17
|
content: "Add your text here. You can format your text, add links, quotes, and bullets."
|
|
25
18
|
})
|
|
26
19
|
|
|
27
20
|
const editor3 = useEditor({
|
|
28
|
-
extensions: [
|
|
29
|
-
StarterKit,
|
|
30
|
-
Link
|
|
31
|
-
],
|
|
21
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
32
22
|
content: "Add your text here. You can format your text, add links, quotes, and bullets."
|
|
33
23
|
})
|
|
34
24
|
|
|
@@ -2,16 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedInline = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [
|
|
12
|
-
StarterKit,
|
|
13
|
-
Link
|
|
14
|
-
],
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
15
11
|
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
|
16
12
|
})
|
|
17
13
|
if (!editor) {
|
|
@@ -2,18 +2,17 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedLabel = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [StarterKit
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
12
11
|
content: "Add your text here. You can format your text, add links, quotes, and bullets.",
|
|
13
12
|
})
|
|
14
13
|
|
|
15
14
|
const editorNoLabel = useEditor({
|
|
16
|
-
extensions: [StarterKit
|
|
15
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
17
16
|
content: "Add your text here. You can format your text, add links, quotes, and bullets.",
|
|
18
17
|
})
|
|
19
18
|
|
data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_markdown_support.jsx
CHANGED
|
@@ -2,13 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from '@tiptap/react'
|
|
4
4
|
import StarterKit from '@tiptap/starter-kit'
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
import { defaultMarkdownParser } from 'prosemirror-markdown'
|
|
7
6
|
import { DOMSerializer } from 'prosemirror-model'
|
|
8
7
|
|
|
9
8
|
const RichTextEditorAdvancedMarkdownSupport = (props) => {
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [StarterKit
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
12
11
|
content: 'Paste Markdown here to preserve headings, emphasis, links, lists, quotes, and code blocks.',
|
|
13
12
|
})
|
|
14
13
|
|
data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_min_height.jsx
CHANGED
|
@@ -2,33 +2,23 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
import { Caption } from "playbook-ui"
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
const RichTextEditorAdvancedMinHeight = (props) => {
|
|
10
9
|
|
|
11
10
|
const editor1 = useEditor({
|
|
12
|
-
extensions: [
|
|
13
|
-
StarterKit,
|
|
14
|
-
Link
|
|
15
|
-
],
|
|
11
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
16
12
|
content: "Add your text here. You can format your text, add links, quotes, and bullets."
|
|
17
13
|
})
|
|
18
14
|
|
|
19
15
|
const editor2 = useEditor({
|
|
20
|
-
extensions: [
|
|
21
|
-
StarterKit,
|
|
22
|
-
Link
|
|
23
|
-
],
|
|
16
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
24
17
|
content: "Add your text here. You can format your text, add links, quotes, and bullets."
|
|
25
18
|
})
|
|
26
19
|
|
|
27
20
|
const editor3 = useEditor({
|
|
28
|
-
extensions: [
|
|
29
|
-
StarterKit,
|
|
30
|
-
Link
|
|
31
|
-
],
|
|
21
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
32
22
|
content: "Add your text here. You can format your text, add links, quotes, and bullets."
|
|
33
23
|
})
|
|
34
24
|
|
|
@@ -4,16 +4,12 @@ import Button from '../../pb_button/_button'
|
|
|
4
4
|
import Card from '../../pb_card/_card'
|
|
5
5
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
6
6
|
import StarterKit from "@tiptap/starter-kit"
|
|
7
|
-
import Link from '@tiptap/extension-link'
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
const RichTextEditorAdvancedPreview = (props) => {
|
|
11
10
|
|
|
12
11
|
const editor = useEditor({
|
|
13
|
-
extensions: [
|
|
14
|
-
StarterKit,
|
|
15
|
-
Link
|
|
16
|
-
],
|
|
12
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
17
13
|
content: "Add text here, format it, and press \"Preview Output\" to see what your stylized output will look like on the page."
|
|
18
14
|
})
|
|
19
15
|
|
data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_advanced_required_indicator.jsx
CHANGED
|
@@ -2,16 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedRequiredIndicator = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [
|
|
12
|
-
StarterKit,
|
|
13
|
-
Link
|
|
14
|
-
],
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
15
11
|
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
|
16
12
|
})
|
|
17
13
|
if (!editor) {
|
|
@@ -2,16 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedSimple = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [
|
|
12
|
-
StarterKit,
|
|
13
|
-
Link
|
|
14
|
-
],
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
15
11
|
content:"Add your text here. Use the simple toolbar above to format your text"
|
|
16
12
|
})
|
|
17
13
|
if (!editor) {
|
|
@@ -2,16 +2,12 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
const RichTextEditorAdvancedSticky = (props) => {
|
|
9
8
|
|
|
10
9
|
const editor = useEditor({
|
|
11
|
-
extensions: [
|
|
12
|
-
StarterKit,
|
|
13
|
-
Link
|
|
14
|
-
],
|
|
10
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
15
11
|
content:"In this example, when you scroll down, the rich text editor's toolbar will scroll along with the page and it will no longer be visible at the top of the page. Dummy text to enable scroll.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lorem ut pellentesque tempor. Vivamus ut ex vestibulum velit rich text editor eleifend fringilla. Sed non metus dictum, elementum mauris wysiwyg html editor non, sagittis odio. Nullam pellentesque leo sit amet ante suscipit wysiwyg html editor sagittis. Donec tempus vulputate suscipit. Ut non felis rich text editor ac dolor pulvinar lacinia eu eget urna. Sed tincidunt sapien vulputate tellus fringilla sodales. Morbi accumsan dui wysiwyg html editor sed massa pellentesque, quis vestibulum lectus scelerisque. Nulla ultrices mi id felis luctus aliquet. Donec nec ligula wysiwyg html editor pretium sapien semper dictum eu id quam. Etiam ut sollicitudin nibh. Quisque eu ultrices dui. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus rich text editor mi eu consequat. Nullam tincidunt erat et placerat mattis. Nunc rich text editor congue, enim vitae dictum dignissim, libero nisl sagittis augue, non aliquet nibh tortor sit amet ex. Aliquam cursus maximus mi eu consequat. Nullam tincidunt erat et placerat mattis."
|
|
16
12
|
|
|
17
13
|
})
|
|
@@ -2,7 +2,6 @@ import React, {useState, useEffect} from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
5
|
|
|
7
6
|
import Select from '../../pb_select/_select'
|
|
8
7
|
|
|
@@ -101,10 +100,7 @@ const handleChange = (event) => {
|
|
|
101
100
|
]
|
|
102
101
|
|
|
103
102
|
const editor = useEditor({
|
|
104
|
-
extensions: [
|
|
105
|
-
StarterKit,
|
|
106
|
-
Link
|
|
107
|
-
],
|
|
103
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
108
104
|
content: editorContent
|
|
109
105
|
})
|
|
110
106
|
|
|
@@ -2,9 +2,6 @@ import React from 'react'
|
|
|
2
2
|
import RichTextEditor from '../../pb_rich_text_editor/_rich_text_editor'
|
|
3
3
|
import { useEditor, EditorContent } from "@tiptap/react"
|
|
4
4
|
import StarterKit from "@tiptap/starter-kit"
|
|
5
|
-
import Link from '@tiptap/extension-link'
|
|
6
|
-
|
|
7
|
-
import HorizontalRule from "@tiptap/extension-horizontal-rule"
|
|
8
5
|
import Highlight from '@tiptap/extension-highlight'
|
|
9
6
|
|
|
10
7
|
|
|
@@ -12,9 +9,7 @@ const RichTextEditorMoreExtensions = (props) => {
|
|
|
12
9
|
|
|
13
10
|
const editor = useEditor({
|
|
14
11
|
extensions: [
|
|
15
|
-
StarterKit,
|
|
16
|
-
Link,
|
|
17
|
-
HorizontalRule,
|
|
12
|
+
StarterKit.configure({ trailingNode: false }),
|
|
18
13
|
Highlight.configure({ multicolor: true })
|
|
19
14
|
],
|
|
20
15
|
content:"Add your text here. You can format your text, add links, quotes, and bullets."
|
|
@@ -26,13 +21,13 @@ const RichTextEditorMoreExtensions = (props) => {
|
|
|
26
21
|
const ExtensionsList = [
|
|
27
22
|
{
|
|
28
23
|
icon: "horizontal-rule",
|
|
29
|
-
isActive: editor.isActive("horizontalRule"),
|
|
24
|
+
isActive: () => editor.isActive("horizontalRule"),
|
|
30
25
|
text: "Horizontal Rule",
|
|
31
26
|
onclick: () => editor.chain().focus().setHorizontalRule().run(),
|
|
32
27
|
},
|
|
33
28
|
{
|
|
34
29
|
icon: "highlighter",
|
|
35
|
-
isActive: editor.isActive("highlight"),
|
|
30
|
+
isActive: () => editor.isActive("highlight"),
|
|
36
31
|
text: "Highlighter",
|
|
37
32
|
onclick: () => editor.chain().focus().toggleHighlight().run(),
|
|
38
33
|
}
|
|
@@ -5,7 +5,7 @@ __NOTE__: In order to leverage this prop, you __must__ install the extension you
|
|
|
5
5
|
In order to add the extension to the editor toolbar, create an array of objects (as shown in the ExtensionsList array in the example below). Each object in this array should include:
|
|
6
6
|
|
|
7
7
|
`icon`: the icon to display within the toolbar dropdown (any Fontawesome icons can be used)
|
|
8
|
-
`isActive`: sets the extension to active within the dropdown, when applicable
|
|
8
|
+
`isActive`: sets the extension to active within the dropdown, when applicable. Prefer a function (`() => editor.isActive(...)`) so TipTap v3 selection changes refresh the highlight (TipTap no longer re-renders `useEditor` hosts on every transaction by default)
|
|
9
9
|
`text`: the label within the toolbar dropdown
|
|
10
10
|
`onclick`: initializes the extension when it’s clicked within the dropdown (snytax varies with extension, see Tiptap's docs for more information)
|
|
11
11
|
|
|
@@ -2,11 +2,11 @@ The Rails rich text editor is a TipTap surface with no React. The UI (toolbar, b
|
|
|
2
2
|
|
|
3
3
|
### How TipTap is loaded (Rails)
|
|
4
4
|
|
|
5
|
-
- The kit’s module script (`rich_text_editor_rails.js`) uses `import()` with **full URLs** on [esm.sh](https://esm.sh) (e.g. `@tiptap/core@
|
|
5
|
+
- The kit’s module script (`rich_text_editor_rails.js`) uses `import()` with **full URLs** on [esm.sh](https://esm.sh) (e.g. `@tiptap/core@3.0.7`). esm.sh resolves dependencies server-side, so **no `<script type="importmap">`** is required—this avoids conflicts when the host page already has an import map (e.g. Vite in dev, or another app map) because Firefox only applies one native map.
|
|
6
6
|
- You do not need TipTap in your app’s npm dependencies or Gemfile for this kit; the browser loads modules from esm.sh when the page runs.
|
|
7
7
|
- Ensure **CSP** allows loading scripts from `https://esm.sh` (and esm.sh’s redirected module URLs) if you use a strict `script-src` / `connect-src`.
|
|
8
8
|
|
|
9
9
|
### Relation to the React implementation
|
|
10
10
|
|
|
11
|
-
- Same core: both use TipTap
|
|
11
|
+
- Same core: both use TipTap v3 on top of ProseMirror; styling lives in Playbook SCSS (`_tiptap_styles.scss`) so the editor chrome lines up between platforms.
|
|
12
12
|
- Different shell: Rails uses ERB + Playbook Rails components + inline module script. React uses `RichTextEditor` / `_tiptap_editor.tsx` and TipTap wired through the bundled Playbook React package—see Advanced Default for that stack and when you need TipTap installed in your JavaScript bundle.
|
|
@@ -68,8 +68,9 @@ test('returns "Dark" class name', () => {
|
|
|
68
68
|
// TipTap testing
|
|
69
69
|
const TestAdvancedEditor = ({ toolbarOnFocus = false, ...props }) => {
|
|
70
70
|
const editor = useEditor({
|
|
71
|
-
extensions: [StarterKit],
|
|
71
|
+
extensions: [StarterKit.configure({ trailingNode: false })],
|
|
72
72
|
content: '<p>Test content</p>',
|
|
73
|
+
shouldRerenderOnTransaction: true,
|
|
73
74
|
})
|
|
74
75
|
|
|
75
76
|
if (!editor) return null
|
|
@@ -3,7 +3,6 @@ import { fireEvent, render, waitFor } from "../utilities/test-utils";
|
|
|
3
3
|
import { Editor } from "@tiptap/core";
|
|
4
4
|
import { useEditor, EditorContent } from "@tiptap/react";
|
|
5
5
|
import StarterKit from "@tiptap/starter-kit";
|
|
6
|
-
import Link from "@tiptap/extension-link";
|
|
7
6
|
import { defaultMarkdownParser } from "prosemirror-markdown";
|
|
8
7
|
import { DOMSerializer } from "prosemirror-model";
|
|
9
8
|
|
|
@@ -13,11 +12,14 @@ import { createMarkdownToHTML, handleMarkdownPaste } from "./TipTap/markdownPast
|
|
|
13
12
|
|
|
14
13
|
const kitClass = "pb_rich_text_editor_advanced_container";
|
|
15
14
|
const markdownToHTML = createMarkdownToHTML(defaultMarkdownParser, DOMSerializer);
|
|
15
|
+
const starterKit = StarterKit.configure({ trailingNode: false });
|
|
16
16
|
|
|
17
17
|
const EditorTest = (props) => {
|
|
18
18
|
const editor = useEditor({
|
|
19
|
-
extensions: [
|
|
19
|
+
extensions: [starterKit],
|
|
20
20
|
content: "",
|
|
21
|
+
// TipTap v3: keep toolbar/tests in sync with editor state without host-app config.
|
|
22
|
+
shouldRerenderOnTransaction: true,
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
return (
|
|
@@ -59,7 +61,7 @@ describe("TipTap list selection", () => {
|
|
|
59
61
|
["bulletList", "ul"],
|
|
60
62
|
["orderedList", "ol"],
|
|
61
63
|
])("excludes a heading touched only at its end boundary from a %s", (listType, tag) => {
|
|
62
|
-
const editor = new Editor({ extensions: [
|
|
64
|
+
const editor = new Editor({ extensions: [starterKit], content });
|
|
63
65
|
const headingEnd = editor.state.doc.child(0).nodeSize - 1;
|
|
64
66
|
const paragraphEnd = headingEnd + editor.state.doc.child(1).nodeSize;
|
|
65
67
|
|
|
@@ -76,7 +78,7 @@ describe("TipTap list selection", () => {
|
|
|
76
78
|
});
|
|
77
79
|
|
|
78
80
|
test("excludes a paragraph touched only at its start boundary", () => {
|
|
79
|
-
const editor = new Editor({ extensions: [
|
|
81
|
+
const editor = new Editor({ extensions: [starterKit], content });
|
|
80
82
|
const firstParagraphStart = editor.state.doc.child(0).nodeSize + 1;
|
|
81
83
|
const secondParagraphStart =
|
|
82
84
|
editor.state.doc.child(0).nodeSize + editor.state.doc.child(1).nodeSize + 1;
|
|
@@ -94,7 +96,7 @@ describe("TipTap list selection", () => {
|
|
|
94
96
|
|
|
95
97
|
test("separates a pasted heading and body joined by a hard break", () => {
|
|
96
98
|
const editor = new Editor({
|
|
97
|
-
extensions: [
|
|
99
|
+
extensions: [starterKit],
|
|
98
100
|
content: "<p><strong>How should it work?</strong><br>Keep React and Rails visible.</p>",
|
|
99
101
|
});
|
|
100
102
|
const hardBreakEnd = editor.state.doc.child(0).child(1).nodeSize +
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Rails TipTap: dynamic import() from esm.sh (no import map — avoids 2nd map ignored by Firefox vs Vite/host).
|
|
2
2
|
// Idempotent: data-pb-rte-initialized / data-pb-rte-pending.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// Keep in sync with TipTap versions used by Playbook docs / Nitro RTE alignment (TipTap v3).
|
|
5
|
+
const RTE_TIPTAP_VERSION = "3.0.7";
|
|
5
6
|
const RTE_TIPTAP_ESM = (pkg) => `https://esm.sh/${pkg}@${RTE_TIPTAP_VERSION}`;
|
|
6
7
|
const RTE_EXTENSIONS = new Set(["underline", "text_align", "horizontal_rule", "image"]);
|
|
7
8
|
|
|
@@ -211,7 +212,6 @@ async function initPlaybookRichTextEditorRails(container) {
|
|
|
211
212
|
try {
|
|
212
213
|
const { Editor } = await import(RTE_TIPTAP_ESM("@tiptap/core"));
|
|
213
214
|
const { default: StarterKit } = await import(RTE_TIPTAP_ESM("@tiptap/starter-kit"));
|
|
214
|
-
const { default: Link } = await import(RTE_TIPTAP_ESM("@tiptap/extension-link"));
|
|
215
215
|
const optionalExtensions = await loadOptionalExtensions(extensionNames);
|
|
216
216
|
const neutralClipboardTags = new Set(["html", "head", "body", "meta", "div", "span", "p"]);
|
|
217
217
|
const markdownSourceTags = new Set([...neutralClipboardTags, "pre", "code"]);
|
|
@@ -246,11 +246,22 @@ async function initPlaybookRichTextEditorRails(container) {
|
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
// TipTap v3 StarterKit includes Link + Underline. Keep underline opt-in via extensions prop;
|
|
250
|
+
// configure Link here so we do not load a second @tiptap/extension-link instance.
|
|
249
251
|
const editor = new Editor({
|
|
250
252
|
element: editorNode,
|
|
251
253
|
extensions: [
|
|
252
|
-
StarterKit.configure({
|
|
253
|
-
|
|
254
|
+
StarterKit.configure({
|
|
255
|
+
heading: { levels: [1, 2, 3] },
|
|
256
|
+
link: {
|
|
257
|
+
openOnClick: false,
|
|
258
|
+
HTMLAttributes: { target: "_blank", rel: "noopener" },
|
|
259
|
+
},
|
|
260
|
+
// TipTap v3 enables TrailingNode by default; disable so getHTML() stays
|
|
261
|
+
// free of a synthetic trailing <p></p> that would dirty/persist blank lines.
|
|
262
|
+
trailingNode: false,
|
|
263
|
+
underline: false,
|
|
264
|
+
}),
|
|
254
265
|
...optionalExtensions,
|
|
255
266
|
],
|
|
256
267
|
content: initialHtml,
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import classnames from 'classnames'
|
|
3
3
|
|
|
4
4
|
import { globalProps } from '../utilities/globalProps'
|
|
5
|
+
import { GlobalEventProps, globalEventProps } from '../utilities/globalEventProps'
|
|
5
6
|
import { buildHtmlProps } from '../utilities/props'
|
|
6
7
|
import Title from '../pb_title/_title'
|
|
7
8
|
|
|
@@ -11,7 +12,7 @@ type StatValueProps = {
|
|
|
11
12
|
id?: string,
|
|
12
13
|
unit?: string,
|
|
13
14
|
value: string | number,
|
|
14
|
-
}
|
|
15
|
+
} & GlobalEventProps
|
|
15
16
|
|
|
16
17
|
const StatValue = (props: StatValueProps): React.ReactElement => {
|
|
17
18
|
const {
|
|
@@ -53,6 +54,7 @@ const StatValue = (props: StatValueProps): React.ReactElement => {
|
|
|
53
54
|
className={classnames('pb_stat_value_kit', globalProps(props), className)}
|
|
54
55
|
id={id}
|
|
55
56
|
{...htmlProps}
|
|
57
|
+
{...globalEventProps(props)}
|
|
56
58
|
>
|
|
57
59
|
<div className="pb_stat_value_wrapper">
|
|
58
60
|
{displayValue(value)}
|