@livepreso/react-plugin-textfield 0.5.2 → 0.6.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/.rush/temp/shrinkwrap-deps.json +2 -2
- package/CHANGELOG.json +20 -0
- package/CHANGELOG.md +8 -1
- package/components/BorderEdgeToggle.js +72 -0
- package/components/BubbleMenu.js +107 -19
- package/components/BubbleMenu.module.scss +0 -1
- package/components/InsertTokenDialog.js +1 -1
- package/components/InsertTokenDialog.module.scss +1 -1
- package/components/LinkEditDialog.js +2 -2
- package/components/LinkEditDialog.module.scss +1 -1
- package/components/TableDensityPicker.js +48 -0
- package/components/{color-picker/ColorPicker.module.scss → TableDensityPicker.module.scss} +4 -3
- package/components/TableToolbar.js +4 -0
- package/components/VerticalAlignToggle.js +8 -8
- package/components/color-picker/ColorPickerCombo.js +5 -5
- package/components/color-picker/ColorPickerCombo.module.scss +1 -1
- package/components/editor-toolbars/EditorMenu.js +2 -1
- package/components/editor-toolbars/EditorMenu.module.scss +1 -1
- package/components/editor-toolbars/EditorToolbar.js +10 -7
- package/components/editor-toolbars/EditorToolbar.module.scss +11 -68
- package/components/editor-toolbars/SimpleButton.module.scss +1 -1
- package/components/editor-toolbars/SubMenu.js +59 -3
- package/components/table-creator/TableCreatorCombo.js +4 -4
- package/components/table-creator/TableCreatorCombo.module.scss +1 -1
- package/components/tiptap/Table.js +172 -5
- package/components/tiptap/TableCells.js +33 -0
- package/components/tiptap/token/Token.module.scss +1 -1
- package/components/tiptap/token/TokenList.module.scss +1 -1
- package/components/utils.js +0 -49
- package/configs/table-toolbar-configuration.js +87 -8
- package/configs/toolbar-configuration.js +3 -3
- package/constants.js +16 -1
- package/index.js +7 -1
- package/index.module.scss +63 -22
- package/package.json +3 -4
- package/utils/generate-border-icon.js +22 -0
- package/utils/generate-vertical-alignment-icon.js +1 -1
- package/components/Popover.js +0 -43
- package/components/Popover.module.scss +0 -80
- package/components/Select/Select.js +0 -71
- package/components/Select/Select.module.scss +0 -100
- package/components/Select/SelectGroup.js +0 -37
- package/components/Select/index.js +0 -1
- package/components/Tooltip.js +0 -34
- package/components/Tooltip.module.scss +0 -87
- package/components/color-picker/ColorPicker.js +0 -28
- package/components/color-picker/ColorPickerChip.js +0 -22
- package/components/color-picker/ColorPickerChip.module.scss +0 -25
- package/components/editor-toolbars/ToolbarButton.js +0 -26
- package/components/editor-toolbars/ToolbarToggle.js +0 -35
- package/components/editor-toolbars/ToolbarToggleGroup.js +0 -43
- package/components/style.module.scss +0 -63
- package/icons/AddColumnLeft.js +0 -15
- package/icons/AddColumnRight.js +0 -15
- package/icons/AddRowAbove.js +0 -15
- package/icons/AddRowBelow.js +0 -15
- package/icons/AlignHorizontalCenter.js +0 -13
- package/icons/AlignHorizontalLeft.js +0 -13
- package/icons/AlignHorizontalRight.js +0 -13
- package/icons/AlignVerticalBottom.js +0 -13
- package/icons/AlignVerticalCenter.js +0 -13
- package/icons/AlignVerticalTop.js +0 -13
- package/icons/Backspace.js +0 -13
- package/icons/Bold.js +0 -14
- package/icons/BorderAll.js +0 -13
- package/icons/BorderBottom.js +0 -13
- package/icons/BorderClear.js +0 -13
- package/icons/BorderHorizontal.js +0 -13
- package/icons/BorderInner.js +0 -13
- package/icons/BorderLeft.js +0 -13
- package/icons/BorderOuter.js +0 -13
- package/icons/BorderRight.js +0 -13
- package/icons/BorderTop.js +0 -13
- package/icons/BorderVertical.js +0 -13
- package/icons/Close.js +0 -13
- package/icons/Delete.js +0 -13
- package/icons/EvenlyDistribute.js +0 -14
- package/icons/FitWidth.js +0 -13
- package/icons/FitWidthArrows.js +0 -21
- package/icons/FormatAlignCenter.js +0 -13
- package/icons/FormatAlignJustify.js +0 -13
- package/icons/FormatAlignLeft.js +0 -13
- package/icons/FormatAlignRight.js +0 -13
- package/icons/FormatBold.js +0 -13
- package/icons/FormatClear.js +0 -13
- package/icons/FormatColorFill.js +0 -13
- package/icons/FormatColorText.js +0 -13
- package/icons/FormatItalic.js +0 -13
- package/icons/FormatLineSpacing.js +0 -13
- package/icons/FormatListBulleted.js +0 -13
- package/icons/FormatListNumbered.js +0 -13
- package/icons/FormatStrikethrough.js +0 -13
- package/icons/FormatUnderlined.js +0 -13
- package/icons/HelpCenter.js +0 -13
- package/icons/HorizontalRule.js +0 -13
- package/icons/Italic.js +0 -14
- package/icons/ItalicIcon.js +0 -18
- package/icons/Link.js +0 -13
- package/icons/LinkOff.js +0 -13
- package/icons/MergeCells.js +0 -14
- package/icons/MoreVert.js +0 -13
- package/icons/Redo.js +0 -13
- package/icons/RemoveColumnOutline.js +0 -28
- package/icons/RemoveRowOutline.js +0 -25
- package/icons/SplitCells.js +0 -14
- package/icons/SplitScene.js +0 -13
- package/icons/Subscript.js +0 -13
- package/icons/Superscript.js +0 -13
- package/icons/Underline.js +0 -14
- package/icons/Undo.js +0 -13
- package/icons/VerticalAlignBottom.js +0 -13
- package/icons/VerticalAlignCenter.js +0 -13
- package/icons/VerticalAlignTop.js +0 -13
- package/icons/WandStars.js +0 -13
- package/icons/add_column_left.svg +0 -6
- package/icons/add_column_right.svg +0 -6
- package/icons/add_row_above.svg +0 -6
- package/icons/add_row_below.svg +0 -6
- package/icons/align_horizontal_center.svg +0 -1
- package/icons/align_horizontal_left.svg +0 -1
- package/icons/align_horizontal_right.svg +0 -1
- package/icons/align_vertical_bottom.svg +0 -1
- package/icons/align_vertical_center.svg +0 -1
- package/icons/align_vertical_top.svg +0 -1
- package/icons/backspace.svg +0 -1
- package/icons/bold.svg +0 -1
- package/icons/border_all.svg +0 -1
- package/icons/border_bottom.svg +0 -1
- package/icons/border_clear.svg +0 -1
- package/icons/border_horizontal.svg +0 -1
- package/icons/border_inner.svg +0 -1
- package/icons/border_left.svg +0 -1
- package/icons/border_outer.svg +0 -1
- package/icons/border_right.svg +0 -1
- package/icons/border_top.svg +0 -1
- package/icons/border_vertical.svg +0 -1
- package/icons/close.svg +0 -1
- package/icons/delete.svg +0 -1
- package/icons/evenly_distribute.svg +0 -5
- package/icons/fit_width.svg +0 -1
- package/icons/fit_width_arrows.svg +0 -12
- package/icons/format_align_center.svg +0 -1
- package/icons/format_align_justify.svg +0 -1
- package/icons/format_align_left.svg +0 -1
- package/icons/format_align_right.svg +0 -1
- package/icons/format_bold.svg +0 -1
- package/icons/format_clear.svg +0 -1
- package/icons/format_color_fill.svg +0 -1
- package/icons/format_italic.svg +0 -1
- package/icons/format_line_spacing.svg +0 -1
- package/icons/format_list_bulleted.svg +0 -1
- package/icons/format_list_numbered.svg +0 -1
- package/icons/format_strikethrough.svg +0 -1
- package/icons/format_underlined.svg +0 -1
- package/icons/help_center.svg +0 -1
- package/icons/horizontal_rule.svg +0 -1
- package/icons/index.js +0 -199
- package/icons/italic.svg +0 -1
- package/icons/link.svg +0 -1
- package/icons/link_off.svg +0 -1
- package/icons/merge_cells.svg +0 -5
- package/icons/more_vert.svg +0 -1
- package/icons/redo.svg +0 -1
- package/icons/remove_column_outline.svg +0 -20
- package/icons/remove_row_outline.svg +0 -17
- package/icons/split_cells.svg +0 -5
- package/icons/split_scene.svg +0 -1
- package/icons/subscript.svg +0 -1
- package/icons/superscript.svg +0 -1
- package/icons/underline.svg +0 -1
- package/icons/undo.svg +0 -1
- package/icons/vertical_align_bottom.svg +0 -1
- package/icons/vertical_align_center.svg +0 -1
- package/icons/vertical_align_top.svg +0 -1
- package/icons/wand_stars.svg +0 -1
- package/scripts/extract-svg.js +0 -290
- package/variables.scss +0 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"../../content/react-plugin-textfield": "../../content/react-plugin-textfield:
|
|
2
|
+
"../../content/react-plugin-textfield": "../../content/react-plugin-textfield:WYj65vjFgDMTKI64ejk+PEiCQkGdzJw91G8OiyO6j9k=:",
|
|
3
3
|
"@babel/code-frame@7.29.0": "@babel/code-frame@7.29.0:kW1E61/G1tPYp8ZHZtSkSne0DKMWSVn35WiB3NdzlCw=:",
|
|
4
4
|
"@babel/compat-data@7.29.0": "@babel/compat-data@7.29.0:a57bU0z+Tu3qDgKTY6g83xpry+Ltpm2tGQHpJnQeNyU=:",
|
|
5
5
|
"@babel/core@7.29.0": "@babel/core@7.29.0:q5im1Hft4sBHQef0WtCXclby5g4txy9LJX/q/yC0g5g=:",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"eslint-scope@8.4.0": "eslint-scope@8.4.0:8sCuk/6sg3/iCXu4ikInhuUYyvcQoTXETHdBY6JCzr0=:",
|
|
174
174
|
"eslint-visitor-keys@3.4.3": "eslint-visitor-keys@3.4.3:JgR2rf9Jpzva8lFrKE+5yhxLwgC8qNXtm9LsuSBeAT8=:",
|
|
175
175
|
"eslint-visitor-keys@4.2.1": "eslint-visitor-keys@4.2.1:uyQNsuDcPZL1cJ29uclbt/ITeoMox36b0gbaWL8EB2E=:",
|
|
176
|
-
"eslint@9.15.0(jiti@1.21.7)": "eslint@9.15.0(jiti@1.21.7):
|
|
176
|
+
"eslint@9.15.0(jiti@1.21.7)": "eslint@9.15.0(jiti@1.21.7):5s8tqOQH56eedeB7EmuDjwdx9JjZeyXi4IS97WDGhbA=:",
|
|
177
177
|
"espree@10.4.0": "espree@10.4.0:NLXs2uyUi7cK0j1u0OxWFDO6zYcblsb73pCi4SupIOE=:",
|
|
178
178
|
"esquery@1.7.0": "esquery@1.7.0:7lTtVBqirWgWzvUR2UO+6Vgzeyg40AnBbmtPEJHSYnI=:",
|
|
179
179
|
"esrecurse@4.3.0": "esrecurse@4.3.0:Uyo8CNm+VUgeJSS5C3ZgOky7Jzoy9NqvDpoJmqgzC1s=:",
|
package/CHANGELOG.json
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livepreso/react-plugin-textfield",
|
|
3
3
|
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.6.0",
|
|
6
|
+
"tag": "@livepreso/react-plugin-textfield_v0.6.0",
|
|
7
|
+
"date": "Thu, 17 Sep 2026 01:30:15 GMT",
|
|
8
|
+
"comments": {
|
|
9
|
+
"minor": [
|
|
10
|
+
{
|
|
11
|
+
"comment": "Refactor to use react-plugin-ui for base components. New table editing features: border selection, density (cell padding)."
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"dependency": [
|
|
15
|
+
{
|
|
16
|
+
"comment": "Updating dependency \"@livepreso/content-react\" to `2.3.1`"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"comment": "Updating dependency \"@livepreso/react-plugin-ui\" to `1.0.0`"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
4
24
|
{
|
|
5
25
|
"version": "0.5.2",
|
|
6
26
|
"tag": "@livepreso/react-plugin-textfield_v0.5.2",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Change Log - @livepreso/react-plugin-textfield
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 17 Sep 2026 01:30:15 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 0.6.0
|
|
6
|
+
Thu, 17 Sep 2026 01:30:15 GMT
|
|
7
|
+
|
|
8
|
+
### Minor changes
|
|
9
|
+
|
|
10
|
+
- Refactor to use react-plugin-ui for base components. New table editing features: border selection, density (cell padding).
|
|
4
11
|
|
|
5
12
|
## 0.5.2
|
|
6
13
|
Tue, 08 Sep 2026 00:30:21 GMT
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import icons from "@livepreso/react-plugin-ui/icons";
|
|
4
|
+
import { Tooltip } from "radix-ui";
|
|
5
|
+
import {
|
|
6
|
+
ToolbarRoot,
|
|
7
|
+
ToolbarToggleGroup,
|
|
8
|
+
} from "@livepreso/react-plugin-ui/toolbar";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A component that renders a toggle group for enabling/disabling individual
|
|
12
|
+
* border edges on a table cell.
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} props - The component props
|
|
15
|
+
* @param {string} props.id - The unique identifier for the toggle group
|
|
16
|
+
* @param {string} props.className - CSS class name to apply to the toolbar
|
|
17
|
+
* @param {Function} props.onChange - Callback triggered with the full set of active edges when the selection changes
|
|
18
|
+
* @param {string[]} props.value - The currently active border edges
|
|
19
|
+
* @returns {React.Element} A toolbar component containing border edge toggle options
|
|
20
|
+
*/
|
|
21
|
+
export function BorderEdgeToggle({
|
|
22
|
+
id,
|
|
23
|
+
className,
|
|
24
|
+
onChange = () => {},
|
|
25
|
+
value,
|
|
26
|
+
}) {
|
|
27
|
+
return (
|
|
28
|
+
<Tooltip.Provider delayDuration={800} skipDelayDuration={500}>
|
|
29
|
+
<ToolbarRoot className={className}>
|
|
30
|
+
<ToolbarToggleGroup
|
|
31
|
+
key={id}
|
|
32
|
+
label="Border"
|
|
33
|
+
type="multiple"
|
|
34
|
+
value={value}
|
|
35
|
+
options={[
|
|
36
|
+
{
|
|
37
|
+
id: "border-top",
|
|
38
|
+
tooltip: "Top border",
|
|
39
|
+
label: "Top",
|
|
40
|
+
value: "top",
|
|
41
|
+
icon: <icons.BorderTop />,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "border-right",
|
|
45
|
+
tooltip: "Right border",
|
|
46
|
+
label: "Right",
|
|
47
|
+
value: "right",
|
|
48
|
+
icon: <icons.BorderRight />,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "border-bottom",
|
|
52
|
+
tooltip: "Bottom border",
|
|
53
|
+
label: "Bottom",
|
|
54
|
+
value: "bottom",
|
|
55
|
+
icon: <icons.BorderBottom />,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "border-left",
|
|
59
|
+
tooltip: "Left border",
|
|
60
|
+
label: "Left",
|
|
61
|
+
value: "left",
|
|
62
|
+
icon: <icons.BorderLeft />,
|
|
63
|
+
},
|
|
64
|
+
]}
|
|
65
|
+
onValueChange={(value) => {
|
|
66
|
+
onChange(value);
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
69
|
+
</ToolbarRoot>
|
|
70
|
+
</Tooltip.Provider>
|
|
71
|
+
);
|
|
72
|
+
}
|
package/components/BubbleMenu.js
CHANGED
|
@@ -6,19 +6,111 @@ import { computePosition } from "@floating-ui/react-dom";
|
|
|
6
6
|
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
7
7
|
|
|
8
8
|
import { OverlayPortal, useTransitions } from "@livepreso/content-react";
|
|
9
|
+
import { getTestRect } from "@livepreso/react-plugin-ui/floating-menu";
|
|
9
10
|
import style from "./BubbleMenu.module.scss";
|
|
10
11
|
import { EDITABLE_OUTER_SELECTOR } from "../constants";
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
// Radix wraps Popover/Select content in this; dialogs and buttons get no wrapper.
|
|
14
|
+
const POPPER_CONTENT_SELECTOR = "[data-radix-popper-content-wrapper]";
|
|
12
15
|
|
|
13
16
|
class UnscaledBubbleMenuView extends BubbleMenuView {
|
|
17
|
+
constructor(options) {
|
|
18
|
+
super(options);
|
|
19
|
+
|
|
20
|
+
// The presenter rescales on container resize without a window resize event.
|
|
21
|
+
window.Bridge?.Event?.on("resize", this.resizeHandler, "deck");
|
|
22
|
+
|
|
23
|
+
// Upstream's blur guard checks `element.parentNode`, which for our portaled
|
|
24
|
+
// menu is the whole overlay — so app chrome counts as toolbar and it never
|
|
25
|
+
// hides. Re-register with a guard scoped to our own surfaces.
|
|
26
|
+
this.editor.off("blur", this.blurHandler);
|
|
27
|
+
this.blurHandler = (payload) => this.handleBlur(payload);
|
|
28
|
+
this.editor.on("blur", this.blurHandler);
|
|
29
|
+
|
|
30
|
+
// Accounts for focus moving to another editor field, by comparing the field
|
|
31
|
+
// the focus landed in against this one.
|
|
32
|
+
this.focusInHandler = ({ target }) => {
|
|
33
|
+
if (!this.isVisible) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const field = target?.closest?.(`.${EDITABLE_OUTER_SELECTOR}`);
|
|
38
|
+
const ownField = this.view.dom.closest(`.${EDITABLE_OUTER_SELECTOR}`);
|
|
39
|
+
|
|
40
|
+
if (field && field !== ownField) {
|
|
41
|
+
this.hide();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
this.presenterEl = window.Bridge.UI.overlay.closest("#presenter");
|
|
46
|
+
this.presenterEl?.addEventListener("focusin", this.focusInHandler);
|
|
47
|
+
|
|
48
|
+
// Default scrollTarget is window, but `scroll` doesn't bubble.
|
|
49
|
+
const scroller = this.view.dom.closest(`.${EDITABLE_OUTER_SELECTOR}`);
|
|
50
|
+
|
|
51
|
+
if (scroller) {
|
|
52
|
+
this.scrollTarget?.removeEventListener("scroll", this.resizeHandler);
|
|
53
|
+
this.scrollTarget = scroller;
|
|
54
|
+
this.scrollTarget.addEventListener("scroll", this.resizeHandler);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
handleBlur({ event }) {
|
|
59
|
+
if (this.editor.isDestroyed) {
|
|
60
|
+
this.destroy();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (this.preventHide) {
|
|
65
|
+
this.preventHide = false;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const focused = event?.relatedTarget;
|
|
70
|
+
|
|
71
|
+
// Focus returned to the editor.
|
|
72
|
+
if (focused === this.view.dom) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// A toolbar of this editor, or a popover/select opened from one.
|
|
77
|
+
if (
|
|
78
|
+
focused instanceof Element &&
|
|
79
|
+
(focused.closest(`.${style.bubbleMenu}`) ||
|
|
80
|
+
focused.closest(POPPER_CONTENT_SELECTOR))
|
|
81
|
+
) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
this.hide();
|
|
86
|
+
}
|
|
87
|
+
|
|
14
88
|
show() {
|
|
89
|
+
// Prevent element being re-appended when it's already here.
|
|
90
|
+
if (this.isVisible) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
15
94
|
this.element.style.visibility = "visible";
|
|
16
95
|
this.element.style.opacity = "1";
|
|
96
|
+
|
|
97
|
+
// Re-attach so the toolbar is the overlay's last child while visible.
|
|
98
|
+
// Appending to the element's parent instead of `Bridge.UI.overlay` keeps
|
|
99
|
+
// this a move within one parent. OverlayPortal owns this node, so
|
|
100
|
+
// re-parenting it would break React's teardown.
|
|
101
|
+
this.element.parentNode?.appendChild(this.element);
|
|
102
|
+
|
|
103
|
+
this.isVisible = true;
|
|
17
104
|
}
|
|
18
105
|
|
|
19
106
|
hide() {
|
|
107
|
+
if (!this.isVisible) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
20
111
|
this.element.style.visibility = "hidden";
|
|
21
112
|
this.element.style.opacity = "0";
|
|
113
|
+
this.isVisible = false;
|
|
22
114
|
}
|
|
23
115
|
|
|
24
116
|
updatePosition() {
|
|
@@ -42,31 +134,26 @@ class UnscaledBubbleMenuView extends BubbleMenuView {
|
|
|
42
134
|
const cell = (closestSelector && el.closest(closestSelector)) || dom;
|
|
43
135
|
const cellRect = cell.getBoundingClientRect();
|
|
44
136
|
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
137
|
+
// The field is the scroll/clip area by default; maskSelector overrides it
|
|
138
|
+
// for decks that use a wrapper of their own.
|
|
139
|
+
const container = maskSelector
|
|
140
|
+
? el.closest(maskSelector)
|
|
141
|
+
: el.closest(`.${EDITABLE_OUTER_SELECTOR}`);
|
|
50
142
|
|
|
51
|
-
|
|
143
|
+
if (!container) {
|
|
144
|
+
if (maskSelector) {
|
|
52
145
|
console.warn(
|
|
53
146
|
`BubbleMenu maskSelector '${maskSelector}' was not found in the DOM.`,
|
|
54
147
|
);
|
|
55
|
-
return cellRect;
|
|
56
148
|
}
|
|
57
149
|
|
|
58
|
-
|
|
59
|
-
return getTestRect(cellRect, containerRect);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// cell has extended beyond visible bounds, use slide article as the reference
|
|
63
|
-
if (cellRect.top < 0 || cellRect.left < 0) {
|
|
64
|
-
console.warn(
|
|
65
|
-
"BubbleMenu content extends beyond visible bounds. Supply a maskSelector to TextField for a fallback hit-test rect.",
|
|
66
|
-
);
|
|
150
|
+
return cellRect;
|
|
67
151
|
}
|
|
68
152
|
|
|
69
|
-
|
|
153
|
+
// `cellRect` is the cell's full geometry even where an ancestor clips it.
|
|
154
|
+
// An unclipped rect attaches floating-ui's flip/shift to an off-screen
|
|
155
|
+
// anchor.
|
|
156
|
+
return getTestRect(cellRect, container.getBoundingClientRect());
|
|
70
157
|
};
|
|
71
158
|
|
|
72
159
|
const virtualElement = {
|
|
@@ -87,7 +174,8 @@ class UnscaledBubbleMenuView extends BubbleMenuView {
|
|
|
87
174
|
|
|
88
175
|
destroy() {
|
|
89
176
|
super.destroy();
|
|
90
|
-
window.
|
|
177
|
+
window.Bridge?.Event?.off("resize", this.resizeHandler, "deck");
|
|
178
|
+
this.presenterEl?.removeEventListener("focusin", this.focusInHandler);
|
|
91
179
|
}
|
|
92
180
|
}
|
|
93
181
|
|
|
@@ -3,7 +3,7 @@ import { Dialog } from "radix-ui";
|
|
|
3
3
|
import style from "./InsertTokenDialog.module.scss";
|
|
4
4
|
import tokenStyle from "./tiptap/token/Token.module.scss";
|
|
5
5
|
import classNames from "classnames";
|
|
6
|
-
import icons, { Close } from "
|
|
6
|
+
import icons, { Close } from "@livepreso/react-plugin-ui/icons";
|
|
7
7
|
import { SimpleButton } from "./editor-toolbars/SimpleButton";
|
|
8
8
|
import { TOKEN_TRIGGER_CHAR } from "./tiptap/token/utils";
|
|
9
9
|
|
|
@@ -2,8 +2,8 @@ import React, { useEffect, useState } from "react";
|
|
|
2
2
|
import { Dialog } from "radix-ui";
|
|
3
3
|
import style from "./LinkEditDialog.module.scss";
|
|
4
4
|
import classNames from "classnames";
|
|
5
|
-
import { Close } from "
|
|
6
|
-
import { ToolbarToggle } from "
|
|
5
|
+
import { Close } from "@livepreso/react-plugin-ui/icons";
|
|
6
|
+
import { ToolbarToggle } from "@livepreso/react-plugin-ui/toolbar";
|
|
7
7
|
|
|
8
8
|
const LinkEditDialog = ({
|
|
9
9
|
icon,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import icons from "@livepreso/react-plugin-ui/icons";
|
|
4
|
+
import { Select } from "@livepreso/react-plugin-ui/select";
|
|
5
|
+
import {
|
|
6
|
+
TABLE_DENSITY_SPACIOUS,
|
|
7
|
+
TABLE_DENSITY_NORMAL,
|
|
8
|
+
TABLE_DENSITY_DENSE,
|
|
9
|
+
} from "./tiptap/Table";
|
|
10
|
+
|
|
11
|
+
import style from "./TableDensityPicker.module.scss";
|
|
12
|
+
|
|
13
|
+
const densityIconMap = {
|
|
14
|
+
[TABLE_DENSITY_SPACIOUS]: icons.DensityLarge,
|
|
15
|
+
[TABLE_DENSITY_NORMAL]: icons.DensityMedium,
|
|
16
|
+
[TABLE_DENSITY_DENSE]: icons.DensitySmall,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const densityOptions = [
|
|
20
|
+
{ label: "Spacious", value: TABLE_DENSITY_SPACIOUS },
|
|
21
|
+
{ label: "Normal", value: TABLE_DENSITY_NORMAL },
|
|
22
|
+
{ label: "Dense", value: TABLE_DENSITY_DENSE },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A component that renders an icon reflecting the current table padding
|
|
27
|
+
* density, alongside a dropdown to change it.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} props - The component props
|
|
30
|
+
* @param {string} props.value - The currently active density
|
|
31
|
+
* @param {Function} props.onChange - Callback triggered with the newly selected density
|
|
32
|
+
* @returns {React.Element} An icon and dropdown for setting table density
|
|
33
|
+
*/
|
|
34
|
+
export function TableDensityPicker({ value, onChange = () => {} }) {
|
|
35
|
+
const Icon = densityIconMap[value];
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className={style.row}>
|
|
39
|
+
{Icon && <Icon />}
|
|
40
|
+
<Select
|
|
41
|
+
label="Table density"
|
|
42
|
+
options={densityOptions}
|
|
43
|
+
value={value}
|
|
44
|
+
onValueChange={onChange}
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -25,6 +25,10 @@ export function TableToolbar({
|
|
|
25
25
|
placement: "bottom-start",
|
|
26
26
|
closestSelector: "table",
|
|
27
27
|
maskSelector,
|
|
28
|
+
// Never flip above the field — that lands on the PrimaryToolbar. With
|
|
29
|
+
// no room below, shift nudges it up over the table's last rows.
|
|
30
|
+
flip: false,
|
|
31
|
+
shift: { crossAxis: true, padding: 8 },
|
|
28
32
|
}}
|
|
29
33
|
shouldShow={({ editor }) => {
|
|
30
34
|
return editor.isFocused && editor.isActive("table");
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import icons from "
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import icons from "@livepreso/react-plugin-ui/icons";
|
|
4
|
+
import { Tooltip } from "radix-ui";
|
|
5
|
+
import {
|
|
6
|
+
ToolbarRoot,
|
|
7
|
+
ToolbarToggleGroup,
|
|
8
|
+
} from "@livepreso/react-plugin-ui/toolbar";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* A component that renders a toggle group for vertical alignment options.
|
|
@@ -16,7 +17,6 @@ import classNames from "classnames";
|
|
|
16
17
|
* @param {string} props.value - The currently selected vertical alignment value
|
|
17
18
|
* @returns {React.Element} A toolbar component containing vertical alignment toggle options
|
|
18
19
|
*/
|
|
19
|
-
|
|
20
20
|
export function VerticalAlignToggle({
|
|
21
21
|
id,
|
|
22
22
|
className,
|
|
@@ -25,7 +25,7 @@ export function VerticalAlignToggle({
|
|
|
25
25
|
}) {
|
|
26
26
|
return (
|
|
27
27
|
<Tooltip.Provider delayDuration={800} skipDelayDuration={500}>
|
|
28
|
-
<
|
|
28
|
+
<ToolbarRoot className={className}>
|
|
29
29
|
<ToolbarToggleGroup
|
|
30
30
|
key={id}
|
|
31
31
|
label="Vertical alignment"
|
|
@@ -59,7 +59,7 @@ export function VerticalAlignToggle({
|
|
|
59
59
|
}}
|
|
60
60
|
defaultValue="top"
|
|
61
61
|
/>
|
|
62
|
-
</
|
|
62
|
+
</ToolbarRoot>
|
|
63
63
|
</Tooltip.Provider>
|
|
64
64
|
);
|
|
65
65
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import classNames from "classnames";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { Popover } from "
|
|
4
|
+
import { ColorPickerBasic } from "@livepreso/react-plugin-ui/color-picker";
|
|
5
|
+
import { Popover } from "@livepreso/react-plugin-ui/popover";
|
|
6
6
|
import { ChevronDownIcon } from "@radix-ui/react-icons";
|
|
7
|
-
import { ToolbarButton } from "
|
|
7
|
+
import { ToolbarButton } from "@livepreso/react-plugin-ui/toolbar";
|
|
8
|
+
import toolbarStyle from "@livepreso/react-plugin-ui/toolbar/toolbar.module.scss";
|
|
8
9
|
import { TextColorIcon } from "./TextColorIcon";
|
|
9
|
-
import toolbarStyle from "../editor-toolbars/EditorToolbar.module.scss";
|
|
10
10
|
import style from "./ColorPickerCombo.module.scss";
|
|
11
11
|
|
|
12
12
|
export function ColorPickerCombo({
|
|
@@ -33,7 +33,7 @@ export function ColorPickerCombo({
|
|
|
33
33
|
trigger={<ChevronDownIcon disabled={disabled} />}
|
|
34
34
|
disabled={disabled}
|
|
35
35
|
>
|
|
36
|
-
<
|
|
36
|
+
<ColorPickerBasic
|
|
37
37
|
colors={colors}
|
|
38
38
|
// null and empty string may be valid for "no color"
|
|
39
39
|
value={typeof pickerValue === "undefined" ? value : pickerValue}
|
|
@@ -60,7 +60,7 @@ export function EditorMenu({
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
if (type === TOOLBAR_COMPONENT_TYPES.SUB) {
|
|
63
|
-
const { items, renderItem } = itemsProps;
|
|
63
|
+
const { items, renderItem, keepOpenOnInteract } = itemsProps;
|
|
64
64
|
const { isEnabled, value } = getState(id, editorState);
|
|
65
65
|
|
|
66
66
|
return (
|
|
@@ -73,6 +73,7 @@ export function EditorMenu({
|
|
|
73
73
|
renderItem={(item) =>
|
|
74
74
|
renderItem(item, { editor, value, ...states })
|
|
75
75
|
}
|
|
76
|
+
keepOpenOnInteract={keepOpenOnInteract}
|
|
76
77
|
/>
|
|
77
78
|
);
|
|
78
79
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Toolbar, Tooltip as TooltipPrimitive } from "radix-ui";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ToolbarButton,
|
|
6
|
+
ToolbarRoot,
|
|
7
|
+
ToolbarToggle,
|
|
8
|
+
ToolbarToggleGroup,
|
|
9
|
+
} from "@livepreso/react-plugin-ui/toolbar";
|
|
10
|
+
import { Tooltip } from "@livepreso/react-plugin-ui/tooltip";
|
|
11
|
+
import { Popover } from "@livepreso/react-plugin-ui/popover";
|
|
5
12
|
import { TOOLBAR_COMPONENT_TYPES } from "../../constants";
|
|
6
|
-
import { Popover } from "../Popover";
|
|
7
13
|
import { getState } from "./utils";
|
|
8
|
-
import { ToolbarButton } from "./ToolbarButton";
|
|
9
|
-
import { ToolbarToggle } from "./ToolbarToggle";
|
|
10
|
-
import { ToolbarToggleGroup } from "./ToolbarToggleGroup";
|
|
11
14
|
import style from "./EditorToolbar.module.scss";
|
|
12
15
|
|
|
13
16
|
export function EditorToolbar({
|
|
@@ -20,7 +23,7 @@ export function EditorToolbar({
|
|
|
20
23
|
|
|
21
24
|
return (
|
|
22
25
|
<TooltipPrimitive.Provider delayDuration={800} skipDelayDuration={500}>
|
|
23
|
-
<
|
|
26
|
+
<ToolbarRoot aria-label="Formatting options">
|
|
24
27
|
{configuration.flatMap(({ id: groupId, items = [] }, index) => [
|
|
25
28
|
index !== 0 && (
|
|
26
29
|
<Toolbar.Separator
|
|
@@ -140,7 +143,7 @@ export function EditorToolbar({
|
|
|
140
143
|
})}
|
|
141
144
|
</div>,
|
|
142
145
|
])}
|
|
143
|
-
</
|
|
146
|
+
</ToolbarRoot>
|
|
144
147
|
</TooltipPrimitive.Provider>
|
|
145
148
|
);
|
|
146
149
|
}
|
|
@@ -1,75 +1,18 @@
|
|
|
1
|
-
@import "
|
|
1
|
+
@import "@livepreso/react-plugin-ui/styles/placeholders.module.scss";
|
|
2
2
|
|
|
3
|
+
// .root, .item, and .toggle-group moved to
|
|
4
|
+
// @livepreso/react-plugin-ui/toolbar (ToolbarRoot/ToolbarButton/
|
|
5
|
+
// ToolbarToggle/ToolbarToggleGroup now own that styling). What's left here is
|
|
6
|
+
// specific to this toolbar's own layout, not to an individual item's look.
|
|
3
7
|
:global(.sp-presenter-overlay) {
|
|
4
|
-
.
|
|
5
|
-
@extend %root;
|
|
6
|
-
padding: 6px;
|
|
7
|
-
// min-width: 100%;
|
|
8
|
-
// min-width: 0;
|
|
9
|
-
// min-height: 0;
|
|
8
|
+
.item-group {
|
|
10
9
|
display: flex;
|
|
11
|
-
flex-
|
|
10
|
+
flex-direction: row;
|
|
12
11
|
align-items: center;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// Loz: gets rid of the forced height applied to spans
|
|
16
|
-
// I don't like it...
|
|
17
|
-
> span {
|
|
18
|
-
line-height: 0;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.item-group {
|
|
22
|
-
display: flex;
|
|
23
|
-
flex-direction: row;
|
|
24
|
-
align-items: center;
|
|
25
|
-
height: $item-height;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.item {
|
|
29
|
-
@extend %item;
|
|
30
|
-
flex: 0 0 auto;
|
|
31
|
-
height: $item-height;
|
|
32
|
-
padding: 0 5px;
|
|
33
|
-
margin: 0 2px;
|
|
34
|
-
border-radius: 4px;
|
|
35
|
-
display: inline-flex;
|
|
36
|
-
align-items: center;
|
|
37
|
-
justify-content: center;
|
|
38
|
-
|
|
39
|
-
&:hover {
|
|
40
|
-
@extend %hover;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
&:focus {
|
|
44
|
-
@extend %focus;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
&.toggle {
|
|
48
|
-
&[data-state="on"] {
|
|
49
|
-
@extend %active;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
&[data-disabled],
|
|
54
|
-
&[disabled] {
|
|
55
|
-
@extend %disabled;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.toggle-group {
|
|
60
|
-
display: flex;
|
|
61
|
-
align-items: center;
|
|
62
|
-
justify-content: center;
|
|
63
|
-
|
|
64
|
-
// Loz: gets rid of the forced height applied to spans
|
|
65
|
-
// I don't like it...
|
|
66
|
-
> span {
|
|
67
|
-
line-height: 0;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
12
|
+
height: $item-height;
|
|
13
|
+
}
|
|
70
14
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
15
|
+
.separator {
|
|
16
|
+
@extend %separator-vertical;
|
|
74
17
|
}
|
|
75
18
|
}
|