Skip to content

Commit

Permalink
feat
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfeng33 committed Dec 4, 2024
1 parent 4b1ea0d commit 5b8072d
Show file tree
Hide file tree
Showing 25 changed files with 918 additions and 121 deletions.
89 changes: 89 additions & 0 deletions apps/www/src/app/(app)/dev/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client';

import { withProps } from '@udecode/cn';
import {
BaseBoldPlugin,
BaseCodePlugin,
BaseItalicPlugin,
BaseStrikethroughPlugin,
BaseSubscriptPlugin,
BaseSuperscriptPlugin,
BaseUnderlinePlugin,
} from '@udecode/plate-basic-marks';
import { BaseBlockquotePlugin } from '@udecode/plate-block-quote';
import {
BaseCodeBlockPlugin,
BaseCodeLinePlugin,
BaseCodeSyntaxPlugin,
} from '@udecode/plate-code-block';
import {
BaseParagraphPlugin,
PlateStatic,
createSlateEditor,
} from '@udecode/plate-common';
import { BaseHeadingPlugin, HEADING_KEYS } from '@udecode/plate-heading';
import { serializeHtml } from '@udecode/plate-html';

import { basicNodesValue } from '@/registry/default/example/values/basic-nodes-value';
import { BlockquoteStaticElement } from '@/registry/default/plate-ui/blockquote-element';
import { CodeBlockElementStatic } from '@/registry/default/plate-ui/code-block-element';
import { CodeStaticLeaf } from '@/registry/default/plate-ui/code-leaf';
import { CodeLineStaticElement } from '@/registry/default/plate-ui/code-line-element';
import { CodeSyntaxStaticLeaf } from '@/registry/default/plate-ui/code-syntax-leaf';
import { HeadingStaticElement } from '@/registry/default/plate-ui/heading-element';
import {
ParagraphStaticElement,
PlateStaticLeaf,
} from '@/registry/default/plate-ui/paragraph-element';

export default function DevPage() {
const editorStatic = createSlateEditor({
plugins: [
BaseParagraphPlugin,
BaseHeadingPlugin,
BaseBoldPlugin,
BaseCodePlugin,
BaseItalicPlugin,
BaseStrikethroughPlugin,
BaseSubscriptPlugin,
BaseSuperscriptPlugin,
BaseUnderlinePlugin,
BaseBlockquotePlugin,
BaseCodeBlockPlugin,
],
staticComponents: {
[BaseBlockquotePlugin.key]: BlockquoteStaticElement,
[BaseBoldPlugin.key]: withProps(PlateStaticLeaf, { as: 'strong' }),
[BaseCodeBlockPlugin.key]: CodeBlockElementStatic,
[BaseCodeLinePlugin.key]: CodeLineStaticElement,
[BaseCodePlugin.key]: CodeStaticLeaf,
[BaseCodeSyntaxPlugin.key]: CodeSyntaxStaticLeaf,
[BaseItalicPlugin.key]: withProps(PlateStaticLeaf, { as: 'em' }),
[BaseParagraphPlugin.key]: ParagraphStaticElement,
[BaseStrikethroughPlugin.key]: withProps(PlateStaticLeaf, { as: 'del' }),
[BaseSubscriptPlugin.key]: withProps(PlateStaticLeaf, { as: 'sub' }),
[BaseSuperscriptPlugin.key]: withProps(PlateStaticLeaf, { as: 'sup' }),
[BaseUnderlinePlugin.key]: withProps(PlateStaticLeaf, { as: 'u' }),
[HEADING_KEYS.h1]: withProps(HeadingStaticElement, { variant: 'h1' }),
[HEADING_KEYS.h2]: withProps(HeadingStaticElement, { variant: 'h2' }),
[HEADING_KEYS.h3]: withProps(HeadingStaticElement, { variant: 'h3' }),
[HEADING_KEYS.h4]: withProps(HeadingStaticElement, { variant: 'h4' }),
[HEADING_KEYS.h5]: withProps(HeadingStaticElement, { variant: 'h5' }),
[HEADING_KEYS.h6]: withProps(HeadingStaticElement, { variant: 'h6' }),
},
value: [...basicNodesValue],
});

const html = serializeHtml(editorStatic, {
convertNewLinesToHtmlBr: true,
nodes: editorStatic.children,
stripWhitespace: true,
});
console.log('🚀 ~ DevPage ~ html:', html);

return (
<div className="mx-auto w-1/2">
<PlateStatic editor={editorStatic} />
</div>
);
}
10 changes: 10 additions & 0 deletions apps/www/src/registry/default/plate-ui/blockquote-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import React from 'react';

import type { StaticElementProps } from '@udecode/plate-common';

import { cn, withRef } from '@udecode/cn';

