@multiplatform.one/rich-text 7.10.0 → 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cjs/RichTextEditor/index.native.js.map +1 -1
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/context.native.js.map +1 -1
- package/dist/cjs/editor/BlockDragHandle.native.js.map +1 -1
- package/dist/cjs/editor/MarkdownPaste.native.js.map +1 -1
- package/dist/cjs/editor/SlashCommands.native.js.map +1 -1
- package/dist/cjs/editor/TentapEditor.native.js +47 -14
- package/dist/cjs/editor/TentapEditor.native.js.map +1 -1
- package/dist/cjs/editor/TiptapEditor.native.js.map +1 -1
- package/dist/cjs/editor/blockAnchor.native.js.map +1 -1
- package/dist/cjs/editor/capabilities.native.js.map +1 -1
- package/dist/cjs/editor/codeBlockPreview.native.js.map +1 -1
- package/dist/cjs/editor/editorStyles.native.js.map +1 -1
- package/dist/cjs/editor/emoji.native.js.map +1 -1
- package/dist/cjs/editor/extensions.native.js.map +1 -1
- package/dist/cjs/editor/index.native.js.map +1 -1
- package/dist/cjs/editor/lazyKatex.native.js.map +1 -1
- package/dist/cjs/editor/markdown.native.js.map +1 -1
- package/dist/cjs/editor/mathematics.native.js.map +1 -1
- package/dist/cjs/editor/media.native.js.map +1 -1
- package/dist/cjs/editor/mentions.native.js.map +1 -1
- package/dist/cjs/editor/nativeEditorCSS.native.js.map +1 -1
- package/dist/cjs/editor/pasteCleanup.native.js.map +1 -1
- package/dist/cjs/editor/suggestionPopup.native.js.map +1 -1
- package/dist/cjs/editor/types.native.js.map +1 -1
- package/dist/cjs/editor/useEditorState.native.js.map +1 -1
- package/dist/cjs/index.native.js +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/preview.native.js.map +1 -1
- package/dist/cjs/shared/t.native.js.map +1 -1
- package/dist/cjs/shared/url.native.js.map +1 -1
- package/dist/cjs/styled.native.js.map +1 -1
- package/dist/cjs/toolbar/BubbleToolbar.native.js.map +1 -1
- package/dist/cjs/toolbar/CodeBlockBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/ColorPicker.cjs +2 -2
- package/dist/cjs/toolbar/HeadingPicker.native.js.map +1 -1
- package/dist/cjs/toolbar/ImageBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/ImageDialog.cjs +1 -1
- package/dist/cjs/toolbar/LinkBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/LinkDialog.cjs +1 -1
- package/dist/cjs/toolbar/ListPicker.native.js.map +1 -1
- package/dist/cjs/toolbar/MathBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/MoreDropdown.cjs +1 -1
- package/dist/cjs/toolbar/MoreDropdown.native.js +1 -1
- package/dist/cjs/toolbar/MoreDropdown.native.js.map +1 -1
- package/dist/cjs/toolbar/ResizeHandle.native.js.map +1 -1
- package/dist/cjs/toolbar/StatusBar.native.js.map +1 -1
- package/dist/cjs/toolbar/TableBubble.cjs +1 -1
- package/dist/cjs/toolbar/TableBubble.native.js +1 -1
- package/dist/cjs/toolbar/TableBubble.native.js.map +1 -1
- package/dist/cjs/toolbar/ToolbarGroup.native.js.map +1 -1
- package/dist/cjs/toolbar/shortcuts.native.js.map +1 -1
- package/dist/cjs/toolbar/useHorizontalScroll.cjs +2 -3
- package/dist/cjs/toolbar/useHorizontalScroll.native.js +2 -3
- package/dist/cjs/toolbar/useHorizontalScroll.native.js.map +1 -1
- package/dist/cjs/toolbar/useRovingFocus.native.js.map +1 -1
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/esm/RichTextEditor/index.native.js.map +1 -1
- package/dist/esm/constants.native.js.map +1 -1
- package/dist/esm/context.native.js.map +1 -1
- package/dist/esm/editor/BlockDragHandle.native.js.map +1 -1
- package/dist/esm/editor/MarkdownPaste.native.js.map +1 -1
- package/dist/esm/editor/SlashCommands.native.js.map +1 -1
- package/dist/esm/editor/TentapEditor.native.js +48 -15
- package/dist/esm/editor/TentapEditor.native.js.map +1 -1
- package/dist/esm/editor/TiptapEditor.native.js.map +1 -1
- package/dist/esm/editor/blockAnchor.native.js.map +1 -1
- package/dist/esm/editor/capabilities.native.js.map +1 -1
- package/dist/esm/editor/codeBlockPreview.native.js.map +1 -1
- package/dist/esm/editor/editorStyles.native.js.map +1 -1
- package/dist/esm/editor/emoji.native.js.map +1 -1
- package/dist/esm/editor/extensions.native.js.map +1 -1
- package/dist/esm/editor/index.native.js.map +1 -1
- package/dist/esm/editor/lazyKatex.native.js.map +1 -1
- package/dist/esm/editor/markdown.native.js.map +1 -1
- package/dist/esm/editor/mathematics.native.js.map +1 -1
- package/dist/esm/editor/media.native.js.map +1 -1
- package/dist/esm/editor/mentions.native.js.map +1 -1
- package/dist/esm/editor/nativeEditorCSS.native.js.map +1 -1
- package/dist/esm/editor/pasteCleanup.native.js.map +1 -1
- package/dist/esm/editor/suggestionPopup.native.js.map +1 -1
- package/dist/esm/editor/types.native.js.map +1 -1
- package/dist/esm/editor/useEditorState.native.js.map +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/preview.native.js.map +1 -1
- package/dist/esm/shared/t.native.js.map +1 -1
- package/dist/esm/shared/url.native.js.map +1 -1
- package/dist/esm/styled.native.js.map +1 -1
- package/dist/esm/toolbar/BubbleToolbar.native.js.map +1 -1
- package/dist/esm/toolbar/CodeBlockBubble.native.js.map +1 -1
- package/dist/esm/toolbar/ColorPicker.mjs +2 -2
- package/dist/esm/toolbar/HeadingPicker.native.js.map +1 -1
- package/dist/esm/toolbar/ImageBubble.native.js.map +1 -1
- package/dist/esm/toolbar/ImageDialog.mjs +1 -1
- package/dist/esm/toolbar/LinkBubble.native.js.map +1 -1
- package/dist/esm/toolbar/LinkDialog.mjs +1 -1
- package/dist/esm/toolbar/ListPicker.native.js.map +1 -1
- package/dist/esm/toolbar/MathBubble.native.js.map +1 -1
- package/dist/esm/toolbar/MoreDropdown.mjs +1 -1
- package/dist/esm/toolbar/MoreDropdown.native.js +1 -1
- package/dist/esm/toolbar/MoreDropdown.native.js.map +1 -1
- package/dist/esm/toolbar/ResizeHandle.native.js.map +1 -1
- package/dist/esm/toolbar/StatusBar.native.js.map +1 -1
- package/dist/esm/toolbar/TableBubble.mjs +2 -2
- package/dist/esm/toolbar/TableBubble.mjs.map +1 -1
- package/dist/esm/toolbar/TableBubble.native.js +2 -2
- package/dist/esm/toolbar/TableBubble.native.js.map +1 -1
- package/dist/esm/toolbar/ToolbarGroup.native.js.map +1 -1
- package/dist/esm/toolbar/shortcuts.native.js.map +1 -1
- package/dist/esm/toolbar/useHorizontalScroll.mjs +2 -3
- package/dist/esm/toolbar/useHorizontalScroll.mjs.map +1 -1
- package/dist/esm/toolbar/useHorizontalScroll.native.js +2 -3
- package/dist/esm/toolbar/useHorizontalScroll.native.js.map +1 -1
- package/dist/esm/toolbar/useRovingFocus.native.js.map +1 -1
- package/dist/esm/types.native.js.map +1 -1
- package/dist/jsx/RichTextEditor/index.native.js.map +1 -1
- package/dist/jsx/constants.native.js.map +1 -1
- package/dist/jsx/context.native.js.map +1 -1
- package/dist/jsx/editor/BlockDragHandle.native.js.map +1 -1
- package/dist/jsx/editor/MarkdownPaste.native.js.map +1 -1
- package/dist/jsx/editor/SlashCommands.native.js.map +1 -1
- package/dist/jsx/editor/TentapEditor.native.js +47 -14
- package/dist/jsx/editor/TentapEditor.native.js.map +1 -1
- package/dist/jsx/editor/TiptapEditor.native.js.map +1 -1
- package/dist/jsx/editor/blockAnchor.native.js.map +1 -1
- package/dist/jsx/editor/capabilities.native.js.map +1 -1
- package/dist/jsx/editor/codeBlockPreview.native.js.map +1 -1
- package/dist/jsx/editor/editorStyles.native.js.map +1 -1
- package/dist/jsx/editor/emoji.native.js.map +1 -1
- package/dist/jsx/editor/extensions.native.js.map +1 -1
- package/dist/jsx/editor/index.native.js.map +1 -1
- package/dist/jsx/editor/lazyKatex.native.js.map +1 -1
- package/dist/jsx/editor/markdown.native.js.map +1 -1
- package/dist/jsx/editor/mathematics.native.js.map +1 -1
- package/dist/jsx/editor/media.native.js.map +1 -1
- package/dist/jsx/editor/mentions.native.js.map +1 -1
- package/dist/jsx/editor/nativeEditorCSS.native.js.map +1 -1
- package/dist/jsx/editor/pasteCleanup.native.js.map +1 -1
- package/dist/jsx/editor/suggestionPopup.native.js.map +1 -1
- package/dist/jsx/editor/types.native.js.map +1 -1
- package/dist/jsx/editor/useEditorState.native.js.map +1 -1
- package/dist/jsx/index.native.js +1 -1
- package/dist/jsx/preview.native.js.map +1 -1
- package/dist/jsx/shared/t.native.js.map +1 -1
- package/dist/jsx/shared/url.native.js.map +1 -1
- package/dist/jsx/styled.native.js.map +1 -1
- package/dist/jsx/toolbar/BubbleToolbar.native.js.map +1 -1
- package/dist/jsx/toolbar/CodeBlockBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/ColorPicker.mjs +2 -2
- package/dist/jsx/toolbar/HeadingPicker.native.js.map +1 -1
- package/dist/jsx/toolbar/ImageBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/ImageDialog.mjs +1 -1
- package/dist/jsx/toolbar/LinkBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/LinkDialog.mjs +1 -1
- package/dist/jsx/toolbar/ListPicker.native.js.map +1 -1
- package/dist/jsx/toolbar/MathBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/MoreDropdown.mjs +1 -1
- package/dist/jsx/toolbar/MoreDropdown.native.js +1 -1
- package/dist/jsx/toolbar/MoreDropdown.native.js.map +1 -1
- package/dist/jsx/toolbar/ResizeHandle.native.js.map +1 -1
- package/dist/jsx/toolbar/StatusBar.native.js.map +1 -1
- package/dist/jsx/toolbar/TableBubble.mjs +2 -2
- package/dist/jsx/toolbar/TableBubble.mjs.map +1 -1
- package/dist/jsx/toolbar/TableBubble.native.js +1 -1
- package/dist/jsx/toolbar/TableBubble.native.js.map +1 -1
- package/dist/jsx/toolbar/ToolbarGroup.native.js.map +1 -1
- package/dist/jsx/toolbar/shortcuts.native.js.map +1 -1
- package/dist/jsx/toolbar/useHorizontalScroll.mjs +2 -3
- package/dist/jsx/toolbar/useHorizontalScroll.mjs.map +1 -1
- package/dist/jsx/toolbar/useHorizontalScroll.native.js +2 -3
- package/dist/jsx/toolbar/useHorizontalScroll.native.js.map +1 -1
- package/dist/jsx/toolbar/useRovingFocus.native.js.map +1 -1
- package/dist/jsx/types.native.js.map +1 -1
- package/package.json +12 -12
- package/src/editor/TentapEditor.native.spec.tsx +39 -1
- package/src/editor/TentapEditor.native.tsx +72 -15
- package/src/toolbar/ColorPicker.tsx +2 -2
- package/src/toolbar/ImageDialog.tsx +1 -1
- package/src/toolbar/LinkDialog.tsx +1 -1
- package/src/toolbar/MoreDropdown.tsx +1 -1
- package/src/toolbar/TableBubble.spec.tsx +6 -0
- package/src/toolbar/TableBubble.tsx +2 -2
- package/src/toolbar/toolbarMenuAnchoring.spec.ts +32 -0
- package/src/toolbar/useHorizontalScroll.tsx +2 -1
- package/types/editor/TentapEditor.native.d.ts.map +1 -1
- package/types/toolbar/useHorizontalScroll.d.ts.map +1 -1
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
darkEditorCss,
|
|
37
37
|
darkEditorTheme,
|
|
38
38
|
} from "@10play/tentap-editor";
|
|
39
|
-
import { View, useTheme, useThemeName } from "tamagui";
|
|
39
|
+
import { View, getConfig, getVariableValue, useTheme, useThemeName } from "tamagui";
|
|
40
40
|
import type { RichEditorProps, RichEditorRef, EditorCommand } from "../types";
|
|
41
41
|
import { RichEditorContext } from "../context";
|
|
42
42
|
import { PALETTE_THEME_TOKENS } from "../constants";
|
|
@@ -46,13 +46,56 @@ import { getEditorCSS } from "./editorStyles";
|
|
|
46
46
|
import { escapeNativeEditorCSS } from "./nativeEditorCSS";
|
|
47
47
|
import { htmlToMarkdown, markdownToHtml } from "./markdown";
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
type EditorScheme = "light" | "dark";
|
|
50
|
+
|
|
51
|
+
function useNativeEditorScheme() {
|
|
52
|
+
const themeName = String(useThemeName() || "");
|
|
51
53
|
const osScheme = useColorScheme();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
const scheme: EditorScheme = themeName
|
|
55
|
+
? themeName.startsWith("dark")
|
|
56
|
+
? "dark"
|
|
57
|
+
: "light"
|
|
58
|
+
: osScheme === "dark"
|
|
59
|
+
? "dark"
|
|
60
|
+
: "light";
|
|
61
|
+
return { themeName: themeName || scheme, scheme, followsAppearance: osScheme === scheme };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function paletteDecls(read: (token: string) => unknown): string {
|
|
65
|
+
return PALETTE_THEME_TOKENS.flatMap((token) => {
|
|
66
|
+
const value = read(token);
|
|
67
|
+
return value ? [`--${token}: ${value};`] : [];
|
|
68
|
+
}).join(" ");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* A theme that follows the appearance gets both palettes behind
|
|
73
|
+
* prefers-color-scheme, so the WebView repaints on a scheme flip JS never
|
|
74
|
+
* hears about: a fullScreen modal detaches the root view, and RN's Appearance
|
|
75
|
+
* stays silent until it closes (MPO-187).
|
|
76
|
+
*/
|
|
77
|
+
function schemeStyles(
|
|
78
|
+
themeName: string,
|
|
79
|
+
scheme: EditorScheme,
|
|
80
|
+
followsAppearance: boolean,
|
|
81
|
+
current: string,
|
|
82
|
+
): { dark: string; palette: string } {
|
|
83
|
+
const staticStyles = {
|
|
84
|
+
dark: scheme === "dark" ? darkEditorCss : "",
|
|
85
|
+
palette: `:root { ${current} }`,
|
|
86
|
+
};
|
|
87
|
+
if (!followsAppearance) return staticStyles;
|
|
88
|
+
const other: EditorScheme = scheme === "dark" ? "light" : "dark";
|
|
89
|
+
const otherTheme = (getConfig().themes as Record<string, Record<string, unknown>>)[
|
|
90
|
+
themeName.replace(/^(light|dark)/, other)
|
|
91
|
+
];
|
|
92
|
+
if (!otherTheme) return staticStyles;
|
|
93
|
+
const opposite = paletteDecls((token) => getVariableValue(otherTheme[token]));
|
|
94
|
+
const byScheme = { [scheme]: current, [other]: opposite } as Record<EditorScheme, string>;
|
|
95
|
+
return {
|
|
96
|
+
dark: `@media (prefers-color-scheme: dark) { ${darkEditorCss} }`,
|
|
97
|
+
palette: `@media (prefers-color-scheme: light) { :root { ${byScheme.light} } } @media (prefers-color-scheme: dark) { :root { ${byScheme.dark} } }`,
|
|
98
|
+
};
|
|
56
99
|
}
|
|
57
100
|
|
|
58
101
|
// ===========================================================================
|
|
@@ -91,7 +134,8 @@ export const TentapEditor = forwardRef(
|
|
|
91
134
|
) => {
|
|
92
135
|
const ctx = RichEditorContext.useStyledContext();
|
|
93
136
|
const placeholder = placeholderProp ?? t("Start writing...");
|
|
94
|
-
const
|
|
137
|
+
const { themeName, scheme, followsAppearance } = useNativeEditorScheme();
|
|
138
|
+
const isDarkMode = scheme === "dark";
|
|
95
139
|
const cachedHtml = useRef<string>("");
|
|
96
140
|
const cachedJson = useRef<any>(null);
|
|
97
141
|
|
|
@@ -133,14 +177,16 @@ export const TentapEditor = forwardRef(
|
|
|
133
177
|
const inject = (css: string, tag: string) => {
|
|
134
178
|
editor.injectCSS(escapeNativeEditorCSS(css), tag);
|
|
135
179
|
};
|
|
136
|
-
inject(isDarkMode ? darkEditorCss : "", "multiplatform-tentap-dark");
|
|
137
180
|
// The WebView has no Tamagui stylesheet. Resolve the same palette as
|
|
138
181
|
// web-authored color/highlight marks before applying content rules.
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
182
|
+
const styles = schemeStyles(
|
|
183
|
+
themeName,
|
|
184
|
+
scheme,
|
|
185
|
+
followsAppearance,
|
|
186
|
+
paletteDecls((token) => (theme as any)[token]?.val),
|
|
187
|
+
);
|
|
188
|
+
inject(styles.dark, "multiplatform-tentap-dark");
|
|
189
|
+
inject(styles.palette, "multiplatform-tentap-palette");
|
|
144
190
|
inject(
|
|
145
191
|
getEditorCSS({
|
|
146
192
|
minHeight,
|
|
@@ -152,7 +198,18 @@ export const TentapEditor = forwardRef(
|
|
|
152
198
|
}),
|
|
153
199
|
"multiplatform-tentap-content",
|
|
154
200
|
);
|
|
155
|
-
}, [
|
|
201
|
+
}, [
|
|
202
|
+
editor,
|
|
203
|
+
themeName,
|
|
204
|
+
scheme,
|
|
205
|
+
followsAppearance,
|
|
206
|
+
theme,
|
|
207
|
+
minHeight,
|
|
208
|
+
maxHeight,
|
|
209
|
+
bodyFontFamily,
|
|
210
|
+
headingFontFamily,
|
|
211
|
+
fill,
|
|
212
|
+
]);
|
|
156
213
|
|
|
157
214
|
// TenTap invokes this after its internal onLoad handling, including its
|
|
158
215
|
// first-load iOS reload. Apply on every load so the replacement document
|
|
@@ -80,7 +80,7 @@ export function TextColorPicker({ editorRef, state, disabled }: ColorPickerProps
|
|
|
80
80
|
);
|
|
81
81
|
|
|
82
82
|
return (
|
|
83
|
-
<Popover open={open} onOpenChange={setOpen} placement="bottom">
|
|
83
|
+
<Popover open={open} onOpenChange={setOpen} placement="bottom-start">
|
|
84
84
|
<Popover.Trigger asChild>
|
|
85
85
|
<ToolbarButton
|
|
86
86
|
active={!!state.textColor}
|
|
@@ -123,7 +123,7 @@ export function HighlightColorPicker({ editorRef, state, disabled }: ColorPicker
|
|
|
123
123
|
);
|
|
124
124
|
|
|
125
125
|
return (
|
|
126
|
-
<Popover open={open} onOpenChange={setOpen} placement="bottom">
|
|
126
|
+
<Popover open={open} onOpenChange={setOpen} placement="bottom-start">
|
|
127
127
|
<Popover.Trigger asChild>
|
|
128
128
|
<ToolbarButton
|
|
129
129
|
active={!!state.highlightColor}
|
|
@@ -43,7 +43,7 @@ export function ImageDialog({ editorRef, disabled }: ImageDialogProps) {
|
|
|
43
43
|
}, [imageUrl, editorRef]);
|
|
44
44
|
|
|
45
45
|
return (
|
|
46
|
-
<Popover open={open} onOpenChange={setOpen} placement="bottom">
|
|
46
|
+
<Popover open={open} onOpenChange={setOpen} placement="bottom-start">
|
|
47
47
|
<Popover.Trigger asChild>
|
|
48
48
|
<ToolbarButton
|
|
49
49
|
disabled={disabled}
|
|
@@ -69,7 +69,7 @@ export function LinkDialog({
|
|
|
69
69
|
}, [editorRef]);
|
|
70
70
|
|
|
71
71
|
return (
|
|
72
|
-
<Popover open={open} onOpenChange={setOpen} placement="bottom">
|
|
72
|
+
<Popover open={open} onOpenChange={setOpen} placement="bottom-start">
|
|
73
73
|
<Popover.Trigger asChild>
|
|
74
74
|
<ToolbarButton
|
|
75
75
|
active={state.isLink}
|
|
@@ -159,7 +159,7 @@ export function MoreDropdown({
|
|
|
159
159
|
);
|
|
160
160
|
|
|
161
161
|
return (
|
|
162
|
-
<DropdownMenu open={open} onOpenChange={setOpen} placement="bottom-
|
|
162
|
+
<DropdownMenu open={open} onOpenChange={setOpen} placement="bottom-start">
|
|
163
163
|
<DropdownMenu.Trigger asChild>
|
|
164
164
|
<ToolbarButton
|
|
165
165
|
disabled={disabled}
|
|
@@ -117,6 +117,12 @@ describe("TableBubble", () => {
|
|
|
117
117
|
expect(bubble.props?.options).toMatchObject({ placement: "top-start" });
|
|
118
118
|
});
|
|
119
119
|
|
|
120
|
+
it("attaches flush to the table at the overlay family gap, not a private 6px (MPO-35)", () => {
|
|
121
|
+
const { editor } = makeEditor();
|
|
122
|
+
render(editor);
|
|
123
|
+
expect(bubble.props?.options).toMatchObject({ offset: 0 });
|
|
124
|
+
});
|
|
125
|
+
|
|
120
126
|
// LC-52: GFM pipe tables are plain grids, so merge and split have no
|
|
121
127
|
// markdown form. The markdown capability must drop exactly those two.
|
|
122
128
|
it("markdown capability removes exactly mergeCells and splitCell", () => {
|
|
@@ -7,7 +7,7 @@ import { useState } from "react";
|
|
|
7
7
|
import type { Editor } from "@tiptap/react";
|
|
8
8
|
import { BubbleMenu } from "@tiptap/react/menus";
|
|
9
9
|
import { PopoverContent } from "@multiplatform.one/components";
|
|
10
|
-
import { useResolvedKnobs } from "@multiplatform.one/theme";
|
|
10
|
+
import { OVERLAY_ATTACH_GAP, useResolvedKnobs } from "@multiplatform.one/theme";
|
|
11
11
|
import { ColumnsPlusRightIcon, RowsPlusBottomIcon, TrashIcon } from "@phosphor-icons/react";
|
|
12
12
|
import { Popover, Text, XStack, YStack } from "tamagui";
|
|
13
13
|
import { DropdownMenuItemFrame, ToolbarSeparatorFrame } from "../styled";
|
|
@@ -111,7 +111,7 @@ export function TableBubble({ editor, capabilities = "full" }: TableBubbleProps)
|
|
|
111
111
|
// the first row and holds still while typing in cells (LC-06 spirit:
|
|
112
112
|
// chrome must not sit on top of the content being edited).
|
|
113
113
|
getReferencedVirtualElement={() => getBlockVirtualElement(editor, "table")}
|
|
114
|
-
options={{ placement: "top-start", offset:
|
|
114
|
+
options={{ placement: "top-start", offset: OVERLAY_ATTACH_GAP }}
|
|
115
115
|
>
|
|
116
116
|
<XStack
|
|
117
117
|
backgroundColor="$background"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
|
|
6
|
+
// MPO-35 ruling B (Clay, 2026-09-26): toolbar menus are input-anchored. Each
|
|
7
|
+
// one drops flush below its trigger and starts at the trigger's left edge, so
|
|
8
|
+
// a menu never covers the toolbar being worked in and never centres itself
|
|
9
|
+
// off to one side. The selection and block bubbles are their own lineage and
|
|
10
|
+
// are not held to this.
|
|
11
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const toolbarMenus = {
|
|
13
|
+
"ColorPicker.tsx": 2,
|
|
14
|
+
"HeadingPicker.tsx": 1,
|
|
15
|
+
"ImageDialog.tsx": 1,
|
|
16
|
+
"LinkDialog.tsx": 1,
|
|
17
|
+
"ListPicker.tsx": 1,
|
|
18
|
+
"MoreDropdown.tsx": 1,
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
describe("rich-text toolbar menus open input-anchored (MPO-35)", () => {
|
|
22
|
+
for (const [file, menus] of Object.entries(toolbarMenus)) {
|
|
23
|
+
it(`${file}: every menu opens bottom-start`, () => {
|
|
24
|
+
const src = readFileSync(join(here, file), "utf8");
|
|
25
|
+
const placements = [
|
|
26
|
+
...src.matchAll(/<(?:Popover|DropdownMenu)\b[^>]*placement="([^"]+)"/g),
|
|
27
|
+
].map((match) => match[1]);
|
|
28
|
+
expect(placements).toHaveLength(menus);
|
|
29
|
+
expect(placements.every((placement) => placement === "bottom-start")).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
@@ -9,6 +9,7 @@ import { View } from "tamagui";
|
|
|
9
9
|
import { LinearGradient } from "@tamagui/linear-gradient";
|
|
10
10
|
import { CaretLeftIcon, CaretRightIcon } from "@phosphor-icons/react";
|
|
11
11
|
import { useDirection } from "@multiplatform.one/components";
|
|
12
|
+
import { transitionProps } from "@multiplatform.one/theme";
|
|
12
13
|
|
|
13
14
|
const scrollArrowThreshold = 8;
|
|
14
15
|
|
|
@@ -276,7 +277,7 @@ export function HorizontalScrollArrow({
|
|
|
276
277
|
opacity={visible ? 1 : 0}
|
|
277
278
|
// `animation` is the tamagui 1.x prop — silently dropped on 2.x, which
|
|
278
279
|
// left this opacity fade popping.
|
|
279
|
-
{...(transition
|
|
280
|
+
{...transitionProps(transition)}
|
|
280
281
|
onPointerEnter={visible ? handlePointerEnter : undefined}
|
|
281
282
|
onPointerLeave={handlePointerLeave}
|
|
282
283
|
data-testid={`toolbar-scroll-arrow-${direction}`}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TentapEditor.native.d.ts","sourceRoot":"","sources":["../../src/editor/TentapEditor.native.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0BH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"TentapEditor.native.d.ts","sourceRoot":"","sources":["../../src/editor/TentapEditor.native.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA0BH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAiE9E,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAID,eAAO,MAAM,YAAY,6GA2RxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHorizontalScroll.d.ts","sourceRoot":"","sources":["../../src/toolbar/useHorizontalScroll.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"useHorizontalScroll.d.ts","sourceRoot":"","sources":["../../src/toolbar/useHorizontalScroll.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,aAAa,GAAG,aAAa,CAAC,EACxE,SAAS,EAAE,KAAK,GAAG,KAAK,GACvB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAOjD;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,QAsE9E;AAMD;;GAEG;AACH,wBAAgB,yBAAyB;;;;4BAO3B,WAAW;EAWxB;AAMD,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,OAAO,EACP,iBAAiB,EACjB,UAAU,GACX,EAAE,0BAA0B,2CAwI5B"}
|