mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 20:35:07 +03:00
added initial test of notesbooks
This commit is contained in:
1 parent
bd1ce11d1c
commit
bcb045f1e3
14 files changed
+1193
-17
No files matched your search
@@ -0,0 +1,164 @@
|
||||
'use client'
|
||||
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import YooptaEditor, {
|
||||
createYooptaEditor,
|
||||
YooptaContentValue,
|
||||
YooptaOnChangeOptions,
|
||||
} from '@yoopta/editor'
|
||||
import Paragraph from '@yoopta/paragraph'
|
||||
import { HeadingOne, HeadingTwo, HeadingThree } from '@yoopta/headings'
|
||||
import { BulletedList, NumberedList } from '@yoopta/lists'
|
||||
import Divider from '@yoopta/divider'
|
||||
import { Bold, Italic, CodeMark, Underline, Strike, Highlight } from '@yoopta/marks'
|
||||
import ActionMenuList from '@yoopta/action-menu-list'
|
||||
import Toolbar from '@yoopta/toolbar'
|
||||
|
||||
import { SQLQueryPlugin } from './plugins/SQLQueryPlugin'
|
||||
import { CustomActionMenuRender } from './components/CustomActionMenuRender'
|
||||
import { CustomToolbarRender } from './components/CustomToolbarRender'
|
||||
import {
|
||||
ParagraphRender,
|
||||
HeadingOneRender,
|
||||
HeadingTwoRender,
|
||||
HeadingThreeRender,
|
||||
BulletedListRender,
|
||||
NumberedListRender,
|
||||
DividerRender,
|
||||
} from './renders'
|
||||
|
||||
// Define plugins with custom renders that use Supabase design system
|
||||
const plugins = [
|
||||
Paragraph.extend({
|
||||
renders: {
|
||||
paragraph: ParagraphRender,
|
||||
},
|
||||
}),
|
||||
HeadingOne.extend({
|
||||
renders: {
|
||||
'heading-one': HeadingOneRender,
|
||||
},
|
||||
}),
|
||||
HeadingTwo.extend({
|
||||
renders: {
|
||||
'heading-two': HeadingTwoRender,
|
||||
},
|
||||
}),
|
||||
HeadingThree.extend({
|
||||
renders: {
|
||||
'heading-three': HeadingThreeRender,
|
||||
},
|
||||
}),
|
||||
BulletedList.extend({
|
||||
renders: {
|
||||
'bulleted-list': BulletedListRender,
|
||||
},
|
||||
}),
|
||||
NumberedList.extend({
|
||||
renders: {
|
||||
'numbered-list': NumberedListRender,
|
||||
},
|
||||
}),
|
||||
Divider.extend({
|
||||
renders: {
|
||||
divider: DividerRender,
|
||||
},
|
||||
}),
|
||||
SQLQueryPlugin,
|
||||
]
|
||||
|
||||
// Define marks
|
||||
const MARKS = [Bold, Italic, CodeMark, Underline, Strike, Highlight]
|
||||
|
||||
// Define tools with custom renders that match Supabase design system
|
||||
const TOOLS = {
|
||||
ActionMenu: {
|
||||
render: CustomActionMenuRender,
|
||||
tool: ActionMenuList,
|
||||
},
|
||||
Toolbar: {
|
||||
render: CustomToolbarRender,
|
||||
tool: Toolbar,
|
||||
},
|
||||
}
|
||||
|
||||
// Initial content with a welcome message
|
||||
const INITIAL_VALUE: YooptaContentValue = {
|
||||
'1': {
|
||||
id: '1',
|
||||
type: 'HeadingOne',
|
||||
value: [
|
||||
{
|
||||
id: '1-element',
|
||||
type: 'heading-one',
|
||||
children: [{ text: 'Welcome to Notebook' }],
|
||||
props: { nodeType: 'block' },
|
||||
},
|
||||
],
|
||||
meta: { order: 0, depth: 0 },
|
||||
},
|
||||
'2': {
|
||||
id: '2',
|
||||
type: 'Paragraph',
|
||||
value: [
|
||||
{
|
||||
id: '2-element',
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{
|
||||
text: 'This is a notebook for exploring your Postgres database. Use the / key to add blocks like text, headings, lists, or SQL queries.',
|
||||
},
|
||||
],
|
||||
props: { nodeType: 'block' },
|
||||
},
|
||||
],
|
||||
meta: { order: 1, depth: 0 },
|
||||
},
|
||||
'3': {
|
||||
id: '3',
|
||||
type: 'Paragraph',
|
||||
value: [
|
||||
{
|
||||
id: '3-element',
|
||||
type: 'paragraph',
|
||||
children: [
|
||||
{ text: 'Try typing /sql to add a SQL query block and start exploring your data.' },
|
||||
],
|
||||
props: { nodeType: 'block' },
|
||||
},
|
||||
],
|
||||
meta: { order: 2, depth: 0 },
|
||||
},
|
||||
}
|
||||
|
||||
export function Notebook() {
|
||||
const editor = useMemo(() => createYooptaEditor(), [])
|
||||
const selectionRef = useRef<HTMLDivElement>(null)
|
||||
const [value, setValue] = useState<YooptaContentValue>(INITIAL_VALUE)
|
||||
|
||||
const onChange = (newValue: YooptaContentValue, options: YooptaOnChangeOptions) => {
|
||||
setValue(newValue)
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={selectionRef} className="h-full w-full overflow-y-auto py-8 px-6 lg:px-12">
|
||||
<div className="w-full max-w-none">
|
||||
<YooptaEditor
|
||||
editor={editor}
|
||||
plugins={plugins}
|
||||
tools={TOOLS}
|
||||
marks={MARKS}
|
||||
selectionBoxRoot={selectionRef}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
autoFocus
|
||||
placeholder="Type '/' for commands..."
|
||||
style={{
|
||||
width: '100%',
|
||||
paddingBottom: '200px',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { ActionMenuRenderProps } from '@yoopta/action-menu-list'
|
||||
import { cn } from 'ui'
|
||||
import {
|
||||
Type,
|
||||
Heading1,
|
||||
Heading2,
|
||||
Heading3,
|
||||
List,
|
||||
ListOrdered,
|
||||
Minus,
|
||||
Database,
|
||||
} from 'lucide-react'
|
||||
|
||||
// Map plugin types to icons
|
||||
const PLUGIN_ICONS: Record<string, React.ReactNode> = {
|
||||
Paragraph: <Type size={18} />,
|
||||
HeadingOne: <Heading1 size={18} />,
|
||||
HeadingTwo: <Heading2 size={18} />,
|
||||
HeadingThree: <Heading3 size={18} />,
|
||||
BulletedList: <List size={18} />,
|
||||
NumberedList: <ListOrdered size={18} />,
|
||||
Divider: <Minus size={18} />,
|
||||
SQLQuery: <Database size={18} />,
|
||||
}
|
||||
|
||||
export function CustomActionMenuRender({
|
||||
actions,
|
||||
getItemProps,
|
||||
getRootProps,
|
||||
empty,
|
||||
}: ActionMenuRenderProps) {
|
||||
if (empty) {
|
||||
return (
|
||||
<div
|
||||
{...getRootProps()}
|
||||
className="z-50 min-w-[200px] overflow-hidden rounded-md border border-default bg-overlay shadow-lg"
|
||||
>
|
||||
<div className="px-3 py-2 text-sm text-foreground-light">No results found</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
{...getRootProps()}
|
||||
className="z-50 min-w-[220px] max-h-[300px] overflow-y-auto rounded-md border border-default bg-overlay shadow-lg"
|
||||
>
|
||||
<div className="p-1">
|
||||
{actions.map((action) => {
|
||||
const itemProps = getItemProps(action.type)
|
||||
const isSelected = itemProps['data-action-menu-item-selected'] === true
|
||||
|
||||
return (
|
||||
<button
|
||||
key={action.type}
|
||||
{...itemProps}
|
||||
className={cn(
|
||||
'flex w-full items-center gap-3 rounded-sm px-2 py-1.5 text-left text-sm transition-colors',
|
||||
'hover:bg-surface-200 focus:bg-surface-200 focus:outline-none',
|
||||
isSelected && 'bg-surface-200'
|
||||
)}
|
||||
>
|
||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md border border-default bg-surface-100 text-foreground-light">
|
||||
{PLUGIN_ICONS[action.type] || action.icon}
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium text-foreground">{action.title}</span>
|
||||
{action.description && (
|
||||
<span className="text-xs text-foreground-lighter">{action.description}</span>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { ToolbarRenderProps } from '@yoopta/toolbar'
|
||||
import { Bold, Italic, Underline, Strikethrough, Code, Highlighter } from 'lucide-react'
|
||||
import { cn } from 'ui'
|
||||
|
||||
const MARK_ICONS: Record<string, React.ReactNode> = {
|
||||
bold: <Bold size={16} />,
|
||||
italic: <Italic size={16} />,
|
||||
underline: <Underline size={16} />,
|
||||
strike: <Strikethrough size={16} />,
|
||||
code: <Code size={16} />,
|
||||
highlight: <Highlighter size={16} />,
|
||||
}
|
||||
|
||||
const MARKS = ['bold', 'italic', 'underline', 'strike', 'code', 'highlight'] as const
|
||||
|
||||
export function CustomToolbarRender({ editor }: ToolbarRenderProps) {
|
||||
const handleMarkClick = (mark: string) => {
|
||||
editor.formats[mark]?.toggle()
|
||||
}
|
||||
|
||||
const isMarkActive = (mark: string) => {
|
||||
return editor.formats[mark]?.isActive()
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="z-50 flex items-center gap-0.5 rounded-md border border-default bg-overlay p-1 shadow-lg">
|
||||
{MARKS.map((mark) => (
|
||||
<button
|
||||
key={mark}
|
||||
onClick={() => handleMarkClick(mark)}
|
||||
className={cn(
|
||||
'flex h-7 w-7 items-center justify-center rounded-sm transition-colors',
|
||||
'hover:bg-surface-200 focus:outline-none',
|
||||
isMarkActive(mark) && 'bg-surface-300 text-foreground'
|
||||
)}
|
||||
title={mark.charAt(0).toUpperCase() + mark.slice(1)}
|
||||
>
|
||||
{MARK_ICONS[mark]}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { CustomActionMenuRender } from './CustomActionMenuRender'
|
||||
export { CustomToolbarRender } from './CustomToolbarRender'
|
||||
@@ -0,0 +1 @@
|
||||
export { Notebook } from './Notebook'
|
||||
@@ -0,0 +1,108 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
import dayjs from 'dayjs'
|
||||
import { Bar, BarChart, CartesianGrid, Cell, Tooltip, XAxis, YAxis } from 'recharts'
|
||||
import { ChartContainer, ChartTooltipContent } from 'ui'
|
||||
import { CHART_COLORS } from 'components/ui/Charts/Charts.constants'
|
||||
import type { ChartConfig } from 'components/ui/QueryBlock/QueryBlock.types'
|
||||
|
||||
interface SQLQueryChartProps {
|
||||
results: any[]
|
||||
chartConfig: ChartConfig
|
||||
}
|
||||
|
||||
function getCumulativeResults(data: { rows: readonly any[] }, config: ChartConfig): any[] {
|
||||
const { xKey, yKey } = config
|
||||
if (!xKey || !yKey) return data.rows as any[]
|
||||
|
||||
let cumulative = 0
|
||||
return data.rows.map((row) => {
|
||||
cumulative += Number(row[yKey]) || 0
|
||||
return {
|
||||
...row,
|
||||
[yKey]: cumulative,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function SQLQueryChart({ results, chartConfig }: SQLQueryChartProps) {
|
||||
const { xKey, yKey, cumulative = false } = chartConfig
|
||||
const [focusDataIndex, setFocusDataIndex] = useState<number>()
|
||||
|
||||
const formattedQueryResult = useMemo(() => {
|
||||
return results?.map((row) => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(row).map(([key, value]) => {
|
||||
if (key === yKey) return [key, Number(value)]
|
||||
return [key, value]
|
||||
})
|
||||
)
|
||||
})
|
||||
}, [results, yKey])
|
||||
|
||||
const chartData = cumulative
|
||||
? getCumulativeResults({ rows: formattedQueryResult ?? [] }, chartConfig)
|
||||
: formattedQueryResult
|
||||
|
||||
const getDateFormat = (key: string) => {
|
||||
const value = chartData?.[0]?.[key] || ''
|
||||
if (typeof value === 'number') return 'number'
|
||||
if (dayjs(value).isValid()) return 'date'
|
||||
return 'string'
|
||||
}
|
||||
|
||||
const xKeyDateFormat = getDateFormat(xKey)
|
||||
|
||||
if (!xKey || !yKey) {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<p className="text-sm text-foreground-light">Select columns for the X and Y axes</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex-1 w-full">
|
||||
<ChartContainer
|
||||
className="aspect-auto px-3 py-2"
|
||||
style={{ height: '230px', minHeight: '230px' }}
|
||||
>
|
||||
<BarChart
|
||||
accessibilityLayer
|
||||
margin={{ left: -20, right: 0, top: 10 }}
|
||||
data={chartData}
|
||||
onMouseMove={(e: any) => {
|
||||
if (e.activeTooltipIndex !== focusDataIndex) {
|
||||
setFocusDataIndex(e.activeTooltipIndex)
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => setFocusDataIndex(undefined)}
|
||||
>
|
||||
<CartesianGrid vertical={false} stroke={CHART_COLORS.AXIS} />
|
||||
<XAxis
|
||||
dataKey={xKey}
|
||||
tickLine={{ stroke: CHART_COLORS.AXIS }}
|
||||
axisLine={{ stroke: CHART_COLORS.AXIS }}
|
||||
interval="preserveStartEnd"
|
||||
tickMargin={4}
|
||||
minTickGap={32}
|
||||
tickFormatter={(value) =>
|
||||
xKeyDateFormat === 'date' ? dayjs(value).format('MMM D YYYY HH:mm') : value
|
||||
}
|
||||
/>
|
||||
<YAxis tickLine={false} axisLine={false} tickMargin={4} />
|
||||
<Tooltip content={<ChartTooltipContent className="w-[150px]" />} />
|
||||
<Bar radius={1} dataKey={yKey}>
|
||||
{chartData?.map((_: any, index: number) => (
|
||||
<Cell
|
||||
key={`cell-${index}`}
|
||||
className="transition-all duration-100"
|
||||
fill="hsl(var(--chart-1))"
|
||||
opacity={focusDataIndex === undefined || focusDataIndex === index ? 1 : 0.4}
|
||||
/>
|
||||
))}
|
||||
</Bar>
|
||||
</BarChart>
|
||||
</ChartContainer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
+299
@@ -0,0 +1,299 @@
|
||||
import { useState, useCallback, useEffect } from 'react'
|
||||
import {
|
||||
PluginElementRenderProps,
|
||||
useYooptaEditor,
|
||||
Elements,
|
||||
useYooptaReadOnly,
|
||||
} from '@yoopta/editor'
|
||||
import { Play, ChevronDown, ChevronUp, Table2, BarChart3, Loader2, Pencil } from 'lucide-react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { useParams } from 'common'
|
||||
import { executeSql } from 'data/sql/execute-sql-query'
|
||||
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
|
||||
import Results from 'components/interfaces/SQLEditor/UtilityPanel/Results'
|
||||
import { Button, cn, Input_Shadcn_ } from 'ui'
|
||||
import { BlockViewConfiguration } from 'components/ui/QueryBlock/BlockViewConfiguration'
|
||||
import { DEFAULT_CHART_CONFIG, type ChartConfig } from 'components/ui/QueryBlock/QueryBlock.types'
|
||||
import { SQLQueryChart } from './SQLQueryChart'
|
||||
|
||||
export interface SQLQueryElementProps {
|
||||
sql: string
|
||||
label: string
|
||||
chartConfig: ChartConfig
|
||||
results?: any[]
|
||||
error?: string
|
||||
}
|
||||
|
||||
export const SQLQueryElement = ({
|
||||
element,
|
||||
children,
|
||||
attributes,
|
||||
blockId,
|
||||
}: PluginElementRenderProps) => {
|
||||
const editor = useYooptaEditor()
|
||||
const isReadOnly = useYooptaReadOnly()
|
||||
const { ref: projectRef } = useParams()
|
||||
const state = useDatabaseSelectorStateSnapshot()
|
||||
|
||||
const props = element.props as SQLQueryElementProps
|
||||
const { sql = '', label = 'Untitled Query', chartConfig = DEFAULT_CHART_CONFIG } = props
|
||||
|
||||
const [localSql, setLocalSql] = useState(sql)
|
||||
const [localLabel, setLocalLabel] = useState(label)
|
||||
const [localChartConfig, setLocalChartConfig] = useState<ChartConfig>(chartConfig)
|
||||
const [showSql, setShowSql] = useState(true)
|
||||
const [isEditingLabel, setIsEditingLabel] = useState(false)
|
||||
const [results, setResults] = useState<any[] | undefined>(props.results)
|
||||
const [error, setError] = useState<string | undefined>(props.error)
|
||||
|
||||
// Sync local state with element props
|
||||
useEffect(() => {
|
||||
setLocalSql(sql)
|
||||
setLocalLabel(label)
|
||||
setLocalChartConfig(chartConfig)
|
||||
setResults(props.results)
|
||||
setError(props.error)
|
||||
}, [sql, label, chartConfig, props.results, props.error])
|
||||
|
||||
const { mutate: executeQuery, isPending: isExecuting } = useMutation({
|
||||
mutationFn: async (query: string) => {
|
||||
const result = await executeSql({
|
||||
projectRef: projectRef!,
|
||||
connectionString: state.selectedDatabaseId,
|
||||
sql: query,
|
||||
})
|
||||
return result
|
||||
},
|
||||
onSuccess: (data) => {
|
||||
const resultRows = Array.isArray(data.result) ? data.result : []
|
||||
setResults(resultRows)
|
||||
setError(undefined)
|
||||
|
||||
// Update element with results
|
||||
Elements.updateElement(editor, blockId, {
|
||||
type: 'sql-query',
|
||||
props: {
|
||||
...props,
|
||||
sql: localSql,
|
||||
label: localLabel,
|
||||
results: resultRows,
|
||||
error: undefined,
|
||||
},
|
||||
})
|
||||
},
|
||||
onError: (err: any) => {
|
||||
const errorMessage = err?.message || 'An error occurred while executing the query'
|
||||
setError(errorMessage)
|
||||
setResults(undefined)
|
||||
|
||||
// Update element with error
|
||||
Elements.updateElement(editor, blockId, {
|
||||
type: 'sql-query',
|
||||
props: {
|
||||
...props,
|
||||
sql: localSql,
|
||||
label: localLabel,
|
||||
results: undefined,
|
||||
error: errorMessage,
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
const handleRunQuery = useCallback(() => {
|
||||
if (!localSql.trim() || !projectRef) return
|
||||
executeQuery(localSql)
|
||||
}, [localSql, projectRef, executeQuery])
|
||||
|
||||
const handleSqlChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
const newSql = e.target.value
|
||||
setLocalSql(newSql)
|
||||
|
||||
// Debounced update to element
|
||||
Elements.updateElement(editor, blockId, {
|
||||
type: 'sql-query',
|
||||
props: {
|
||||
...props,
|
||||
sql: newSql,
|
||||
},
|
||||
})
|
||||
},
|
||||
[editor, blockId, props]
|
||||
)
|
||||
|
||||
const handleLabelChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newLabel = e.target.value
|
||||
setLocalLabel(newLabel)
|
||||
}, [])
|
||||
|
||||
const handleLabelBlur = useCallback(() => {
|
||||
setIsEditingLabel(false)
|
||||
Elements.updateElement(editor, blockId, {
|
||||
type: 'sql-query',
|
||||
props: {
|
||||
...props,
|
||||
label: localLabel,
|
||||
},
|
||||
})
|
||||
}, [editor, blockId, props, localLabel])
|
||||
|
||||
const handleChartConfigChange = useCallback(
|
||||
(config: Partial<ChartConfig>) => {
|
||||
const newConfig = { ...localChartConfig, ...config }
|
||||
setLocalChartConfig(newConfig)
|
||||
|
||||
Elements.updateElement(editor, blockId, {
|
||||
type: 'sql-query',
|
||||
props: {
|
||||
...props,
|
||||
chartConfig: newConfig,
|
||||
},
|
||||
})
|
||||
},
|
||||
[editor, blockId, props, localChartConfig]
|
||||
)
|
||||
|
||||
const hasResults = Array.isArray(results) && results.length > 0
|
||||
const view = localChartConfig.view || 'table'
|
||||
|
||||
return (
|
||||
<div
|
||||
{...attributes}
|
||||
contentEditable={false}
|
||||
className="yoopta-sql-query my-4 rounded-md border border-default bg-surface-100 overflow-hidden"
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between px-3 py-2 border-b border-default bg-surface-200">
|
||||
<div className="flex items-center gap-2 flex-1 min-w-0">
|
||||
{isEditingLabel && !isReadOnly ? (
|
||||
<Input_Shadcn_
|
||||
value={localLabel}
|
||||
onChange={handleLabelChange}
|
||||
onBlur={handleLabelBlur}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleLabelBlur()
|
||||
}
|
||||
}}
|
||||
className="h-6 text-sm font-medium max-w-[200px]"
|
||||
autoFocus
|
||||
/>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => !isReadOnly && setIsEditingLabel(true)}
|
||||
className={cn(
|
||||
'text-sm font-medium text-foreground truncate',
|
||||
!isReadOnly && 'hover:text-foreground-light cursor-pointer'
|
||||
)}
|
||||
>
|
||||
{localLabel}
|
||||
</button>
|
||||
)}
|
||||
{!isReadOnly && !isEditingLabel && (
|
||||
<button
|
||||
onClick={() => setIsEditingLabel(true)}
|
||||
className="text-foreground-lighter hover:text-foreground transition-colors"
|
||||
>
|
||||
<Pencil size={12} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
type="text"
|
||||
size="tiny"
|
||||
className="w-7 h-7"
|
||||
onClick={() => setShowSql(!showSql)}
|
||||
icon={showSql ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
|
||||
/>
|
||||
|
||||
{hasResults && (
|
||||
<BlockViewConfiguration
|
||||
view={view}
|
||||
isChart={view === 'chart'}
|
||||
lockColumns={false}
|
||||
chartConfig={localChartConfig}
|
||||
columns={Object.keys(results?.[0] ?? {})}
|
||||
changeView={(nextView) => handleChartConfigChange({ view: nextView })}
|
||||
updateChartConfig={handleChartConfigChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!isReadOnly && (
|
||||
<Button
|
||||
type="text"
|
||||
size="tiny"
|
||||
className="w-7 h-7"
|
||||
onClick={handleRunQuery}
|
||||
disabled={isExecuting || !localSql.trim()}
|
||||
icon={
|
||||
isExecuting ? <Loader2 size={14} className="animate-spin" /> : <Play size={14} />
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* SQL Editor */}
|
||||
{showSql && (
|
||||
<div className="border-b border-default">
|
||||
<textarea
|
||||
value={localSql}
|
||||
onChange={handleSqlChange}
|
||||
placeholder="SELECT * FROM your_table LIMIT 10"
|
||||
className={cn(
|
||||
'w-full min-h-[100px] p-3 font-mono text-sm bg-transparent resize-y',
|
||||
'focus:outline-none focus:ring-0 border-0',
|
||||
'text-foreground placeholder:text-foreground-muted'
|
||||
)}
|
||||
readOnly={isReadOnly}
|
||||
onKeyDown={(e) => {
|
||||
// Run query on Cmd/Ctrl + Enter
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
handleRunQuery()
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Loading State */}
|
||||
{isExecuting && (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 size={24} className="animate-spin text-foreground-muted" />
|
||||
<span className="ml-2 text-sm text-foreground-muted">Executing query...</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Error State */}
|
||||
{!isExecuting && error && (
|
||||
<div className="p-3 bg-destructive-200">
|
||||
<p className="text-sm text-destructive font-mono">ERROR: {error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Results */}
|
||||
{!isExecuting && !error && results !== undefined && (
|
||||
<>
|
||||
{results.length === 0 ? (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<p className="text-sm text-foreground-light">No results returned from query</p>
|
||||
</div>
|
||||
) : view === 'chart' ? (
|
||||
<SQLQueryChart results={results} chartConfig={localChartConfig} />
|
||||
) : (
|
||||
<div className="max-h-64 overflow-auto">
|
||||
<Results rows={results} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Hidden children for Slate */}
|
||||
<div className="hidden">{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { YooptaPlugin, generateId } from '@yoopta/editor'
|
||||
import { SQLQueryElement, type SQLQueryElementProps } from './SQLQueryElement'
|
||||
import { DEFAULT_CHART_CONFIG } from 'components/ui/QueryBlock/QueryBlock.types'
|
||||
|
||||
const SQLQueryPlugin = new YooptaPlugin({
|
||||
type: 'SQLQuery',
|
||||
elements: {
|
||||
'sql-query': {
|
||||
render: SQLQueryElement,
|
||||
props: {
|
||||
sql: '',
|
||||
label: 'Untitled Query',
|
||||
chartConfig: DEFAULT_CHART_CONFIG,
|
||||
nodeType: 'void',
|
||||
},
|
||||
},
|
||||
},
|
||||
options: {
|
||||
display: {
|
||||
title: 'SQL Query',
|
||||
description: 'Execute SQL queries and visualize results',
|
||||
},
|
||||
shortcuts: ['sql', 'query', 'select'],
|
||||
},
|
||||
parsers: {
|
||||
html: {
|
||||
deserialize: {
|
||||
nodeNames: ['DIV'],
|
||||
parse: (el) => {
|
||||
if (el.getAttribute('data-type') === 'sql-query') {
|
||||
return {
|
||||
id: generateId(),
|
||||
type: 'sql-query',
|
||||
children: [{ text: '' }],
|
||||
props: {
|
||||
sql: el.getAttribute('data-sql') || '',
|
||||
label: el.getAttribute('data-label') || 'Untitled Query',
|
||||
chartConfig: DEFAULT_CHART_CONFIG,
|
||||
},
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
},
|
||||
serialize: (element) => {
|
||||
const props = element.props as SQLQueryElementProps
|
||||
return `<div data-type="sql-query" data-sql="${props.sql}" data-label="${props.label}">
|
||||
<pre><code class="language-sql">${props.sql}</code></pre>
|
||||
</div>`
|
||||
},
|
||||
},
|
||||
markdown: {
|
||||
serialize: (element) => {
|
||||
const props = element.props as SQLQueryElementProps
|
||||
return `\`\`\`sql\n${props.sql}\n\`\`\`\n`
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export { SQLQueryPlugin }
|
||||
@@ -0,0 +1,75 @@
|
||||
import { PluginElementRenderProps } from '@yoopta/editor'
|
||||
import { cn } from 'ui'
|
||||
|
||||
// Paragraph render
|
||||
export function ParagraphRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<p {...attributes} className={cn('text-base leading-relaxed text-foreground', 'mb-1')}>
|
||||
{children}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
// Heading One render
|
||||
export function HeadingOneRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<h1
|
||||
{...attributes}
|
||||
className={cn('text-3xl font-bold leading-tight text-foreground', 'mt-6 mb-2')}
|
||||
>
|
||||
{children}
|
||||
</h1>
|
||||
)
|
||||
}
|
||||
|
||||
// Heading Two render
|
||||
export function HeadingTwoRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<h2
|
||||
{...attributes}
|
||||
className={cn('text-2xl font-semibold leading-tight text-foreground', 'mt-5 mb-2')}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
)
|
||||
}
|
||||
|
||||
// Heading Three render
|
||||
export function HeadingThreeRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<h3
|
||||
{...attributes}
|
||||
className={cn('text-xl font-semibold leading-snug text-foreground', 'mt-4 mb-2')}
|
||||
>
|
||||
{children}
|
||||
</h3>
|
||||
)
|
||||
}
|
||||
|
||||
// Bulleted List render
|
||||
export function BulletedListRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<ul {...attributes} className={cn('list-disc pl-6 text-foreground', 'mb-2')}>
|
||||
{children}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
// Numbered List render
|
||||
export function NumberedListRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<ol {...attributes} className={cn('list-decimal pl-6 text-foreground', 'mb-2')}>
|
||||
{children}
|
||||
</ol>
|
||||
)
|
||||
}
|
||||
|
||||
// Divider render
|
||||
export function DividerRender({ attributes, children, element }: PluginElementRenderProps) {
|
||||
return (
|
||||
<div {...attributes} contentEditable={false} className="py-4">
|
||||
<hr className="border-t border-border-default" />
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Blocks, FileText, Lightbulb, List, Settings, Telescope } from 'lucide-react'
|
||||
import { Blocks, BookOpen, FileText, Lightbulb, List, Settings, Telescope } from 'lucide-react'
|
||||
|
||||
import { ICON_SIZE, ICON_STROKE_WIDTH } from 'components/interfaces/Sidebar'
|
||||
import { generateAuthMenu } from 'components/layouts/AuthLayout/AuthLayout.utils'
|
||||
@@ -28,6 +28,12 @@ export const generateToolRoutes = (ref?: string, project?: Project, features?: {
|
||||
icon: <SqlEditor size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
|
||||
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/sql`),
|
||||
},
|
||||
{
|
||||
key: 'notebook',
|
||||
label: 'Notebook',
|
||||
icon: <BookOpen size={ICON_SIZE} strokeWidth={ICON_STROKE_WIDTH} />,
|
||||
link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/notebook`),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
export type ChartConfig = {
|
||||
view?: 'table' | 'chart'
|
||||
type: 'bar' | 'line'
|
||||
cumulative: boolean
|
||||
xKey: string
|
||||
yKey: string
|
||||
showLabels?: boolean
|
||||
showGrid?: boolean
|
||||
}
|
||||
|
||||
export const DEFAULT_CHART_CONFIG: ChartConfig = {
|
||||
type: 'bar',
|
||||
cumulative: false,
|
||||
xKey: '',
|
||||
yKey: '',
|
||||
showLabels: false,
|
||||
showGrid: false,
|
||||
view: 'table',
|
||||
}
|
||||
@@ -75,6 +75,14 @@
|
||||
"@types/d3-geo": "^3.1.0",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"@vercel/functions": "^2.1.0",
|
||||
"@yoopta/action-menu-list": "^4.9.9",
|
||||
"@yoopta/divider": "^4.9.9",
|
||||
"@yoopta/editor": "^4.9.9",
|
||||
"@yoopta/headings": "^4.9.9",
|
||||
"@yoopta/lists": "^4.9.9",
|
||||
"@yoopta/marks": "^4.9.9",
|
||||
"@yoopta/paragraph": "^4.9.9",
|
||||
"@yoopta/toolbar": "^4.9.9",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"@zip.js/zip.js": "^2.7.29",
|
||||
"ai": "5.0.52",
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Notebook } from 'components/interfaces/Notebook/Notebook'
|
||||
import DefaultLayout from 'components/layouts/DefaultLayout'
|
||||
import { ProjectLayoutWithAuth } from 'components/layouts/ProjectLayout'
|
||||
import type { NextPageWithLayout } from 'types'
|
||||
|
||||
const NotebookPage: NextPageWithLayout = () => {
|
||||
return <Notebook />
|
||||
}
|
||||
|
||||
NotebookPage.getLayout = (page) => (
|
||||
<DefaultLayout>
|
||||
<ProjectLayoutWithAuth title="Notebook">{page}</ProjectLayoutWithAuth>
|
||||
</DefaultLayout>
|
||||
)
|
||||
|
||||
export default NotebookPage
|
||||
Generated
+312
-16
@@ -903,6 +903,30 @@ importers:
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.3.4
|
||||
version: 4.3.4(supports-color@8.1.1)(vite@7.1.11(@types/node@22.13.14)(jiti@2.5.1)(sass@1.77.4)(terser@5.39.0)(tsx@4.20.3)(yaml@2.8.1))
|
||||
'@yoopta/action-menu-list':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/divider':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/editor':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
'@yoopta/headings':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/lists':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/marks':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/paragraph':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/toolbar':
|
||||
specifier: ^4.9.9
|
||||
version: 4.9.9(@types/react-dom@18.3.0)(@types/react@18.3.3)(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@zip.js/zip.js':
|
||||
specifier: ^2.7.29
|
||||
version: 2.7.30
|
||||
@@ -3813,12 +3837,6 @@ packages:
|
||||
'@floating-ui/dom@1.5.3':
|
||||
resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==}
|
||||
|
||||
'@floating-ui/react-dom@2.0.2':
|
||||
resolution: {integrity: sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
|
||||
'@floating-ui/react-dom@2.1.3':
|
||||
resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==}
|
||||
peerDependencies:
|
||||
@@ -4763,6 +4781,9 @@ packages:
|
||||
'@jsr/std__toml@1.0.11':
|
||||
resolution: {integrity: sha512-+LZAizoPAPwMDmRZr86/xPrbO8E0Oq0BJ70mr1fNMobJ/6X6v15Jk16ZClFGukWgzBMd8ggiMWnzp24+N3VNZg==, tarball: https://npm.jsr.io/~/11/@jsr/std__toml/1.0.11.tgz}
|
||||
|
||||
'@juggle/resize-observer@3.4.0':
|
||||
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
|
||||
|
||||
'@kwsites/file-exists@1.1.1':
|
||||
resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
|
||||
|
||||
@@ -7002,6 +7023,11 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-icons@1.3.2':
|
||||
resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==}
|
||||
peerDependencies:
|
||||
react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc
|
||||
|
||||
'@radix-ui/react-id@1.0.1':
|
||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||
peerDependencies:
|
||||
@@ -7614,6 +7640,19 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-separator@1.1.7':
|
||||
resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-slider@1.1.2':
|
||||
resolution: {integrity: sha512-NKs15MJylfzVsCagVSWKhGGLNR1W9qWs+HtgbmjjVUB3B9+lb3PYoXxVju3kOrpf0VKyVCtZp+iTwVoqpa1Chw==}
|
||||
peerDependencies:
|
||||
@@ -7785,6 +7824,19 @@ packages:
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-toolbar@1.1.11':
|
||||
resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
|
||||
'@radix-ui/react-tooltip@1.0.7':
|
||||
resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==}
|
||||
peerDependencies:
|
||||
@@ -9513,6 +9565,9 @@ packages:
|
||||
'@types/hoist-non-react-statics@3.3.2':
|
||||
resolution: {integrity: sha512-YIQtIg4PKr7ZyqNPZObpxfHsHEmuB8dXCxd6qVcGuQVDK2bpsF7bYNnBJ4Nn7giuACZg+WewExgrtAJ3XnA4Xw==}
|
||||
|
||||
'@types/is-hotkey@0.1.10':
|
||||
resolution: {integrity: sha512-RvC8KMw5BCac1NvRRyaHgMMEtBaZ6wh0pyPTBu7izn4Sj/AX9Y4aXU5c7rX8PnM/knsuUpC1IeoBkANtxBypsQ==}
|
||||
|
||||
'@types/js-cookie@2.2.7':
|
||||
resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==}
|
||||
|
||||
@@ -10070,6 +10125,63 @@ packages:
|
||||
'@xtuc/long@4.2.2':
|
||||
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
||||
|
||||
'@yoopta/action-menu-list@4.9.9':
|
||||
resolution: {integrity: sha512-xsnKK0Oa2klq+m0AgsXeyMthMSKumrpq+cbr2WMDTTbPfDW4w9TEpvkG5HRmzhyXHSZw5xEsqaZzDE1htyD/fA==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@yoopta/divider@4.9.9':
|
||||
resolution: {integrity: sha512-+CS7n1puWDHO5Qm8rUAlyWNqq2oCvL869NLFLt2TtFP7OfrFuhaC2PBE8KTqMG3nfQVE9D/vhV/pQBPjfwUSiQ==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@yoopta/editor@4.9.9':
|
||||
resolution: {integrity: sha512-sKWGngswJ3Mw7J0kJuw+Ej7MOBda6rE0tQ8Y76JR6ZsllCjzYWmn4ynJPX1CMTbO8gCv/HaXr7hXBWD8TiApnw==}
|
||||
peerDependencies:
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
slate: ^0.102.0
|
||||
slate-react: ^0.102.0
|
||||
|
||||
'@yoopta/headings@4.9.9':
|
||||
resolution: {integrity: sha512-FW1pQQw6jHstyMMV2ltxv0pUsciklj7CLdZb5c9e4qw2E2LbDH7H0ssRLRzJXCo85zmLlKg6X8KnRYuSwudpZw==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@yoopta/lists@4.9.9':
|
||||
resolution: {integrity: sha512-9LM+zgECB7QiOTzWBLSS8UOs78zuXgH2s+YmoizqLpfePQIJ60LaOgzksKrQNFPXSKA5Mruj6kS7sz0pTkxA6g==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@yoopta/marks@4.9.9':
|
||||
resolution: {integrity: sha512-0aY+u/t7GJ99B66/AbTq4G1X6PRY3OqMrdDWjcnCDvHUjXWtbw83ERB3XDRUdLx7livHjy50yQxFVX1bkx7TSA==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@yoopta/paragraph@4.9.9':
|
||||
resolution: {integrity: sha512-0luS6xtRoi6NQ4ZavWwN3KAY/FxAwQqrvuJQ8g4yII1iPedFJxbgf8Q9fUFk+JMqbKcwM7/tkM1I+vn+soNBNQ==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@yoopta/toolbar@4.9.9':
|
||||
resolution: {integrity: sha512-xYBvLOhve3b1USGbw0d/naMJOa67EuI0xOU08lQmD1Gzdpu+vWsKP+VPh52gPYKbIfmZZcdfZEc4ozykjkwn7w==}
|
||||
peerDependencies:
|
||||
'@yoopta/editor': '>=4.0.0'
|
||||
react: '>=17.0.2'
|
||||
react-dom: '>=17.0.2'
|
||||
|
||||
'@zip.js/zip.js@2.7.30':
|
||||
resolution: {integrity: sha512-nhMvQCj+TF1ATBqYzFds7v+yxPBhdDYHh8J341KtC1D2UrVBUIYcYK4Jy1/GiTsxOXEiKOXSUxvPG/XR+7jMqw==}
|
||||
engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'}
|
||||
@@ -11817,6 +11929,10 @@ packages:
|
||||
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
direction@1.0.4:
|
||||
resolution: {integrity: sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==}
|
||||
hasBin: true
|
||||
|
||||
discontinuous-range@1.0.0:
|
||||
resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==}
|
||||
|
||||
@@ -13813,6 +13929,9 @@ packages:
|
||||
is-hexadecimal@2.0.1:
|
||||
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
|
||||
|
||||
is-hotkey@0.2.0:
|
||||
resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==}
|
||||
|
||||
is-inside-container@1.0.0:
|
||||
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
|
||||
engines: {node: '>=14.16'}
|
||||
@@ -14464,6 +14583,9 @@ packages:
|
||||
lodash.castarray@4.4.0:
|
||||
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
|
||||
|
||||
lodash.clonedeep@4.5.0:
|
||||
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
|
||||
|
||||
lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
|
||||
@@ -14558,6 +14680,11 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc
|
||||
|
||||
lucide-react@0.469.0:
|
||||
resolution: {integrity: sha512-28vvUnnKQ/dBwiCQtwJw7QauYnE7yd2Cyp4tTTJpvglX4EMpbflcdBgrgToX2j71B3YvugK/NH3BGUk+E/p/Fw==}
|
||||
peerDependencies:
|
||||
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
lucide-react@0.511.0:
|
||||
resolution: {integrity: sha512-VK5a2ydJ7xm8GvBeKLS9mu1pVK6ucef9780JVUjw6bAjJL/QXnd4Y0p7SPeOUMC27YhzNCZvm5d/QX0Tp3rc0w==}
|
||||
peerDependencies:
|
||||
@@ -16886,6 +17013,12 @@ packages:
|
||||
react: ^16.8.5 || ^17.0.0 || ^18.0.0
|
||||
react-dom: ^16.8.5 || ^17.0.0 || ^18.0.0
|
||||
|
||||
react-colorful@5.6.1:
|
||||
resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==}
|
||||
peerDependencies:
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
|
||||
react-compiler-runtime@19.1.0-rc.1:
|
||||
resolution: {integrity: sha512-wCt6g+cRh8g32QT18/9blfQHywGjYu+4FlEc3CW1mx3pPxYzZZl1y+VtqxRgnKKBCFLIGUYxog4j4rs5YS86hw==}
|
||||
peerDependencies:
|
||||
@@ -17917,6 +18050,16 @@ packages:
|
||||
resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
||||
slate-react@0.102.0:
|
||||
resolution: {integrity: sha512-SAcFsK5qaOxXjm0hr/t2pvIxfRv6HJGzmWkG58TdH4LdJCsgKS1n6hQOakHPlRVCwPgwvngB6R+t3pPjv8MqwA==}
|
||||
peerDependencies:
|
||||
react: '>=18.2.0'
|
||||
react-dom: '>=18.2.0'
|
||||
slate: '>=0.99.0'
|
||||
|
||||
slate@0.102.0:
|
||||
resolution: {integrity: sha512-RT+tHgqOyZVB1oFV9Pv99ajwh4OUCN9p28QWdnDTIzaN/kZxMsHeQN39UNAgtkZTVVVygFqeg7/R2jiptCvfyA==}
|
||||
|
||||
slice-ansi@3.0.0:
|
||||
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -18529,6 +18672,9 @@ packages:
|
||||
tiny-inflate@1.0.3:
|
||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||
|
||||
tiny-invariant@1.3.1:
|
||||
resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==}
|
||||
|
||||
tiny-invariant@1.3.3:
|
||||
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
||||
|
||||
@@ -19202,6 +19348,12 @@ packages:
|
||||
react: '>=18.0.0'
|
||||
scheduler: '>=0.19.0'
|
||||
|
||||
use-debounce@10.1.0:
|
||||
resolution: {integrity: sha512-lu87Za35V3n/MyMoEpD5zJv0k7hCn0p+V/fK2kWD+3k2u3kOCwO593UArbczg1fhfs2rqPEnHpULJ3KmGdDzvg==}
|
||||
engines: {node: '>= 16.0.0'}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
|
||||
use-debounce@7.0.1:
|
||||
resolution: {integrity: sha512-fOrzIw2wstbAJuv8PC9Vg4XgwyTLEOdq4y/Z3IhVl8DAE4svRcgyEUvrEXu+BMNgMoc3YND6qLT61kkgEKXh7Q==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
@@ -19306,6 +19458,10 @@ packages:
|
||||
validate.io-function@1.0.2:
|
||||
resolution: {integrity: sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==}
|
||||
|
||||
validator@13.15.26:
|
||||
resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
valtio@1.12.0:
|
||||
resolution: {integrity: sha512-co8NkCHeY0NsL0XsL/cSICt5VhTjwZlYT8mi50dYY5thx3r3w1D15A04Lvs9WL/y/Rf98vUKY5PAAJCTLHvkJw==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
@@ -21913,12 +22069,6 @@ snapshots:
|
||||
'@floating-ui/core': 1.5.0
|
||||
'@floating-ui/utils': 0.1.6
|
||||
|
||||
'@floating-ui/react-dom@2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.5.3
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@floating-ui/react-dom@2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.5.3
|
||||
@@ -23067,6 +23217,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@jsr/std__collections': 1.1.3
|
||||
|
||||
'@juggle/resize-observer@3.4.0': {}
|
||||
|
||||
'@kwsites/file-exists@1.1.1(supports-color@8.1.1)':
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@8.1.1)
|
||||
@@ -25733,6 +25885,10 @@ snapshots:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-icons@1.3.2(react@18.3.1)':
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
'@radix-ui/react-id@1.0.1(@types/react@18.3.3)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
@@ -26002,7 +26158,7 @@ snapshots:
|
||||
|
||||
'@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/react-dom': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@floating-ui/react-dom': 2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1)
|
||||
@@ -26020,7 +26176,7 @@ snapshots:
|
||||
|
||||
'@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/react-dom': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@floating-ui/react-dom': 2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-context': 1.1.1(@types/react@18.3.3)(react@18.3.1)
|
||||
@@ -26451,6 +26607,15 @@ snapshots:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-separator@1.1.7(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-slider@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
@@ -26640,6 +26805,21 @@ snapshots:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-toolbar@1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@radix-ui/primitive': 1.1.3
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-direction': 1.1.1(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-separator': 1.1.7(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.3
|
||||
'@types/react-dom': 18.3.0
|
||||
|
||||
'@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
@@ -29107,6 +29287,8 @@ snapshots:
|
||||
'@types/react': 18.3.3
|
||||
hoist-non-react-statics: 3.3.2
|
||||
|
||||
'@types/is-hotkey@0.1.10': {}
|
||||
|
||||
'@types/js-cookie@2.2.7': {}
|
||||
|
||||
'@types/js-yaml@4.0.6': {}
|
||||
@@ -29884,6 +30066,77 @@ snapshots:
|
||||
|
||||
'@xtuc/long@4.2.2': {}
|
||||
|
||||
'@yoopta/action-menu-list@4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/react': 0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-icons': 1.3.2(react@18.3.1)
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@yoopta/divider@4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)':
|
||||
dependencies:
|
||||
'@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@dnd-kit/sortable': 8.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
'@floating-ui/react': 0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-icons': 1.3.2(react@18.3.1)
|
||||
copy-to-clipboard: 3.3.3
|
||||
eventemitter3: 5.0.1
|
||||
immer: 10.1.1
|
||||
is-hotkey: 0.2.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
slate: 0.102.0
|
||||
slate-react: 0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0)
|
||||
validator: 13.15.26
|
||||
|
||||
'@yoopta/headings@4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@yoopta/lists@4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@yoopta/marks@4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@yoopta/paragraph@4.9.9(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@yoopta/toolbar@4.9.9(@types/react-dom@18.3.0)(@types/react@18.3.3)(@yoopta/editor@4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/react': 0.26.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-icons': 1.3.2(react@18.3.1)
|
||||
'@radix-ui/react-toolbar': 1.1.11(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@yoopta/editor': 4.9.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0))(slate@0.102.0)
|
||||
lodash.throttle: 4.1.1
|
||||
lucide-react: 0.469.0(react@18.3.1)
|
||||
react: 18.3.1
|
||||
react-colorful: 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
use-debounce: 10.1.0(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- '@types/react-dom'
|
||||
|
||||
'@zip.js/zip.js@2.7.30': {}
|
||||
|
||||
abab@2.0.6:
|
||||
@@ -31779,6 +32032,8 @@ snapshots:
|
||||
dependencies:
|
||||
path-type: 4.0.0
|
||||
|
||||
direction@1.0.4: {}
|
||||
|
||||
discontinuous-range@1.0.0: {}
|
||||
|
||||
dlv@1.1.3: {}
|
||||
@@ -33913,8 +34168,7 @@ snapshots:
|
||||
|
||||
imagescript@1.3.0: {}
|
||||
|
||||
immer@10.1.1:
|
||||
optional: true
|
||||
immer@10.1.1: {}
|
||||
|
||||
immutability-helper@3.1.1: {}
|
||||
|
||||
@@ -34161,6 +34415,8 @@ snapshots:
|
||||
|
||||
is-hexadecimal@2.0.1: {}
|
||||
|
||||
is-hotkey@0.2.0: {}
|
||||
|
||||
is-inside-container@1.0.0:
|
||||
dependencies:
|
||||
is-docker: 3.0.0
|
||||
@@ -34823,6 +35079,8 @@ snapshots:
|
||||
|
||||
lodash.castarray@4.4.0: {}
|
||||
|
||||
lodash.clonedeep@4.5.0: {}
|
||||
|
||||
lodash.defaults@4.2.0: {}
|
||||
|
||||
lodash.isarguments@3.1.0: {}
|
||||
@@ -34913,6 +35171,10 @@ snapshots:
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
lucide-react@0.469.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
lucide-react@0.511.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
@@ -38215,6 +38477,11 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- react-native
|
||||
|
||||
react-colorful@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
react-compiler-runtime@19.1.0-rc.1(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
@@ -39683,6 +39950,27 @@ snapshots:
|
||||
|
||||
slash@5.1.0: {}
|
||||
|
||||
slate-react@0.102.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(slate@0.102.0):
|
||||
dependencies:
|
||||
'@juggle/resize-observer': 3.4.0
|
||||
'@types/is-hotkey': 0.1.10
|
||||
'@types/lodash': 4.17.16
|
||||
direction: 1.0.4
|
||||
is-hotkey: 0.2.0
|
||||
is-plain-object: 5.0.0
|
||||
lodash: 4.17.21
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
scroll-into-view-if-needed: 3.1.0
|
||||
slate: 0.102.0
|
||||
tiny-invariant: 1.3.1
|
||||
|
||||
slate@0.102.0:
|
||||
dependencies:
|
||||
immer: 10.1.1
|
||||
is-plain-object: 5.0.0
|
||||
tiny-warning: 1.0.3
|
||||
|
||||
slice-ansi@3.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
@@ -40398,6 +40686,8 @@ snapshots:
|
||||
|
||||
tiny-inflate@1.0.3: {}
|
||||
|
||||
tiny-invariant@1.3.1: {}
|
||||
|
||||
tiny-invariant@1.3.3: {}
|
||||
|
||||
tiny-warning@1.0.3: {}
|
||||
@@ -41085,6 +41375,10 @@ snapshots:
|
||||
react: 18.3.1
|
||||
scheduler: 0.25.0
|
||||
|
||||
use-debounce@10.1.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
use-debounce@7.0.1(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
@@ -41160,6 +41454,8 @@ snapshots:
|
||||
|
||||
validate.io-function@1.0.2: {}
|
||||
|
||||
validator@13.15.26: {}
|
||||
|
||||
valtio@1.12.0(@types/react@18.3.3)(react@18.3.1):
|
||||
dependencies:
|
||||
derive-valtio: 0.1.0(valtio@1.12.0(@types/react@18.3.3)(react@18.3.1))
|
||||
|
||||
Reference in new issue
Block a user