@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
package/src/ui/select.tsx
CHANGED
|
@@ -1,171 +1,171 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { createPortal } from "react-dom"
|
|
3
|
-
import { cn } from "../lib/utils"
|
|
4
|
-
|
|
5
|
-
interface SelectContextValue {
|
|
6
|
-
value: string
|
|
7
|
-
onValueChange?: (value: string) => void
|
|
8
|
-
open: boolean
|
|
9
|
-
setOpen: (open: boolean) => void
|
|
10
|
-
triggerRef: React.RefObject<HTMLButtonElement | null>
|
|
11
|
-
disabled?: boolean
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const SelectContext = React.createContext<SelectContextValue | null>(null)
|
|
15
|
-
|
|
16
|
-
export interface SelectProps {
|
|
17
|
-
value: string
|
|
18
|
-
onValueChange?: (value: string) => void
|
|
19
|
-
children: React.ReactNode
|
|
20
|
-
disabled?: boolean
|
|
21
|
-
modal?: boolean
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function Select({ value, onValueChange, children, disabled }: SelectProps) {
|
|
25
|
-
const [open, setOpen] = React.useState(false)
|
|
26
|
-
const triggerRef = React.useRef<HTMLButtonElement>(null)
|
|
27
|
-
|
|
28
|
-
const contextValue = React.useMemo(() => ({
|
|
29
|
-
value, onValueChange, open, setOpen, triggerRef, disabled
|
|
30
|
-
}), [value, onValueChange, open, setOpen, disabled])
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<SelectContext.Provider value={contextValue}>
|
|
34
|
-
{children}
|
|
35
|
-
</SelectContext.Provider>
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface SelectTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
40
|
-
size?: "default" | "sm" | "lg" | "icon"
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function SelectTrigger({ className, children, size = "default", ...props }: SelectTriggerProps) {
|
|
44
|
-
const context = React.useContext(SelectContext)
|
|
45
|
-
if (!context) throw new Error("SelectTrigger must be used within Select")
|
|
46
|
-
|
|
47
|
-
const { triggerRef, disabled, open, setOpen } = context
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<button
|
|
51
|
-
ref={triggerRef}
|
|
52
|
-
type="button"
|
|
53
|
-
className={cn(
|
|
54
|
-
"editor-select",
|
|
55
|
-
size !== "default" && `editor-select--size-${size}`,
|
|
56
|
-
className
|
|
57
|
-
)}
|
|
58
|
-
onClick={() => !disabled && setOpen(!open)}
|
|
59
|
-
disabled={disabled || props.disabled}
|
|
60
|
-
{...props}
|
|
61
|
-
>
|
|
62
|
-
{children}
|
|
63
|
-
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" className="editor-select-icon">
|
|
64
|
-
<path d="M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.26618 11.9026 7.38064 11.95 7.49999 11.95C7.61933 11.95 7.73379 11.9026 7.81819 11.8182L10.0682 9.56819Z" fill="currentColor" fillRule="evenodd" clipRule="evenodd"></path>
|
|
65
|
-
</svg>
|
|
66
|
-
</button>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function SelectValue({ placeholder }: { placeholder?: string }) {
|
|
71
|
-
const context = React.useContext(SelectContext)
|
|
72
|
-
if (!context) throw new Error("SelectValue must be used within Select")
|
|
73
|
-
|
|
74
|
-
return <span>{context.value || placeholder}</span>
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function SelectContent({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
78
|
-
const context = React.useContext(SelectContext)
|
|
79
|
-
const [position, setPosition] = React.useState({ top: 0, left: 0, width: 0 })
|
|
80
|
-
const contentRef = React.useRef<HTMLDivElement>(null)
|
|
81
|
-
|
|
82
|
-
React.useEffect(() => {
|
|
83
|
-
if (context?.open && context.triggerRef.current) {
|
|
84
|
-
const rect = context.triggerRef.current.getBoundingClientRect()
|
|
85
|
-
setPosition({
|
|
86
|
-
top: rect.bottom + window.scrollY + 4,
|
|
87
|
-
left: rect.left + window.scrollX,
|
|
88
|
-
width: rect.width
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
// Simple click outside for portal
|
|
92
|
-
const handleClickOutside = (e: MouseEvent) => {
|
|
93
|
-
if (contentRef.current && !contentRef.current.contains(e.target as Node) &&
|
|
94
|
-
!context.triggerRef.current?.contains(e.target as Node)) {
|
|
95
|
-
context.setOpen(false)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
document.addEventListener("mousedown", handleClickOutside)
|
|
99
|
-
return () => document.removeEventListener("mousedown", handleClickOutside)
|
|
100
|
-
}
|
|
101
|
-
}, [context, context?.open, context?.triggerRef, context?.setOpen])
|
|
102
|
-
|
|
103
|
-
if (!context?.open) return null
|
|
104
|
-
|
|
105
|
-
return createPortal(
|
|
106
|
-
<div
|
|
107
|
-
ref={contentRef}
|
|
108
|
-
className={cn("editor-popover-content", className)}
|
|
109
|
-
style={{
|
|
110
|
-
position: "absolute",
|
|
111
|
-
top: position.top,
|
|
112
|
-
left: position.left,
|
|
113
|
-
minWidth: position.width,
|
|
114
|
-
width: "auto", // allow wider
|
|
115
|
-
padding: "4px",
|
|
116
|
-
zIndex: 9999
|
|
117
|
-
}}
|
|
118
|
-
{...props}
|
|
119
|
-
>
|
|
120
|
-
{children}
|
|
121
|
-
</div>,
|
|
122
|
-
document.body
|
|
123
|
-
)
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function SelectItem({ value, children, className, ...props }: React.HTMLAttributes<HTMLDivElement> & { value: string }) {
|
|
127
|
-
const context = React.useContext(SelectContext)
|
|
128
|
-
if (!context) throw new Error("SelectItem must be used within Select")
|
|
129
|
-
|
|
130
|
-
const isSelected = context.value === value
|
|
131
|
-
|
|
132
|
-
return (
|
|
133
|
-
<div
|
|
134
|
-
className={cn(
|
|
135
|
-
"editor-select-item",
|
|
136
|
-
className
|
|
137
|
-
)}
|
|
138
|
-
data-selected={isSelected}
|
|
139
|
-
onClick={() => {
|
|
140
|
-
context.onValueChange?.(value)
|
|
141
|
-
context.setOpen(false)
|
|
142
|
-
}}
|
|
143
|
-
{...props}
|
|
144
|
-
>
|
|
145
|
-
{isSelected && (
|
|
146
|
-
<span className="editor-select-item__check">
|
|
147
|
-
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" className="editor-icon-sm">
|
|
148
|
-
<path d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z" fill="currentColor" fillRule="evenodd" clipRule="evenodd"></path>
|
|
149
|
-
</svg>
|
|
150
|
-
</span>
|
|
151
|
-
)}
|
|
152
|
-
{children}
|
|
153
|
-
</div>
|
|
154
|
-
)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export function SelectGroup({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
158
|
-
return (
|
|
159
|
-
<div role="group" className={className} {...props}>
|
|
160
|
-
{children}
|
|
161
|
-
</div>
|
|
162
|
-
)
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function SelectLabel({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
166
|
-
return (
|
|
167
|
-
<div className={cn("editor-select-label", className)} {...props}>
|
|
168
|
-
{children}
|
|
169
|
-
</div>
|
|
170
|
-
)
|
|
171
|
-
}
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { createPortal } from "react-dom"
|
|
3
|
+
import { cn } from "../lib/utils"
|
|
4
|
+
|
|
5
|
+
interface SelectContextValue {
|
|
6
|
+
value: string
|
|
7
|
+
onValueChange?: (value: string) => void
|
|
8
|
+
open: boolean
|
|
9
|
+
setOpen: (open: boolean) => void
|
|
10
|
+
triggerRef: React.RefObject<HTMLButtonElement | null>
|
|
11
|
+
disabled?: boolean
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const SelectContext = React.createContext<SelectContextValue | null>(null)
|
|
15
|
+
|
|
16
|
+
export interface SelectProps {
|
|
17
|
+
value: string
|
|
18
|
+
onValueChange?: (value: string) => void
|
|
19
|
+
children: React.ReactNode
|
|
20
|
+
disabled?: boolean
|
|
21
|
+
modal?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function Select({ value, onValueChange, children, disabled }: SelectProps) {
|
|
25
|
+
const [open, setOpen] = React.useState(false)
|
|
26
|
+
const triggerRef = React.useRef<HTMLButtonElement>(null)
|
|
27
|
+
|
|
28
|
+
const contextValue = React.useMemo(() => ({
|
|
29
|
+
value, onValueChange, open, setOpen, triggerRef, disabled
|
|
30
|
+
}), [value, onValueChange, open, setOpen, disabled])
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<SelectContext.Provider value={contextValue}>
|
|
34
|
+
{children}
|
|
35
|
+
</SelectContext.Provider>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface SelectTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
40
|
+
size?: "default" | "sm" | "lg" | "icon"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function SelectTrigger({ className, children, size = "default", ...props }: SelectTriggerProps) {
|
|
44
|
+
const context = React.useContext(SelectContext)
|
|
45
|
+
if (!context) throw new Error("SelectTrigger must be used within Select")
|
|
46
|
+
|
|
47
|
+
const { triggerRef, disabled, open, setOpen } = context
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<button
|
|
51
|
+
ref={triggerRef}
|
|
52
|
+
type="button"
|
|
53
|
+
className={cn(
|
|
54
|
+
"editor-select",
|
|
55
|
+
size !== "default" && `editor-select--size-${size}`,
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
58
|
+
onClick={() => !disabled && setOpen(!open)}
|
|
59
|
+
disabled={disabled || props.disabled}
|
|
60
|
+
{...props}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" className="editor-select-icon">
|
|
64
|
+
<path d="M4.93179 5.43179C4.75605 5.60753 4.75605 5.89245 4.93179 6.06819C5.10753 6.24392 5.39245 6.24392 5.56819 6.06819L7.49999 4.13638L9.43179 6.06819C9.60753 6.24392 9.89245 6.24392 10.0682 6.06819C10.2439 5.89245 10.2439 5.60753 10.0682 5.43179L7.81819 3.18179C7.73379 3.0974 7.61933 3.04999 7.49999 3.04999C7.38064 3.04999 7.26618 3.0974 7.18179 3.18179L4.93179 5.43179ZM10.0682 9.56819C10.2439 9.39245 10.2439 9.10753 10.0682 8.93179C9.89245 8.75606 9.60753 8.75606 9.43179 8.93179L7.49999 10.8636L5.56819 8.93179C5.39245 8.75606 5.10753 8.75606 4.93179 8.93179C4.75605 9.10753 4.75605 9.39245 4.93179 9.56819L7.18179 11.8182C7.26618 11.9026 7.38064 11.95 7.49999 11.95C7.61933 11.95 7.73379 11.9026 7.81819 11.8182L10.0682 9.56819Z" fill="currentColor" fillRule="evenodd" clipRule="evenodd"></path>
|
|
65
|
+
</svg>
|
|
66
|
+
</button>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function SelectValue({ placeholder }: { placeholder?: string }) {
|
|
71
|
+
const context = React.useContext(SelectContext)
|
|
72
|
+
if (!context) throw new Error("SelectValue must be used within Select")
|
|
73
|
+
|
|
74
|
+
return <span>{context.value || placeholder}</span>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function SelectContent({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
78
|
+
const context = React.useContext(SelectContext)
|
|
79
|
+
const [position, setPosition] = React.useState({ top: 0, left: 0, width: 0 })
|
|
80
|
+
const contentRef = React.useRef<HTMLDivElement>(null)
|
|
81
|
+
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
if (context?.open && context.triggerRef.current) {
|
|
84
|
+
const rect = context.triggerRef.current.getBoundingClientRect()
|
|
85
|
+
setPosition({
|
|
86
|
+
top: rect.bottom + window.scrollY + 4,
|
|
87
|
+
left: rect.left + window.scrollX,
|
|
88
|
+
width: rect.width
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Simple click outside for portal
|
|
92
|
+
const handleClickOutside = (e: MouseEvent) => {
|
|
93
|
+
if (contentRef.current && !contentRef.current.contains(e.target as Node) &&
|
|
94
|
+
!context.triggerRef.current?.contains(e.target as Node)) {
|
|
95
|
+
context.setOpen(false)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
document.addEventListener("mousedown", handleClickOutside)
|
|
99
|
+
return () => document.removeEventListener("mousedown", handleClickOutside)
|
|
100
|
+
}
|
|
101
|
+
}, [context, context?.open, context?.triggerRef, context?.setOpen])
|
|
102
|
+
|
|
103
|
+
if (!context?.open) return null
|
|
104
|
+
|
|
105
|
+
return createPortal(
|
|
106
|
+
<div
|
|
107
|
+
ref={contentRef}
|
|
108
|
+
className={cn("editor-popover-content", className)}
|
|
109
|
+
style={{
|
|
110
|
+
position: "absolute",
|
|
111
|
+
top: position.top,
|
|
112
|
+
left: position.left,
|
|
113
|
+
minWidth: position.width,
|
|
114
|
+
width: "auto", // allow wider
|
|
115
|
+
padding: "4px",
|
|
116
|
+
zIndex: 9999
|
|
117
|
+
}}
|
|
118
|
+
{...props}
|
|
119
|
+
>
|
|
120
|
+
{children}
|
|
121
|
+
</div>,
|
|
122
|
+
document.body
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function SelectItem({ value, children, className, ...props }: React.HTMLAttributes<HTMLDivElement> & { value: string }) {
|
|
127
|
+
const context = React.useContext(SelectContext)
|
|
128
|
+
if (!context) throw new Error("SelectItem must be used within Select")
|
|
129
|
+
|
|
130
|
+
const isSelected = context.value === value
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div
|
|
134
|
+
className={cn(
|
|
135
|
+
"editor-select-item",
|
|
136
|
+
className
|
|
137
|
+
)}
|
|
138
|
+
data-selected={isSelected}
|
|
139
|
+
onClick={() => {
|
|
140
|
+
context.onValueChange?.(value)
|
|
141
|
+
context.setOpen(false)
|
|
142
|
+
}}
|
|
143
|
+
{...props}
|
|
144
|
+
>
|
|
145
|
+
{isSelected && (
|
|
146
|
+
<span className="editor-select-item__check">
|
|
147
|
+
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" className="editor-icon-sm">
|
|
148
|
+
<path d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z" fill="currentColor" fillRule="evenodd" clipRule="evenodd"></path>
|
|
149
|
+
</svg>
|
|
150
|
+
</span>
|
|
151
|
+
)}
|
|
152
|
+
{children}
|
|
153
|
+
</div>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function SelectGroup({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
158
|
+
return (
|
|
159
|
+
<div role="group" className={className} {...props}>
|
|
160
|
+
{children}
|
|
161
|
+
</div>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function SelectLabel({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
166
|
+
return (
|
|
167
|
+
<div className={cn("editor-select-label", className)} {...props}>
|
|
168
|
+
{children}
|
|
169
|
+
</div>
|
|
170
|
+
)
|
|
171
|
+
}
|
package/src/ui/separator.tsx
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
|
|
4
|
-
export const Separator = React.forwardRef<
|
|
5
|
-
HTMLDivElement,
|
|
6
|
-
React.HTMLAttributes<HTMLDivElement> & { orientation?: "horizontal" | "vertical" }
|
|
7
|
-
>(({ className, orientation = "horizontal", ...props }, ref) => (
|
|
8
|
-
<div
|
|
9
|
-
ref={ref}
|
|
10
|
-
role="separator"
|
|
11
|
-
aria-orientation={orientation}
|
|
12
|
-
className={cn(
|
|
13
|
-
"editor-separator",
|
|
14
|
-
`editor-separator--${orientation}`,
|
|
15
|
-
className
|
|
16
|
-
)}
|
|
17
|
-
{...props}
|
|
18
|
-
/>
|
|
19
|
-
))
|
|
20
|
-
Separator.displayName = "Separator"
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
export const Separator = React.forwardRef<
|
|
5
|
+
HTMLDivElement,
|
|
6
|
+
React.HTMLAttributes<HTMLDivElement> & { orientation?: "horizontal" | "vertical" }
|
|
7
|
+
>(({ className, orientation = "horizontal", ...props }, ref) => (
|
|
8
|
+
<div
|
|
9
|
+
ref={ref}
|
|
10
|
+
role="separator"
|
|
11
|
+
aria-orientation={orientation}
|
|
12
|
+
className={cn(
|
|
13
|
+
"editor-separator",
|
|
14
|
+
`editor-separator--${orientation}`,
|
|
15
|
+
className
|
|
16
|
+
)}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
))
|
|
20
|
+
Separator.displayName = "Separator"
|
package/src/ui/slider.tsx
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
|
|
4
|
-
export const Slider = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(
|
|
5
|
-
({ className, ...props }, ref) => (
|
|
6
|
-
<input
|
|
7
|
-
type="range"
|
|
8
|
-
ref={ref}
|
|
9
|
-
className={cn("editor-slider-input", className)}
|
|
10
|
-
{...props}
|
|
11
|
-
/>
|
|
12
|
-
)
|
|
13
|
-
)
|
|
14
|
-
Slider.displayName = "Slider"
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
export const Slider = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(
|
|
5
|
+
({ className, ...props }, ref) => (
|
|
6
|
+
<input
|
|
7
|
+
type="range"
|
|
8
|
+
ref={ref}
|
|
9
|
+
className={cn("editor-slider-input", className)}
|
|
10
|
+
{...props}
|
|
11
|
+
/>
|
|
12
|
+
)
|
|
13
|
+
)
|
|
14
|
+
Slider.displayName = "Slider"
|
package/src/ui/slot.tsx
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Slot as RadixSlot } from "@radix-ui/react-slot"
|
|
2
|
-
|
|
3
|
-
export const Slot = RadixSlot
|
|
1
|
+
import { Slot as RadixSlot } from "@radix-ui/react-slot"
|
|
2
|
+
|
|
3
|
+
export const Slot = RadixSlot
|
package/src/ui/tabs.tsx
CHANGED
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cn } from "../lib/utils"
|
|
3
|
-
|
|
4
|
-
const TabsContext = React.createContext<{
|
|
5
|
-
value: string
|
|
6
|
-
onValueChange: (value: string) => void
|
|
7
|
-
} | null>(null)
|
|
8
|
-
|
|
9
|
-
export function Tabs({
|
|
10
|
-
defaultValue,
|
|
11
|
-
value: controlledValue,
|
|
12
|
-
onValueChange,
|
|
13
|
-
children,
|
|
14
|
-
className,
|
|
15
|
-
...props
|
|
16
|
-
}: {
|
|
17
|
-
defaultValue?: string
|
|
18
|
-
value?: string
|
|
19
|
-
onValueChange?: (value: string) => void
|
|
20
|
-
children: React.ReactNode
|
|
21
|
-
className?: string
|
|
22
|
-
}) {
|
|
23
|
-
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue || "")
|
|
24
|
-
const value = controlledValue ?? uncontrolledValue
|
|
25
|
-
const setValue = onValueChange ?? setUncontrolledValue
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<TabsContext.Provider value={{ value, onValueChange: setValue }}>
|
|
29
|
-
<div className={cn(className)} {...props}>
|
|
30
|
-
{children}
|
|
31
|
-
</div>
|
|
32
|
-
</TabsContext.Provider>
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function TabsList({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
37
|
-
return (
|
|
38
|
-
<div
|
|
39
|
-
className={cn(
|
|
40
|
-
"editor-tabs-list",
|
|
41
|
-
className
|
|
42
|
-
)}
|
|
43
|
-
{...props}
|
|
44
|
-
>
|
|
45
|
-
{children}
|
|
46
|
-
</div>
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function TabsTrigger({ value, className, children, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement> & { value: string }) {
|
|
51
|
-
const context = React.useContext(TabsContext)
|
|
52
|
-
const isSelected = context?.value === value
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<button
|
|
56
|
-
type="button"
|
|
57
|
-
className={cn(
|
|
58
|
-
"editor-tabs-trigger",
|
|
59
|
-
className
|
|
60
|
-
)}
|
|
61
|
-
data-state={isSelected ? "active" : "inactive"}
|
|
62
|
-
onClick={() => context?.onValueChange(value)}
|
|
63
|
-
{...props}
|
|
64
|
-
>
|
|
65
|
-
{children}
|
|
66
|
-
</button>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function TabsContent({ value, className, children, ...props }: React.HTMLAttributes<HTMLDivElement> & { value: string }) {
|
|
71
|
-
const context = React.useContext(TabsContext)
|
|
72
|
-
const isSelected = context?.value === value
|
|
73
|
-
|
|
74
|
-
if (!isSelected) return null
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<div
|
|
78
|
-
className={cn(
|
|
79
|
-
"editor-tabs-content",
|
|
80
|
-
className
|
|
81
|
-
)}
|
|
82
|
-
{...props}
|
|
83
|
-
>
|
|
84
|
-
{children}
|
|
85
|
-
</div>
|
|
86
|
-
)
|
|
87
|
-
}
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { cn } from "../lib/utils"
|
|
3
|
+
|
|
4
|
+
const TabsContext = React.createContext<{
|
|
5
|
+
value: string
|
|
6
|
+
onValueChange: (value: string) => void
|
|
7
|
+
} | null>(null)
|
|
8
|
+
|
|
9
|
+
export function Tabs({
|
|
10
|
+
defaultValue,
|
|
11
|
+
value: controlledValue,
|
|
12
|
+
onValueChange,
|
|
13
|
+
children,
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}: {
|
|
17
|
+
defaultValue?: string
|
|
18
|
+
value?: string
|
|
19
|
+
onValueChange?: (value: string) => void
|
|
20
|
+
children: React.ReactNode
|
|
21
|
+
className?: string
|
|
22
|
+
}) {
|
|
23
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue || "")
|
|
24
|
+
const value = controlledValue ?? uncontrolledValue
|
|
25
|
+
const setValue = onValueChange ?? setUncontrolledValue
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<TabsContext.Provider value={{ value, onValueChange: setValue }}>
|
|
29
|
+
<div className={cn(className)} {...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</div>
|
|
32
|
+
</TabsContext.Provider>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function TabsList({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
className={cn(
|
|
40
|
+
"editor-tabs-list",
|
|
41
|
+
className
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
</div>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function TabsTrigger({ value, className, children, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement> & { value: string }) {
|
|
51
|
+
const context = React.useContext(TabsContext)
|
|
52
|
+
const isSelected = context?.value === value
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
className={cn(
|
|
58
|
+
"editor-tabs-trigger",
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
data-state={isSelected ? "active" : "inactive"}
|
|
62
|
+
onClick={() => context?.onValueChange(value)}
|
|
63
|
+
{...props}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</button>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function TabsContent({ value, className, children, ...props }: React.HTMLAttributes<HTMLDivElement> & { value: string }) {
|
|
71
|
+
const context = React.useContext(TabsContext)
|
|
72
|
+
const isSelected = context?.value === value
|
|
73
|
+
|
|
74
|
+
if (!isSelected) return null
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div
|
|
78
|
+
className={cn(
|
|
79
|
+
"editor-tabs-content",
|
|
80
|
+
className
|
|
81
|
+
)}
|
|
82
|
+
{...props}
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</div>
|
|
86
|
+
)
|
|
87
|
+
}
|