import { PlateElement } from './plate-element';
Expand All @@ -20,3 +22,11 @@ export const BlockquoteElement = withRef<typeof PlateElement>(
);
}
);

export const BlockquoteStaticElement = (props: StaticElementProps) => {
return (
<blockquote className="my-1 border-l-2 pl-6 italic">
{props.children}
</blockquote>
);
};
80 changes: 49 additions & 31 deletions apps/www/src/registry/default/plate-ui/code-block-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,56 @@

import React from 'react';

import { cn, withRef } from '@udecode/cn';
import { useCodeBlockElementState } from '@udecode/plate-code-block/react';
import type { TCodeBlockElement } from '@udecode/plate-code-block';
import type { StaticElementProps } from '@udecode/plate-common';

import { CodeBlockCombobox } from './code-block-combobox';
import { PlateElement } from './plate-element';
import { cn } from '@udecode/cn';

import './code-block-element.css';

export const CodeBlockElement = withRef<typeof PlateElement>(
({ children, className, ...props }, ref) => {
const { element } = props;
const state = useCodeBlockElementState({ element });

return (
<PlateElement
ref={ref}
className={cn('relative py-1', state.className, className)}
{...props}
>
<pre className="overflow-x-auto rounded-md bg-muted px-6 py-8 font-mono text-sm leading-[normal] [tab-size:2]">
<code>{children}</code>
</pre>

{state.syntax && (
<div
className="absolute right-2 top-2 z-10 select-none"
contentEditable={false}
>
<CodeBlockCombobox />
</div>
)}
</PlateElement>
);
}
);
// export const CodeBlockElement = withRef<typeof PlateElement>(
// ({ children, className, ...props }, ref) => {
// const { element } = props;

// const state = useCodeBlockElementState({ element });

// return (
// <PlateElement
// ref={ref}
// className={cn('relative py-1', className)}
// {...props}
// >
// <pre className="overflow-x-auto rounded-md bg-muted px-6 py-8 font-mono text-sm leading-[normal] [tab-size:2]">
// <code>{children}</code>
// </pre>

// {state.syntax && (
// <div
// className="absolute right-2 top-2 z-10 select-none"
// contentEditable={false}
// >
// <CodeBlockCombobox />
// </div>
// )}
// </PlateElement>
// );
// }
// );

export const CodeBlockElementStatic = (
props: StaticElementProps<TCodeBlockElement>
) => {
const { attributes, children, element } = props;

const codeClassName = element?.lang
? `${element.lang} language-${element.lang}`
: '';

return (
<div className={cn('relative py-1', codeClassName)} {...attributes}>
<pre className="overflow-x-auto rounded-md bg-muted px-6 py-8 font-mono text-sm leading-[normal] [tab-size:2]">
<code>{children}</code>
</pre>
</div>
);
};
12 changes: 12 additions & 0 deletions apps/www/src/registry/default/plate-ui/code-leaf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import React from 'react';

import type { StaticLeafProps } from '@udecode/plate-common';

import { cn, withRef } from '@udecode/cn';
import { PlateLeaf } from '@udecode/plate-common/react';

Expand All @@ -22,3 +24,13 @@ export const CodeLeaf = withRef<typeof PlateLeaf>(
);
}
);

export const CodeStaticLeaf = (props: StaticLeafProps) => {
return (
<span>
<code className="whitespace-pre-wrap rounded-md bg-muted px-[0.3em] py-[0.2em] font-mono text-sm">
{props.children}
</code>
</span>
);
};
8 changes: 8 additions & 0 deletions apps/www/src/registry/default/plate-ui/code-line-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@

import React from 'react';

import type { StaticElementProps } from '@udecode/plate-common';

import { withRef } from '@udecode/cn';

import { PlateElement } from './plate-element';

export const CodeLineElement = withRef<typeof PlateElement>((props, ref) => (
<PlateElement ref={ref} {...props} />
));

export const CodeLineStaticElement = (props: StaticElementProps) => {
const { children } = props;

return <div>{children}</div>;
};
6 changes: 6 additions & 0 deletions apps/www/src/registry/default/plate-ui/code-syntax-leaf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import React from 'react';

import type { StaticLeafProps } from '@udecode/plate-core';

import { withRef } from '@udecode/cn';
import { useCodeSyntaxLeaf } from '@udecode/plate-code-block/react';
import { PlateLeaf } from '@udecode/plate-common/react';
Expand All @@ -19,3 +21,7 @@ export const CodeSyntaxLeaf = withRef<typeof PlateLeaf>(
);
}
);

export function CodeSyntaxStaticLeaf({ children, ...props }: StaticLeafProps) {
return <div {...props}>{children}</div>;
}
4 changes: 2 additions & 2 deletions apps/www/src/registry/default/plate-ui/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
} from '@udecode/plate-common/react';
import { cva } from 'class-variance-authority';

