@thangph2146/lexical-editor 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor-x/editor.cjs +33121 -0
- package/dist/editor-x/editor.cjs.map +1 -0
- package/dist/editor-x/editor.css +2854 -0
- package/dist/editor-x/editor.css.map +1 -0
- package/dist/editor-x/editor.d.cts +12 -0
- package/dist/editor-x/editor.d.ts +12 -0
- package/dist/editor-x/editor.js +33095 -0
- package/dist/editor-x/editor.js.map +1 -0
- package/dist/index.cjs +33210 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +2854 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +33183 -0
- package/dist/index.js.map +1 -0
- package/package.json +84 -0
- package/src/components/lexical-editor.tsx +123 -0
- package/src/context/editor-container-context.tsx +29 -0
- package/src/context/priority-image-context.tsx +7 -0
- package/src/context/toolbar-context.tsx +60 -0
- package/src/context/uploads-context.tsx +53 -0
- package/src/editor-hooks/use-debounce.ts +80 -0
- package/src/editor-hooks/use-modal.tsx +64 -0
- package/src/editor-hooks/use-report.ts +57 -0
- package/src/editor-hooks/use-update-toolbar.ts +41 -0
- package/src/editor-ui/broken-image.tsx +18 -0
- package/src/editor-ui/caption-composer.tsx +45 -0
- package/src/editor-ui/code-button.tsx +75 -0
- package/src/editor-ui/color-picker.tsx +2010 -0
- package/src/editor-ui/content-editable.tsx +37 -0
- package/src/editor-ui/hooks/use-image-caption-controls.ts +118 -0
- package/src/editor-ui/hooks/use-image-node-interactions.ts +245 -0
- package/src/editor-ui/hooks/use-responsive-image-dimensions.ts +202 -0
- package/src/editor-ui/image-component.tsx +321 -0
- package/src/editor-ui/image-placeholder.tsx +57 -0
- package/src/editor-ui/image-resizer.tsx +499 -0
- package/src/editor-ui/image-sizing.ts +120 -0
- package/src/editor-ui/lazy-image.tsx +136 -0
- package/src/editor-x/editor.tsx +117 -0
- package/src/editor-x/nodes.ts +79 -0
- package/src/editor-x/plugins.tsx +380 -0
- package/src/hooks/use-click-outside.ts +27 -0
- package/src/hooks/use-element-size.ts +54 -0
- package/src/hooks/use-header-height.ts +95 -0
- package/src/hooks/use-isomorphic-layout-effect.ts +4 -0
- package/src/index.ts +4 -0
- package/src/lib/logger.ts +6 -0
- package/src/lib/utils.ts +19 -0
- package/src/nodes/autocomplete-node.tsx +94 -0
- package/src/nodes/embeds/tweet-node.tsx +224 -0
- package/src/nodes/embeds/youtube-node.tsx +519 -0
- package/src/nodes/emoji-node.tsx +83 -0
- package/src/nodes/image-node.tsx +328 -0
- package/src/nodes/keyword-node.tsx +58 -0
- package/src/nodes/layout-container-node.tsx +128 -0
- package/src/nodes/layout-item-node.tsx +118 -0
- package/src/nodes/list-with-color-node.tsx +160 -0
- package/src/nodes/mention-node.ts +122 -0
- package/src/plugins/actions/actions-plugin.tsx +3 -0
- package/src/plugins/actions/character-limit-plugin.tsx +27 -0
- package/src/plugins/actions/clear-editor-plugin.tsx +70 -0
- package/src/plugins/actions/counter-character-plugin.tsx +80 -0
- package/src/plugins/actions/edit-mode-toggle-plugin.tsx +49 -0
- package/src/plugins/actions/import-export-plugin.tsx +61 -0
- package/src/plugins/actions/markdown-toggle-plugin.tsx +78 -0
- package/src/plugins/actions/max-length-plugin.tsx +59 -0
- package/src/plugins/actions/share-content-plugin.tsx +72 -0
- package/src/plugins/actions/speech-to-text-plugin.tsx +159 -0
- package/src/plugins/actions/tree-view-plugin.tsx +63 -0
- package/src/plugins/align-plugin.tsx +86 -0
- package/src/plugins/auto-link-plugin.tsx +34 -0
- package/src/plugins/autocomplete-plugin.tsx +2574 -0
- package/src/plugins/code-action-menu-plugin.tsx +240 -0
- package/src/plugins/code-highlight-plugin.tsx +22 -0
- package/src/plugins/component-picker-menu-plugin.tsx +427 -0
- package/src/plugins/context-menu-plugin.tsx +311 -0
- package/src/plugins/drag-drop-paste-plugin.tsx +52 -0
- package/src/plugins/draggable-block-plugin.tsx +50 -0
- package/src/plugins/embeds/auto-embed-plugin.tsx +324 -0
- package/src/plugins/embeds/twitter-plugin.tsx +45 -0
- package/src/plugins/embeds/youtube-plugin.tsx +84 -0
- package/src/plugins/emoji-picker-plugin.tsx +206 -0
- package/src/plugins/emojis-plugin.tsx +84 -0
- package/src/plugins/floating-link-editor-plugin.tsx +791 -0
- package/src/plugins/floating-text-format-plugin.tsx +710 -0
- package/src/plugins/images-plugin.tsx +671 -0
- package/src/plugins/keywords-plugin.tsx +59 -0
- package/src/plugins/layout-plugin.tsx +658 -0
- package/src/plugins/link-plugin.tsx +18 -0
- package/src/plugins/list-color-plugin.tsx +178 -0
- package/src/plugins/list-max-indent-level-plugin.tsx +85 -0
- package/src/plugins/mentions-plugin.tsx +714 -0
- package/src/plugins/picker/alignment-picker-plugin.tsx +40 -0
- package/src/plugins/picker/bulleted-list-picker-plugin.tsx +14 -0
- package/src/plugins/picker/check-list-picker-plugin.tsx +14 -0
- package/src/plugins/picker/code-picker-plugin.tsx +30 -0
- package/src/plugins/picker/columns-layout-picker-plugin.tsx +16 -0
- package/src/plugins/picker/component-picker-option.tsx +47 -0
- package/src/plugins/picker/divider-picker-plugin.tsx +14 -0
- package/src/plugins/picker/embeds-picker-plugin.tsx +24 -0
- package/src/plugins/picker/heading-picker-plugin.tsx +32 -0
- package/src/plugins/picker/image-picker-plugin.tsx +16 -0
- package/src/plugins/picker/numbered-list-picker-plugin.tsx +14 -0
- package/src/plugins/picker/paragraph-picker-plugin.tsx +20 -0
- package/src/plugins/picker/quote-picker-plugin.tsx +21 -0
- package/src/plugins/picker/table-picker-plugin.tsx +56 -0
- package/src/plugins/tab-focus-plugin.tsx +66 -0
- package/src/plugins/table-column-resizer-plugin.tsx +309 -0
- package/src/plugins/table-plugin.tsx +299 -0
- package/src/plugins/toolbar/block-format/block-format-data.tsx +69 -0
- package/src/plugins/toolbar/block-format/format-bulleted-list.tsx +40 -0
- package/src/plugins/toolbar/block-format/format-check-list.tsx +40 -0
- package/src/plugins/toolbar/block-format/format-code-block.tsx +45 -0
- package/src/plugins/toolbar/block-format/format-heading.tsx +34 -0
- package/src/plugins/toolbar/block-format/format-list-with-marker.tsx +74 -0
- package/src/plugins/toolbar/block-format/format-numbered-list.tsx +40 -0
- package/src/plugins/toolbar/block-format/format-paragraph.tsx +31 -0
- package/src/plugins/toolbar/block-format/format-quote.tsx +32 -0
- package/src/plugins/toolbar/block-format-toolbar-plugin.tsx +117 -0
- package/src/plugins/toolbar/block-insert/insert-columns-layout.tsx +32 -0
- package/src/plugins/toolbar/block-insert/insert-embeds.tsx +31 -0
- package/src/plugins/toolbar/block-insert/insert-horizontal-rule.tsx +30 -0
- package/src/plugins/toolbar/block-insert/insert-image.tsx +32 -0
- package/src/plugins/toolbar/block-insert/insert-table.tsx +32 -0
- package/src/plugins/toolbar/block-insert-plugin.tsx +30 -0
- package/src/plugins/toolbar/clear-formatting-toolbar-plugin.tsx +92 -0
- package/src/plugins/toolbar/code-language-toolbar-plugin.tsx +121 -0
- package/src/plugins/toolbar/element-format-toolbar-plugin.tsx +251 -0
- package/src/plugins/toolbar/font-background-toolbar-plugin.tsx +179 -0
- package/src/plugins/toolbar/font-color-toolbar-plugin.tsx +101 -0
- package/src/plugins/toolbar/font-family-toolbar-plugin.tsx +91 -0
- package/src/plugins/toolbar/font-format-toolbar-plugin.tsx +85 -0
- package/src/plugins/toolbar/font-size-toolbar-plugin.tsx +177 -0
- package/src/plugins/toolbar/history-toolbar-plugin.tsx +87 -0
- package/src/plugins/toolbar/link-toolbar-plugin.tsx +90 -0
- package/src/plugins/toolbar/subsuper-toolbar-plugin.tsx +69 -0
- package/src/plugins/toolbar/toolbar-plugin.tsx +66 -0
- package/src/plugins/typing-pref-plugin.tsx +118 -0
- package/src/shared/can-use-dom.ts +4 -0
- package/src/shared/environment.ts +47 -0
- package/src/shared/invariant.ts +16 -0
- package/src/shared/use-layout-effect.ts +12 -0
- package/src/themes/_mixins.scss +107 -0
- package/src/themes/_variables.scss +33 -0
- package/src/themes/editor-theme.scss +622 -0
- package/src/themes/editor-theme.ts +118 -0
- package/src/themes/plugins.scss +1180 -0
- package/src/themes/ui-components.scss +936 -0
- package/src/transformers/markdown-emoji-transformer.ts +20 -0
- package/src/transformers/markdown-hr-transformer.ts +28 -0
- package/src/transformers/markdown-image-transformer.ts +31 -0
- package/src/transformers/markdown-list-transformer.ts +51 -0
- package/src/transformers/markdown-table-transformer.ts +200 -0
- package/src/transformers/markdown-tweet-transformer.ts +26 -0
- package/src/ui/button-group.tsx +10 -0
- package/src/ui/button.tsx +29 -0
- package/src/ui/collapsible.tsx +67 -0
- package/src/ui/command.tsx +48 -0
- package/src/ui/dialog.tsx +146 -0
- package/src/ui/flex.tsx +38 -0
- package/src/ui/input.tsx +20 -0
- package/src/ui/label.tsx +20 -0
- package/src/ui/popover.tsx +128 -0
- package/src/ui/scroll-area.tsx +17 -0
- package/src/ui/select.tsx +171 -0
- package/src/ui/separator.tsx +20 -0
- package/src/ui/slider.tsx +14 -0
- package/src/ui/slot.tsx +3 -0
- package/src/ui/tabs.tsx +87 -0
- package/src/ui/toggle-group.tsx +109 -0
- package/src/ui/toggle.tsx +28 -0
- package/src/ui/tooltip.tsx +28 -0
- package/src/ui/typography.tsx +44 -0
- package/src/utils/doc-serialization.ts +68 -0
- package/src/utils/emoji-list.ts +16604 -0
- package/src/utils/get-dom-range-rect.ts +20 -0
- package/src/utils/get-selected-node.ts +20 -0
- package/src/utils/is-mobile-width.ts +0 -0
- package/src/utils/set-floating-elem-position-for-link-editor.ts +39 -0
- package/src/utils/set-floating-elem-position.ts +44 -0
- package/src/utils/swipe.ts +119 -0
- package/src/utils/url.ts +32 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { type CSSProperties, type ReactNode, useEffect, useState } from "react"
|
|
4
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext"
|
|
5
|
+
import { COMMAND_PRIORITY_CRITICAL, SELECTION_CHANGE_COMMAND } from "lexical"
|
|
6
|
+
|
|
7
|
+
import { ToolbarContext } from "../../context/toolbar-context"
|
|
8
|
+
import { useEditorModal } from "../../editor-hooks/use-modal"
|
|
9
|
+
import { useHeaderHeight } from "../../hooks/use-header-height"
|
|
10
|
+
import { cn } from "../../lib/utils"
|
|
11
|
+
|
|
12
|
+
export function ToolbarPlugin({
|
|
13
|
+
children,
|
|
14
|
+
className,
|
|
15
|
+
style,
|
|
16
|
+
}: {
|
|
17
|
+
children: (props: { blockType: string }) => ReactNode
|
|
18
|
+
className?: string
|
|
19
|
+
style?: CSSProperties
|
|
20
|
+
}) {
|
|
21
|
+
const [editor] = useLexicalComposerContext()
|
|
22
|
+
const { headerHeight } = useHeaderHeight()
|
|
23
|
+
|
|
24
|
+
const [activeEditor, setActiveEditor] = useState(editor)
|
|
25
|
+
const [blockType, setBlockType] = useState<string>("paragraph")
|
|
26
|
+
|
|
27
|
+
const [modal, showModal] = useEditorModal()
|
|
28
|
+
|
|
29
|
+
const $updateToolbar = () => {}
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
return activeEditor.registerCommand(
|
|
33
|
+
SELECTION_CHANGE_COMMAND,
|
|
34
|
+
(_payload, newEditor) => {
|
|
35
|
+
setActiveEditor(newEditor)
|
|
36
|
+
return false
|
|
37
|
+
},
|
|
38
|
+
COMMAND_PRIORITY_CRITICAL
|
|
39
|
+
)
|
|
40
|
+
}, [activeEditor, editor])
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<ToolbarContext
|
|
44
|
+
activeEditor={activeEditor}
|
|
45
|
+
$updateToolbar={$updateToolbar}
|
|
46
|
+
blockType={blockType}
|
|
47
|
+
setBlockType={setBlockType}
|
|
48
|
+
showModal={showModal}
|
|
49
|
+
>
|
|
50
|
+
{modal}
|
|
51
|
+
|
|
52
|
+
<div
|
|
53
|
+
className={cn(
|
|
54
|
+
"editor-toolbar",
|
|
55
|
+
className
|
|
56
|
+
)}
|
|
57
|
+
style={{
|
|
58
|
+
...style,
|
|
59
|
+
top: Math.round(headerHeight),
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
{children({ blockType })}
|
|
63
|
+
</div>
|
|
64
|
+
</ToolbarContext>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
import { JSX, useEffect } from "react"
|
|
11
|
+
|
|
12
|
+
import { useReport } from "../editor-hooks/use-report"
|
|
13
|
+
|
|
14
|
+
const validInputTypes = new Set([
|
|
15
|
+
"insertText",
|
|
16
|
+
"insertCompositionText",
|
|
17
|
+
"insertFromComposition",
|
|
18
|
+
"insertLineBreak",
|
|
19
|
+
"insertParagraph",
|
|
20
|
+
"deleteCompositionText",
|
|
21
|
+
"deleteContentBackward",
|
|
22
|
+
"deleteByComposition",
|
|
23
|
+
"deleteContent",
|
|
24
|
+
"deleteContentForward",
|
|
25
|
+
"deleteWordBackward",
|
|
26
|
+
"deleteWordForward",
|
|
27
|
+
"deleteHardLineBackward",
|
|
28
|
+
"deleteSoftLineBackward",
|
|
29
|
+
"deleteHardLineForward",
|
|
30
|
+
"deleteSoftLineForward",
|
|
31
|
+
])
|
|
32
|
+
|
|
33
|
+
export function TypingPerfPlugin(): JSX.Element | null {
|
|
34
|
+
const report = useReport()
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
let start = 0
|
|
37
|
+
let timerId: ReturnType<typeof setTimeout> | null
|
|
38
|
+
let keyPressTimerId: ReturnType<typeof setTimeout> | null
|
|
39
|
+
let log: Array<DOMHighResTimeStamp> = []
|
|
40
|
+
let invalidatingEvent = false
|
|
41
|
+
|
|
42
|
+
const measureEventEnd = function logKeyPress() {
|
|
43
|
+
if (keyPressTimerId != null) {
|
|
44
|
+
if (invalidatingEvent) {
|
|
45
|
+
invalidatingEvent = false
|
|
46
|
+
} else {
|
|
47
|
+
log.push(performance.now() - start)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
clearTimeout(keyPressTimerId)
|
|
51
|
+
keyPressTimerId = null
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const measureEventStart = function measureEvent() {
|
|
56
|
+
if (timerId != null) {
|
|
57
|
+
clearTimeout(timerId)
|
|
58
|
+
timerId = null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// We use a setTimeout(0) instead of requestAnimationFrame, due to
|
|
62
|
+
// inconsistencies between the sequencing of rAF in different browsers.
|
|
63
|
+
keyPressTimerId = setTimeout(measureEventEnd, 0)
|
|
64
|
+
// Schedule a timer to report the results.
|
|
65
|
+
timerId = setTimeout(() => {
|
|
66
|
+
const total = log.reduce((a, b) => a + b, 0)
|
|
67
|
+
const reportedText =
|
|
68
|
+
"Typing Perf: " + Math.round((total / log.length) * 100) / 100 + "ms"
|
|
69
|
+
report(reportedText)
|
|
70
|
+
log = []
|
|
71
|
+
}, 2000)
|
|
72
|
+
// Make the time after we do the previous logic, so we don't measure the overhead
|
|
73
|
+
// for it all.
|
|
74
|
+
start = performance.now()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const beforeInputHandler = function beforeInputHandler(event: InputEvent) {
|
|
78
|
+
if (!validInputTypes.has(event.inputType) || invalidatingEvent) {
|
|
79
|
+
invalidatingEvent = false
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
measureEventStart()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const keyDownHandler = function keyDownHandler(event: KeyboardEvent) {
|
|
87
|
+
const key = event.key
|
|
88
|
+
|
|
89
|
+
if (key === "Backspace" || key === "Enter") {
|
|
90
|
+
measureEventStart()
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const pasteHandler = function pasteHandler() {
|
|
95
|
+
invalidatingEvent = true
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const cutHandler = function cutHandler() {
|
|
99
|
+
invalidatingEvent = true
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
window.addEventListener("keydown", keyDownHandler, true)
|
|
103
|
+
window.addEventListener("selectionchange", measureEventEnd, true)
|
|
104
|
+
window.addEventListener("beforeinput", beforeInputHandler, true)
|
|
105
|
+
window.addEventListener("paste", pasteHandler, true)
|
|
106
|
+
window.addEventListener("cut", cutHandler, true)
|
|
107
|
+
|
|
108
|
+
return () => {
|
|
109
|
+
window.removeEventListener("keydown", keyDownHandler, true)
|
|
110
|
+
window.removeEventListener("selectionchange", measureEventEnd, true)
|
|
111
|
+
window.removeEventListener("beforeinput", beforeInputHandler, true)
|
|
112
|
+
window.removeEventListener("paste", pasteHandler, true)
|
|
113
|
+
window.removeEventListener("cut", cutHandler, true)
|
|
114
|
+
}
|
|
115
|
+
}, [report])
|
|
116
|
+
|
|
117
|
+
return null
|
|
118
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { CAN_USE_DOM } from "../shared/can-use-dom"
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
interface Document {
|
|
5
|
+
documentMode?: unknown
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface Window {
|
|
9
|
+
MSStream?: unknown
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const documentMode =
|
|
14
|
+
CAN_USE_DOM && "documentMode" in document ? document.documentMode : null
|
|
15
|
+
|
|
16
|
+
export const IS_APPLE: boolean =
|
|
17
|
+
CAN_USE_DOM && /Mac|iPod|iPhone|iPad/.test(navigator.platform)
|
|
18
|
+
|
|
19
|
+
export const IS_FIREFOX: boolean =
|
|
20
|
+
CAN_USE_DOM && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent)
|
|
21
|
+
|
|
22
|
+
export const CAN_USE_BEFORE_INPUT: boolean =
|
|
23
|
+
CAN_USE_DOM && "InputEvent" in window && !documentMode
|
|
24
|
+
? "getTargetRanges" in new window.InputEvent("input")
|
|
25
|
+
: false
|
|
26
|
+
|
|
27
|
+
export const IS_SAFARI: boolean =
|
|
28
|
+
CAN_USE_DOM && /Version\/[\d.]+.*Safari/.test(navigator.userAgent)
|
|
29
|
+
|
|
30
|
+
export const IS_IOS: boolean =
|
|
31
|
+
CAN_USE_DOM &&
|
|
32
|
+
/iPad|iPhone|iPod/.test(navigator.userAgent) &&
|
|
33
|
+
!window.MSStream
|
|
34
|
+
|
|
35
|
+
export const IS_ANDROID: boolean =
|
|
36
|
+
CAN_USE_DOM && /Android/.test(navigator.userAgent)
|
|
37
|
+
|
|
38
|
+
// Keep these in case we need to use them in the future.
|
|
39
|
+
// export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
|
|
40
|
+
export const IS_CHROME: boolean =
|
|
41
|
+
CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent)
|
|
42
|
+
// export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
|
|
43
|
+
|
|
44
|
+
export const IS_ANDROID_CHROME: boolean = CAN_USE_DOM && IS_ANDROID && IS_CHROME
|
|
45
|
+
|
|
46
|
+
export const IS_APPLE_WEBKIT =
|
|
47
|
+
CAN_USE_DOM && /AppleWebKit\/[\d.]+/.test(navigator.userAgent) && !IS_CHROME
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function invariant(
|
|
2
|
+
cond?: boolean,
|
|
3
|
+
message?: string,
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- rest args for compile-time replacement
|
|
5
|
+
..._args: string[]
|
|
6
|
+
): asserts cond {
|
|
7
|
+
if (cond) {
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
throw new Error(
|
|
12
|
+
"Internal Lexical error: invariant() is meant to be replaced at compile " +
|
|
13
|
+
"time. There is no runtime version. Error: " +
|
|
14
|
+
message
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { useEffect, useLayoutEffect } from "react"
|
|
2
|
+
|
|
3
|
+
import { CAN_USE_DOM } from "../shared/can-use-dom"
|
|
4
|
+
|
|
5
|
+
// This workaround is no longer necessary in React 19,
|
|
6
|
+
// but we currently support React >=17.x
|
|
7
|
+
// https://github.com/facebook/react/pull/26395
|
|
8
|
+
const useLayoutEffectImpl: typeof useLayoutEffect = CAN_USE_DOM
|
|
9
|
+
? useLayoutEffect
|
|
10
|
+
: useEffect
|
|
11
|
+
|
|
12
|
+
export default useLayoutEffectImpl
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor Theme Mixins
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
@use "variables" as *;
|
|
6
|
+
|
|
7
|
+
@mixin focus-ring {
|
|
8
|
+
&:focus-visible {
|
|
9
|
+
outline: none;
|
|
10
|
+
box-shadow: 0 0 0 2px var(--ring), 0 0 0 4px $editor-bg-color;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@mixin text-sm {
|
|
15
|
+
font-size: 14px;
|
|
16
|
+
line-height: 20px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@mixin flex-center {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@mixin flex-col {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@mixin flex-center-justify {
|
|
30
|
+
@include flex-center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@mixin shadow-sm {
|
|
35
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@mixin shadow-md {
|
|
39
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@mixin shadow-lg {
|
|
43
|
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@mixin shadow-xl {
|
|
47
|
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@mixin rounded-sm {
|
|
51
|
+
border-radius: calc($editor-border-radius - 2px);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@mixin rounded-md {
|
|
55
|
+
border-radius: $editor-border-radius;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@mixin rounded-lg {
|
|
59
|
+
border-radius: calc($editor-border-radius + 4px);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// --- Unified Hover Styles ---
|
|
63
|
+
@mixin editor-hover-base {
|
|
64
|
+
background-color: $editor-accent-color;
|
|
65
|
+
color: $editor-accent-foreground-color;
|
|
66
|
+
border-color: $editor-accent-color;
|
|
67
|
+
transform: translateY(-1px);
|
|
68
|
+
box-shadow: 0 2px 4px -1px rgba(0, 0, 0, 0.1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@mixin editor-active-base {
|
|
72
|
+
transform: translateY(0);
|
|
73
|
+
box-shadow: none;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@mixin editor-button-interactive {
|
|
77
|
+
&:hover:not(:disabled):not([data-state="on"]) {
|
|
78
|
+
@include editor-hover-base;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&:active:not(:disabled) {
|
|
82
|
+
@include editor-active-base;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Interactive mixin for dropdown/menu items
|
|
87
|
+
@mixin editor-dropdown-item-interactive {
|
|
88
|
+
&:hover, &:focus, &--selected, &[aria-selected="true"], &[data-selected="true"] {
|
|
89
|
+
background-color: $editor-accent-color;
|
|
90
|
+
color: $editor-accent-foreground-color;
|
|
91
|
+
border-color: $editor-border-color; // Use border color for visibility
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&:active {
|
|
95
|
+
@include editor-active-base;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@keyframes spin {
|
|
100
|
+
from { transform: rotate(0deg); }
|
|
101
|
+
to { transform: rotate(360deg); }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@keyframes editor-fade-in {
|
|
105
|
+
from { opacity: 0; transform: translateY(-10px); }
|
|
106
|
+
to { opacity: 1; transform: translateY(0); }
|
|
107
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor Theme Variables
|
|
3
|
+
* Use these variables to customize the editor's appearance.
|
|
4
|
+
* All variables use !default so they can be overridden by the consumer.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Typography
|
|
8
|
+
$editor-font-family: var(--font-inter), "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default;
|
|
9
|
+
$editor-font-size-base: 16px !default;
|
|
10
|
+
$editor-line-height-base: 1.75 !default;
|
|
11
|
+
|
|
12
|
+
// Colors - Compatible with Shadcn CSS Variables
|
|
13
|
+
$editor-primary-color: var(--primary, #3b82f6) !default; // blue-500 fallback
|
|
14
|
+
$editor-link-color: #3b82f6 !default; // Fixed link color (Blue 500) to ensure consistency across apps
|
|
15
|
+
$editor-text-color: var(--foreground, #1f2937) !default; // gray-800 fallback
|
|
16
|
+
$editor-bg-color: var(--background, transparent) !default;
|
|
17
|
+
$editor-muted-color: var(--muted, #f3f4f6) !default; // gray-100 fallback
|
|
18
|
+
$editor-border-color: var(--border, #d1d5db) !default; // gray-300 fallback
|
|
19
|
+
$editor-quote-border-color: var(--input, #e5e7eb) !default; // gray-200 fallback
|
|
20
|
+
$editor-accent-color: var(--accent, #f1f5f9) !default; // slate-100 fallback
|
|
21
|
+
$editor-accent-foreground-color: var(--accent-foreground, #0f172a) !default; // slate-900 fallback
|
|
22
|
+
|
|
23
|
+
// Layout
|
|
24
|
+
$editor-border-radius: var(--radius, 8px) !default;
|
|
25
|
+
$editor-spacing-unit: 8px !default;
|
|
26
|
+
|
|
27
|
+
// Code
|
|
28
|
+
$editor-code-bg: var(--muted, #f3f4f6) !default;
|
|
29
|
+
$editor-code-color: var(--muted-foreground, #1f2937) !default;
|
|
30
|
+
|
|
31
|
+
// Table
|
|
32
|
+
$editor-table-border-color: var(--border, #d1d5db) !default;
|
|
33
|
+
$editor-table-header-bg: var(--muted, #f9fafb) !default; // gray-50 fallback
|