@thangph2146/lexical-editor 0.0.11 → 0.0.13
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 -1
- package/dist/editor-x/editor.cjs +280 -20
- package/dist/editor-x/editor.cjs.map +1 -1
- package/dist/editor-x/editor.css +27 -4
- package/dist/editor-x/editor.css.map +1 -1
- package/dist/editor-x/editor.js +281 -21
- package/dist/editor-x/editor.js.map +1 -1
- package/dist/index.cjs +292 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +27 -4
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +293 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/lexical-editor.tsx +19 -6
- package/src/context/uploads-context.tsx +1 -0
- package/src/editor-ui/content-editable.tsx +18 -2
- package/src/editor-x/nodes.ts +2 -0
- package/src/nodes/download-link-node.tsx +118 -0
- package/src/plugins/floating-link-editor-plugin.tsx +338 -91
- package/src/themes/core/_tables.scss +0 -1
- package/src/themes/plugins/_floating-link-editor.scss +28 -2
- package/src/themes/ui-components/_button.scss +1 -1
- package/src/themes/ui-components/_flex.scss +1 -0
- package/src/ui/button-group.tsx +10 -10
- package/src/ui/button.tsx +38 -38
- package/src/ui/collapsible.tsx +67 -67
- package/src/ui/command.tsx +48 -48
- package/src/ui/dialog.tsx +146 -146
- package/src/ui/flex.tsx +45 -45
- package/src/ui/input.tsx +20 -20
- package/src/ui/label.tsx +20 -20
- package/src/ui/number-input.tsx +104 -104
- package/src/ui/popover.tsx +128 -128
- package/src/ui/scroll-area.tsx +17 -17
- package/src/ui/select.tsx +171 -171
- package/src/ui/separator.tsx +20 -20
- package/src/ui/slider.tsx +14 -14
- package/src/ui/slot.tsx +3 -3
- package/src/ui/tabs.tsx +87 -87
- package/src/ui/toggle-group.tsx +109 -109
- package/src/ui/toggle.tsx +28 -28
- package/src/ui/tooltip.tsx +28 -28
- package/src/ui/typography.tsx +44 -44
|
@@ -20,15 +20,41 @@
|
|
|
20
20
|
&__input-container {
|
|
21
21
|
@include flex-center;
|
|
22
22
|
gap: $editor-gap-1;
|
|
23
|
-
padding: $editor-gap-
|
|
23
|
+
padding: $editor-gap-2;
|
|
24
|
+
width: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&__library {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
gap: $editor-gap-1;
|
|
31
|
+
width: 100%;
|
|
32
|
+
max-height: 220px;
|
|
33
|
+
overflow: auto;
|
|
34
|
+
border-top: $editor-border-width solid var(--border);
|
|
35
|
+
padding: $editor-gap-2;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&__library-item {
|
|
24
39
|
width: 100%;
|
|
40
|
+
text-align: left;
|
|
41
|
+
background: transparent;
|
|
42
|
+
border: 0;
|
|
43
|
+
color: var(--foreground);
|
|
44
|
+
padding: $editor-gap-1;
|
|
45
|
+
@include rounded-sm;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
background: var(--muted);
|
|
50
|
+
}
|
|
25
51
|
}
|
|
26
52
|
|
|
27
53
|
&__view-container {
|
|
28
54
|
@include flex-center;
|
|
29
55
|
justify-content: space-between;
|
|
30
56
|
gap: $editor-gap-2;
|
|
31
|
-
padding: $editor-gap-1 $editor-gap-1 $editor-gap-1 $editor-gap-3;
|
|
57
|
+
padding: $editor-gap-1 $editor-gap-1 $editor-gap-1 $editor-gap-3 !important;
|
|
32
58
|
width: 100%;
|
|
33
59
|
}
|
|
34
60
|
|
package/src/ui/button-group.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
|
|
4
|
-
export function ButtonGroup({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
5
|
-
return (
|
|
6
|
-
<div className={cn("editor-button-group", className)} {...props}>
|
|
7
|
-
{children}
|
|
8
|
-
</div>
|
|
9
|
-
)
|
|
10
|
-
}
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
export function ButtonGroup({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
5
|
+
return (
|
|
6
|
+
<div className={cn("editor-button-group", className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
)
|
|
10
|
+
}
|
package/src/ui/button.tsx
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
import { Loader2 } from "lucide-react"
|
|
4
|
-
|
|
5
|
-
export interface ButtonProps
|
|
6
|
-
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
7
|
-
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
|
|
8
|
-
size?: "default" | "sm" | "md" | "lg" | "icon"
|
|
9
|
-
isLoading?: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
13
|
-
({ className, variant = "default", size = "default", type = "button", isLoading, disabled, children, ...props }, ref) => {
|
|
14
|
-
return (
|
|
15
|
-
<button
|
|
16
|
-
type={type}
|
|
17
|
-
className={cn(
|
|
18
|
-
"editor-btn",
|
|
19
|
-
variant !== "default" && `editor-btn--${variant}`,
|
|
20
|
-
size !== "default" && `editor-btn--size-${size}`,
|
|
21
|
-
isLoading && "editor-btn--loading",
|
|
22
|
-
className
|
|
23
|
-
)}
|
|
24
|
-
disabled={isLoading || disabled}
|
|
25
|
-
ref={ref}
|
|
26
|
-
{...props}
|
|
27
|
-
>
|
|
28
|
-
{isLoading && <Loader2 className="editor-btn__loader editor-animate-spin" size={16} />}
|
|
29
|
-
<span className={cn("editor-btn__content", isLoading && "editor-opacity-0")}>
|
|
30
|
-
{children}
|
|
31
|
-
</span>
|
|
32
|
-
</button>
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
)
|
|
36
|
-
Button.displayName = "Button"
|
|
37
|
-
|
|
38
|
-
export { Button }
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
import { Loader2 } from "lucide-react"
|
|
4
|
+
|
|
5
|
+
export interface ButtonProps
|
|
6
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
7
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
|
|
8
|
+
size?: "default" | "sm" | "md" | "lg" | "icon"
|
|
9
|
+
isLoading?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
13
|
+
({ className, variant = "default", size = "default", type = "button", isLoading, disabled, children, ...props }, ref) => {
|
|
14
|
+
return (
|
|
15
|
+
<button
|
|
16
|
+
type={type}
|
|
17
|
+
className={cn(
|
|
18
|
+
"editor-btn",
|
|
19
|
+
variant !== "default" && `editor-btn--${variant}`,
|
|
20
|
+
size !== "default" && `editor-btn--size-${size}`,
|
|
21
|
+
isLoading && "editor-btn--loading",
|
|
22
|
+
className
|
|
23
|
+
)}
|
|
24
|
+
disabled={isLoading || disabled}
|
|
25
|
+
ref={ref}
|
|
26
|
+
{...props}
|
|
27
|
+
>
|
|
28
|
+
{isLoading && <Loader2 className="editor-btn__loader editor-animate-spin" size={16} />}
|
|
29
|
+
<span className={cn("editor-btn__content", isLoading && "editor-opacity-0")}>
|
|
30
|
+
{children}
|
|
31
|
+
</span>
|
|
32
|
+
</button>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
Button.displayName = "Button"
|
|
37
|
+
|
|
38
|
+
export { Button }
|
package/src/ui/collapsible.tsx
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
|
|
4
|
-
const CollapsibleContext = React.createContext<{
|
|
5
|
-
open: boolean
|
|
6
|
-
setOpen: (open: boolean) => void
|
|
7
|
-
} | null>(null)
|
|
8
|
-
|
|
9
|
-
export function Collapsible({
|
|
10
|
-
children,
|
|
11
|
-
open: controlledOpen,
|
|
12
|
-
onOpenChange,
|
|
13
|
-
className,
|
|
14
|
-
...props
|
|
15
|
-
}: {
|
|
16
|
-
children: React.ReactNode
|
|
17
|
-
open?: boolean
|
|
18
|
-
onOpenChange?: (open: boolean) => void
|
|
19
|
-
className?: string
|
|
20
|
-
}) {
|
|
21
|
-
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false)
|
|
22
|
-
const open = controlledOpen ?? uncontrolledOpen
|
|
23
|
-
const setOpen = onOpenChange ?? setUncontrolledOpen
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<CollapsibleContext.Provider value={{ open, setOpen }}>
|
|
27
|
-
<div className={cn("editor-collapsible", className)} data-state={open ? "open" : "closed"} {...props}>
|
|
28
|
-
{children}
|
|
29
|
-
</div>
|
|
30
|
-
</CollapsibleContext.Provider>
|
|
31
|
-
)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function CollapsibleTrigger({ children, asChild, ...props }: React.HTMLAttributes<HTMLElement> & { asChild?: boolean, children: React.ReactNode }) {
|
|
35
|
-
const context = React.useContext(CollapsibleContext)
|
|
36
|
-
if (!context) throw new Error("CollapsibleTrigger must be used within Collapsible")
|
|
37
|
-
|
|
38
|
-
const handleClick = (e: React.MouseEvent<HTMLElement>) => {
|
|
39
|
-
context.setOpen(!context.open)
|
|
40
|
-
if (React.isValidElement(children)) {
|
|
41
|
-
(children as React.ReactElement<{ onClick?: React.MouseEventHandler<HTMLElement> }>).props.onClick?.(e)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (asChild && React.isValidElement(children)) {
|
|
46
|
-
return React.cloneElement(children as React.ReactElement<React.HTMLAttributes<HTMLElement>>, { onClick: handleClick, ...props })
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<button type="button" onClick={handleClick} {...props}>
|
|
51
|
-
{children}
|
|
52
|
-
</button>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function CollapsibleContent({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
57
|
-
const context = React.useContext(CollapsibleContext)
|
|
58
|
-
if (!context) throw new Error("CollapsibleContent must be used within Collapsible")
|
|
59
|
-
|
|
60
|
-
if (!context.open) return null
|
|
61
|
-
|
|
62
|
-
return (
|
|
63
|
-
<div className={cn("editor-overflow-hidden", className)} {...props}>
|
|
64
|
-
{children}
|
|
65
|
-
</div>
|
|
66
|
-
)
|
|
67
|
-
}
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
const CollapsibleContext = React.createContext<{
|
|
5
|
+
open: boolean
|
|
6
|
+
setOpen: (open: boolean) => void
|
|
7
|
+
} | null>(null)
|
|
8
|
+
|
|
9
|
+
export function Collapsible({
|
|
10
|
+
children,
|
|
11
|
+
open: controlledOpen,
|
|
12
|
+
onOpenChange,
|
|
13
|
+
className,
|
|
14
|
+
...props
|
|
15
|
+
}: {
|
|
16
|
+
children: React.ReactNode
|
|
17
|
+
open?: boolean
|
|
18
|
+
onOpenChange?: (open: boolean) => void
|
|
19
|
+
className?: string
|
|
20
|
+
}) {
|
|
21
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false)
|
|
22
|
+
const open = controlledOpen ?? uncontrolledOpen
|
|
23
|
+
const setOpen = onOpenChange ?? setUncontrolledOpen
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<CollapsibleContext.Provider value={{ open, setOpen }}>
|
|
27
|
+
<div className={cn("editor-collapsible", className)} data-state={open ? "open" : "closed"} {...props}>
|
|
28
|
+
{children}
|
|
29
|
+
</div>
|
|
30
|
+
</CollapsibleContext.Provider>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function CollapsibleTrigger({ children, asChild, ...props }: React.HTMLAttributes<HTMLElement> & { asChild?: boolean, children: React.ReactNode }) {
|
|
35
|
+
const context = React.useContext(CollapsibleContext)
|
|
36
|
+
if (!context) throw new Error("CollapsibleTrigger must be used within Collapsible")
|
|
37
|
+
|
|
38
|
+
const handleClick = (e: React.MouseEvent<HTMLElement>) => {
|
|
39
|
+
context.setOpen(!context.open)
|
|
40
|
+
if (React.isValidElement(children)) {
|
|
41
|
+
(children as React.ReactElement<{ onClick?: React.MouseEventHandler<HTMLElement> }>).props.onClick?.(e)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (asChild && React.isValidElement(children)) {
|
|
46
|
+
return React.cloneElement(children as React.ReactElement<React.HTMLAttributes<HTMLElement>>, { onClick: handleClick, ...props })
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<button type="button" onClick={handleClick} {...props}>
|
|
51
|
+
{children}
|
|
52
|
+
</button>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function CollapsibleContent({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
57
|
+
const context = React.useContext(CollapsibleContext)
|
|
58
|
+
if (!context) throw new Error("CollapsibleContent must be used within Collapsible")
|
|
59
|
+
|
|
60
|
+
if (!context.open) return null
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div className={cn("editor-overflow-hidden", className)} {...props}>
|
|
64
|
+
{children}
|
|
65
|
+
</div>
|
|
66
|
+
)
|
|
67
|
+
}
|
package/src/ui/command.tsx
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
|
|
4
|
-
export const Command = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
5
|
-
({ className, ...props }, ref) => (
|
|
6
|
-
<div
|
|
7
|
-
ref={ref}
|
|
8
|
-
className={cn("editor-command", className)}
|
|
9
|
-
{...props}
|
|
10
|
-
/>
|
|
11
|
-
)
|
|
12
|
-
)
|
|
13
|
-
Command.displayName = "Command"
|
|
14
|
-
|
|
15
|
-
export const CommandList = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
16
|
-
({ className, ...props }, ref) => (
|
|
17
|
-
<div
|
|
18
|
-
ref={ref}
|
|
19
|
-
className={cn("editor-command-list", className)}
|
|
20
|
-
{...props}
|
|
21
|
-
/>
|
|
22
|
-
)
|
|
23
|
-
)
|
|
24
|
-
CommandList.displayName = "CommandList"
|
|
25
|
-
|
|
26
|
-
export const CommandGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
27
|
-
({ className, ...props }, ref) => (
|
|
28
|
-
<div
|
|
29
|
-
ref={ref}
|
|
30
|
-
className={cn("editor-command-group", className)}
|
|
31
|
-
{...props}
|
|
32
|
-
/>
|
|
33
|
-
)
|
|
34
|
-
)
|
|
35
|
-
CommandGroup.displayName = "CommandGroup"
|
|
36
|
-
|
|
37
|
-
export const CommandItem = React.forwardRef<
|
|
38
|
-
HTMLDivElement,
|
|
39
|
-
React.HTMLAttributes<HTMLDivElement> & { onSelect?: () => void; value?: string }
|
|
40
|
-
>(({ className, onSelect, ...props }, ref) => (
|
|
41
|
-
<div
|
|
42
|
-
ref={ref}
|
|
43
|
-
className={cn("editor-command-item", className)}
|
|
44
|
-
onClick={onSelect}
|
|
45
|
-
{...props}
|
|
46
|
-
/>
|
|
47
|
-
))
|
|
48
|
-
CommandItem.displayName = "CommandItem"
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
export const Command = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
5
|
+
({ className, ...props }, ref) => (
|
|
6
|
+
<div
|
|
7
|
+
ref={ref}
|
|
8
|
+
className={cn("editor-command", className)}
|
|
9
|
+
{...props}
|
|
10
|
+
/>
|
|
11
|
+
)
|
|
12
|
+
)
|
|
13
|
+
Command.displayName = "Command"
|
|
14
|
+
|
|
15
|
+
export const CommandList = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
16
|
+
({ className, ...props }, ref) => (
|
|
17
|
+
<div
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn("editor-command-list", className)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
)
|
|
23
|
+
)
|
|
24
|
+
CommandList.displayName = "CommandList"
|
|
25
|
+
|
|
26
|
+
export const CommandGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
27
|
+
({ className, ...props }, ref) => (
|
|
28
|
+
<div
|
|
29
|
+
ref={ref}
|
|
30
|
+
className={cn("editor-command-group", className)}
|
|
31
|
+
{...props}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
CommandGroup.displayName = "CommandGroup"
|
|
36
|
+
|
|
37
|
+
export const CommandItem = React.forwardRef<
|
|
38
|
+
HTMLDivElement,
|
|
39
|
+
React.HTMLAttributes<HTMLDivElement> & { onSelect?: () => void; value?: string }
|
|
40
|
+
>(({ className, onSelect, ...props }, ref) => (
|
|
41
|
+
<div
|
|
42
|
+
ref={ref}
|
|
43
|
+
className={cn("editor-command-item", className)}
|
|
44
|
+
onClick={onSelect}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
))
|
|
48
|
+
CommandItem.displayName = "CommandItem"
|