const editorContainerVariants = cva(
export const editorContainerVariants = cva(
'relative w-full cursor-text overflow-y-auto caret-primary selection:bg-brand/25 focus-visible:outline-none [&_.slate-selection-area]:border [&_.slate-selection-area]:border-brand/25 [&_.slate-selection-area]:bg-brand/15',
{
defaultVariants: {
Expand Down Expand Up @@ -57,7 +57,7 @@ export const EditorContainer = ({

EditorContainer.displayName = 'EditorContainer';

const editorVariants = cva(
export const editorVariants = cva(
cn(
'group/editor',
'relative w-full overflow-x-hidden whitespace-pre-wrap break-words',
Expand Down
17 changes: 17 additions & 0 deletions apps/www/src/registry/default/plate-ui/heading-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import React from 'react';

import type { StaticElementProps } from '@udecode/plate-common';

import { withRef, withVariants } from '@udecode/cn';
import { cva } from 'class-variance-authority';

Expand Down Expand Up @@ -38,3 +40,18 @@ export const HeadingElement = withRef<typeof HeadingElementVariants>(
);
}
);

interface HeadingElementViewProps extends StaticElementProps {
variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
}

export const HeadingStaticElement = ({
children,
variant = 'h1',
}: HeadingElementViewProps) => {
const Component = variant as any;

return (
<Component className={headingVariants({ variant })}>{children}</Component>
);
};
15 changes: 15 additions & 0 deletions apps/www/src/registry/default/plate-ui/paragraph-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

import React from 'react';

import type {
StaticElementProps,
StaticLeafProps,
} from '@udecode/plate-common';

import { cn } from '@udecode/cn';
import { withRef } from '@udecode/plate-common/react';

Expand All @@ -20,3 +25,13 @@ export const ParagraphElement = withRef<typeof PlateElement>(
);
}
);

export const ParagraphStaticElement = ({ children }: StaticElementProps) => {
return <div className="m-0 px-0 py-1">{children}</div>;
};

export function PlateStaticLeaf({ as, children }: StaticLeafProps) {
const Leaf = (as ?? 'span') as any;

return <Leaf>{children}</Leaf>;
}
2 changes: 2 additions & 0 deletions packages/core/src/lib/editor/SlateEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {
InjectNodeProps,
} from '../plugin/SlatePlugin';
import type { CorePlugin } from '../plugins';
import type { NodeComponent } from './withSlate';

export type BaseEditor = TEditor & {
key: any;
Expand Down Expand Up @@ -98,6 +99,7 @@ export type SlateEditor = BaseEditor & {

plugins: Record<string, AnyEditorPlugin>;

staticComponents: Record<string, NodeComponent>;
// Alias for transforms
tf: SlateEditor['transforms'];
transforms: UnionToIntersection<InferTransforms<CorePlugin>>;
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/lib/editor/withSlate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import { getPluginType, getSlatePlugin } from '../plugin/getSlatePlugin';
import { type CorePlugin, getCorePlugins } from '../plugins/getCorePlugins';
import { pipeNormalizeInitialValue } from '../utils/pipeNormalizeInitialValue';
import { resolvePlugins } from '../utils/resolvePlugins';
import { resolveStaticPlugin } from '../utils/resolveStaticPlugin';

export type NodeComponent<T = any> = React.FC<T>;

export type StaticComponents = Record<string, NodeComponent>;

export type BaseWithSlateOptions<P extends AnyPluginConfig = CorePlugin> = {
id?: any;
Expand Down Expand Up @@ -49,6 +54,8 @@ export type BaseWithSlateOptions<P extends AnyPluginConfig = CorePlugin> = {
* @default false
*/
shouldNormalizeEditor?: boolean;

staticComponents?: Record<string, NodeComponent>;
};

export type WithSlateOptions<
Expand Down Expand Up @@ -96,6 +103,7 @@ export const withSlate = <
rootPlugin,
selection,
shouldNormalizeEditor,
staticComponents,
value,
...pluginConfig
}: WithSlateOptions<V, P> = {}
Expand Down Expand Up @@ -188,6 +196,8 @@ export const withSlate = <

resolvePlugins(editor, [rootPluginInstance]);

resolveStaticPlugin(editor, staticComponents ?? {});

if (typeof value === 'string') {
editor.children = editor.api.html.deserialize({ element: value }) as Value;
} else if (typeof value === 'function') {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './editor/index';
export * from './libs/index';
export * from './plugin/index';
export * from './plugins/index';
export * from './static/index';
export * from './transforms/index';
export * from './types/index';
export * from './utils/index';
Loading

0 comments on commit 5b8072d

Please sign in to comment.