playbook_ui 16.5.0.pre.alpha.RTEPOC15747 → 16.5.0.pre.alpha.RTEPOC15748
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_rich_text_editor/_tiptap_styles.scss +6 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_default.md +4 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.html.erb +9 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_simple.md +12 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +1 -0
- data/app/pb_kits/playbook/pb_rich_text_editor/kit.schema.json +4 -2
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +50 -14
- data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +3 -0
- data/dist/playbook.css +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8860b0cd8332d8b7d6727c3871dd06ff3b3d429e7cca826855e97657ecc82ce8
|
|
4
|
+
data.tar.gz: fb9521d937a214c6fae9bd4ea0b3856f95b4d5e9be67e387292b279aca0f5f83
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d74bfc111083f77e948b3fda81623aa925ff89acea5370873345e3ac73d70b591f42c5d06cfbe1302867f1bdd992c3a84fe99827545a91c3eb8361eac01caed3
|
|
7
|
+
data.tar.gz: 6371ded7a68098e54d28074edfadd3ad223d61f8361ce6684ff2081e72686b01e915efc8e5266de664b02b109648a623eee3cc390fde00f28231ac7316104e33
|
|
@@ -196,6 +196,12 @@
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
// Rails TipTap toolbar: mirror React Toolbar.tsx — <Flex paddingX="sm" paddingY="xxs" justify="between">.
|
|
199
|
+
&.rte-rails-toolbar-layout--simple {
|
|
200
|
+
.rte-toolbar-left {
|
|
201
|
+
overflow-x: visible;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
199
205
|
&.rte-rails-toolbar-layout {
|
|
200
206
|
max-width: 100%;
|
|
201
207
|
min-width: 0;
|
|
@@ -10,3 +10,7 @@ The Rails rich text editor is a TipTap surface with no React. The UI (toolbar, b
|
|
|
10
10
|
|
|
11
11
|
- Same core: both use TipTap v2 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.
|
|
13
|
+
|
|
14
|
+
### Simple toolbar (`simple: true`)
|
|
15
|
+
|
|
16
|
+
**Bold**, **Italic**, **Undo**, and **Redo** only (no block dropdown / Popover). See the **Rails (TipTap — Simple toolbar)** example.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
### Simple toolbar (`simple: true`)
|
|
2
|
+
|
|
3
|
+
Pass **`simple: true`** for a compact toolbar: **Bold**, **Italic**, **Undo**, and **Redo** (same history controls as the full toolbar—plain buttons, not popovers).
|
|
4
|
+
|
|
5
|
+
- No block-style dropdown (no “Paragraph” / headings / lists in the menu).
|
|
6
|
+
- No **`pb_popover`** on the toolbar—useful in **native `<dialog>`** modals, turbo-loaded panels, or other tight layouts where the full block menu is awkward to position.
|
|
7
|
+
|
|
8
|
+
The underlying TipTap document still accepts the same HTML as the default Rails editor; `simple` only changes which **toolbar controls** are shown.
|
|
9
|
+
|
|
10
|
+
### When to use the default instead
|
|
11
|
+
|
|
12
|
+
Keep the **default** toolbar (omit `simple` or pass `simple: false`) when you need the block-style menu, strikethrough, code block, and link actions in the chrome.
|
|
@@ -68,7 +68,38 @@
|
|
|
68
68
|
</label>
|
|
69
69
|
<% end %>
|
|
70
70
|
<input type="hidden" name="<%= object.input_name %>" id="<%= object.input_id %>" value="" />
|
|
71
|
-
<div class="pb_rich_text_editor_advanced_container toolbar-active">
|
|
71
|
+
<div class="pb_rich_text_editor_advanced_container toolbar-active<%= " pb_rich_text_editor_rte--simple" if object.simple %>">
|
|
72
|
+
<% if object.simple %>
|
|
73
|
+
<%# Compact toolbar: Bold/Italic + Undo/Redo — no block-style Popover (avoids dialog positioning issues). %>
|
|
74
|
+
<div class="pb_background_kit pb_background_color_white toolbar rte-rails-toolbar-layout rte-rails-toolbar-layout--simple" id="<%= object.toolbar_id %>">
|
|
75
|
+
<div class="rte-rails-toolbar-row">
|
|
76
|
+
<div class="toolbar_block rte-toolbar-left">
|
|
77
|
+
<button type="button" class="toolbar_button" data-action="bold" title="Bold" role="button" tabindex="0">
|
|
78
|
+
<%= pb_rails("flex", props: { align: "center", justify: "center", classname: "toolbar_button_icon" }) do %>
|
|
79
|
+
<%= pb_rails("icon", props: { icon: "bold", size: "lg" }) %>
|
|
80
|
+
<% end %>
|
|
81
|
+
</button>
|
|
82
|
+
<button type="button" class="toolbar_button" data-action="italic" title="Italic" role="button" tabindex="0">
|
|
83
|
+
<%= pb_rails("flex", props: { align: "center", justify: "center", classname: "toolbar_button_icon" }) do %>
|
|
84
|
+
<%= pb_rails("icon", props: { icon: "italic", size: "lg" }) %>
|
|
85
|
+
<% end %>
|
|
86
|
+
</button>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="toolbar_block rte-toolbar-right">
|
|
89
|
+
<button type="button" class="toolbar_button" data-action="undo" title="Undo" role="button" tabindex="0">
|
|
90
|
+
<%= pb_rails("flex", props: { align: "center", justify: "center", classname: "toolbar_button_icon" }) do %>
|
|
91
|
+
<%= pb_rails("icon", props: { icon: "undo", size: "lg" }) %>
|
|
92
|
+
<% end %>
|
|
93
|
+
</button>
|
|
94
|
+
<button type="button" class="toolbar_button" data-action="redo" title="Redo" role="button" tabindex="0">
|
|
95
|
+
<%= pb_rails("flex", props: { align: "center", justify: "center", classname: "toolbar_button_icon" }) do %>
|
|
96
|
+
<%= pb_rails("icon", props: { icon: "redo", size: "lg" }) %>
|
|
97
|
+
<% end %>
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<% else %>
|
|
72
103
|
<% block_style_options = [
|
|
73
104
|
{ value: "paragraph", text: "Paragraph", icon: "paragraph" },
|
|
74
105
|
{ value: "heading-1", text: "Heading 1", icon: "h1" },
|
|
@@ -174,6 +205,7 @@
|
|
|
174
205
|
</span>
|
|
175
206
|
<% end %>
|
|
176
207
|
</div>
|
|
208
|
+
<% end %>
|
|
177
209
|
<div class="rte-editor-wrap">
|
|
178
210
|
<div id="<%= object.editor_node_id %>"></div>
|
|
179
211
|
</div>
|
|
@@ -193,8 +225,9 @@
|
|
|
193
225
|
const hiddenInput = document.getElementById(inputId);
|
|
194
226
|
const editorNode = document.getElementById("<%= object.editor_node_id %>");
|
|
195
227
|
const toolbar = document.getElementById("<%= object.toolbar_id %>");
|
|
228
|
+
const rteSimple = <%= object.simple ? "true" : "false" %> === "true";
|
|
196
229
|
const blockTooltipId = "<%= object.rte_block_style_tooltip_id %>";
|
|
197
|
-
const iconTemplatesRoot = document.getElementById("<%= object.container_id %>-block-icon-templates");
|
|
230
|
+
const iconTemplatesRoot = rteSimple ? null : document.getElementById("<%= object.container_id %>-block-icon-templates");
|
|
198
231
|
if (!editorNode || !hiddenInput || !toolbar) return;
|
|
199
232
|
|
|
200
233
|
function syncToHiddenInput(editor) {
|
|
@@ -239,6 +272,7 @@
|
|
|
239
272
|
}
|
|
240
273
|
|
|
241
274
|
function syncBlockTrigger() {
|
|
275
|
+
if (rteSimple) return;
|
|
242
276
|
const current = getCurrentBlockValue();
|
|
243
277
|
const triggerRoot = toolbar.querySelector("[data-rte-block-trigger]");
|
|
244
278
|
let tpl = iconTemplatesRoot && [...iconTemplatesRoot.children].find(
|
|
@@ -276,18 +310,20 @@
|
|
|
276
310
|
else if (value === "blockquote") chain.toggleBlockquote().run();
|
|
277
311
|
}
|
|
278
312
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
313
|
+
if (!rteSimple) {
|
|
314
|
+
const blockStyleTooltip = document.getElementById(blockTooltipId);
|
|
315
|
+
if (blockStyleTooltip) {
|
|
316
|
+
blockStyleTooltip.addEventListener("click", (e) => {
|
|
317
|
+
const a = e.target.closest("a[href^='#']");
|
|
318
|
+
if (!a || !blockStyleTooltip.contains(a)) return;
|
|
319
|
+
e.preventDefault();
|
|
320
|
+
const href = a.getAttribute("href") || "";
|
|
321
|
+
const v = href.startsWith("#") ? href.slice(1) : "";
|
|
322
|
+
if (!v) return;
|
|
323
|
+
applyBlockType(v);
|
|
324
|
+
updateActiveStates();
|
|
325
|
+
});
|
|
326
|
+
}
|
|
291
327
|
}
|
|
292
328
|
|
|
293
329
|
function updateActiveStates() {
|
|
@@ -9,6 +9,9 @@ module Playbook
|
|
|
9
9
|
prop :input_options, type: Playbook::Props::HashProp, default: {}
|
|
10
10
|
prop :label
|
|
11
11
|
prop :required_indicator, type: Playbook::Props::Boolean, default: false
|
|
12
|
+
# When true, TipTap toolbar matches React `simple`: Bold + Italic only (no block-style Popover).
|
|
13
|
+
# Use in modals or narrow layouts where the block dropdown misbehaves.
|
|
14
|
+
prop :simple, type: Playbook::Props::Boolean, default: false
|
|
12
15
|
|
|
13
16
|
# Match React default (globalProps maxWidth "md").
|
|
14
17
|
def max_width
|