Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Column plugin #3118

Merged
merged 28 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"@udecode/plate-indent-list": "workspace:^",
"@udecode/plate-juice": "workspace:^",
"@udecode/plate-kbd": "workspace:^",
"@udecode/plate-layout": "workspace:^",
"@udecode/plate-line-height": "workspace:^",
"@udecode/plate-link": "workspace:^",
"@udecode/plate-list": "workspace:^",
Expand Down
3 changes: 1 addition & 2 deletions apps/www/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const HomeTabs = dynamic(() => import('./_components/home-tabs'));
const CustomizerDrawer = dynamic(
() => import('@/components/customizer-drawer')
);

export default function IndexPage() {
return (
<div className="container relative">
Expand All @@ -43,7 +42,7 @@ export default function IndexPage() {
</PageHeaderDescription>
<section className="flex w-full items-center space-x-4 py-4 md:pb-10">
<Link href="/docs" className={cn(buttonVariants())}>
Get Started
Get Started1
</Link>
<Link
target="_blank"
Expand Down
122 changes: 122 additions & 0 deletions apps/www/src/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,129 @@ const yarn = (props: LucideProps) => (
</svg>
);

export const DoubleColumnOutlined = (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8.5 3H13V13H8.5V3ZM7.5 2H8.5H13C13.5523 2 14 2.44772 14 3V13C14 13.5523 13.5523 14 13 14H8.5H7.5H3C2.44772 14 2 13.5523 2 13V3C2 2.44772 2.44772 2 3 2H7.5ZM7.5 13H3L3 3H7.5V13Z"
fill="#595E6F"
/>
</svg>
);

export const ThreeColumnOutlined = (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9.25 3H6.75V13H9.25V3ZM9.25 2H6.75H5.75H3C2.44772 2 2 2.44772 2 3V13C2 13.5523 2.44772 14 3 14H5.75H6.75H9.25H10.25H13C13.5523 14 14 13.5523 14 13V3C14 2.44772 13.5523 2 13 2H10.25H9.25ZM10.25 3V13H13V3H10.25ZM3 13H5.75V3H3L3 13Z"
fill="#4C5161"
/>
</svg>
);

export const RightSideDoubleColumnOutlined = (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M11.25 3H13V13H11.25V3ZM10.25 2H11.25H13C13.5523 2 14 2.44772 14 3V13C14 13.5523 13.5523 14 13 14H11.25H10.25H3C2.44772 14 2 13.5523 2 13V3C2 2.44772 2.44772 2 3 2H10.25ZM10.25 13H3L3 3H10.25V13Z"
fill="#595E6F"
/>
</svg>
);

export const LeftSideDoubleColumnOutlined = (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.75 3H13V13H5.75V3ZM4.75 2H5.75H13C13.5523 2 14 2.44772 14 3V13C14 13.5523 13.5523 14 13 14H5.75H4.75H3C2.44772 14 2 13.5523 2 13V3C2 2.44772 2.44772 2 3 2H4.75ZM4.75 13H3L3 3H4.75V13Z"
fill="#595E6F"
/>
</svg>
);

export const DoubleSideDoubleColumnOutlined = (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.25 3H5.75V13H10.25V3ZM10.25 2H5.75H4.75H3C2.44772 2 2 2.44772 2 3V13C2 13.5523 2.44772 14 3 14H4.75H5.75H10.25H11.25H13C13.5523 14 14 13.5523 14 13V3C14 2.44772 13.5523 2 13 2H11.25H10.25ZM11.25 3V13H13V3H11.25ZM3 13H4.75V3H3L3 13Z"
fill="#595E6F"
/>
</svg>
);

const LayoutIcon = (props: LucideProps) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
fill="currentColor"
stroke="currentColor"
strokeWidth={0.1}
{...props}
>
<path
d="M3 2C2.44772 2 2 2.44772 2 3V7C2 7.55228 2.44772 8 3 8H13C13.5523 8 14 7.55228 14 7V3C14 2.44772 13.5523 2 13 2H3ZM13 3V7H3L3 3H13Z"
fill="#595E6F"
/>
<path
d="M2 10C2 9.72386 2.22386 9.5 2.5 9.5H13.5C13.7761 9.5 14 9.72386 14 10C14 10.2761 13.7761 10.5 13.5 10.5H2.5C2.22386 10.5 2 10.2761 2 10Z"
fill="#595E6F"
/>
<path
d="M2.5 12C2.22386 12 2 12.2239 2 12.5C2 12.7761 2.22386 13 2.5 13H8.5C8.77614 13 9 12.7761 9 12.5C9 12.2239 8.77614 12 8.5 12H2.5Z"
fill="#595E6F"
/>
</svg>
);

export const Icons = {
doubleColumn: DoubleColumnOutlined,
threeColumn: ThreeColumnOutlined,
rightSideDoubleColumn: RightSideDoubleColumnOutlined,
leftSideDoubleColumn: LeftSideDoubleColumnOutlined,
doubleSideDoubleColumn: DoubleSideDoubleColumnOutlined,
LayoutIcon,
todo: Square,
add: Plus,
alignCenter: AlignCenter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
KEY_LIST_STYLE_TYPE,
toggleIndentList,
} from '@udecode/plate-indent-list';
import { ELEMENT_COLUMN_GROUP, insertColumnGroup } from '@udecode/plate-layout';
import { ELEMENT_LINK, triggerFloatingLink } from '@udecode/plate-link';
import { toggleList } from '@udecode/plate-list';
import {
Expand Down Expand Up @@ -125,6 +126,12 @@ const items = [
description: 'Divider (---)',
icon: Icons.hr,
},
{
value: ELEMENT_COLUMN_GROUP,
label: 'Columns',
description: 'Columns',
icon: Icons.LayoutIcon,
},
],
},
{
Expand Down Expand Up @@ -197,6 +204,11 @@ export function PlaygroundInsertDropdownMenu(props: DropdownMenuProps) {
className="min-w-[180px]"
onSelect={async () => {
switch (type) {
case ELEMENT_COLUMN_GROUP: {
insertColumnGroup(editor);
break;
}

case ELEMENT_CODE_BLOCK: {
insertEmptyCodeBlock(editor);

Expand Down
5 changes: 5 additions & 0 deletions apps/www/src/lib/plate/create-plate-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
import { MARK_HIGHLIGHT } from '@udecode/plate-highlight';
import { ELEMENT_HR } from '@udecode/plate-horizontal-rule';
import { MARK_KBD } from '@udecode/plate-kbd';
import { ELEMENT_COLUMN, ELEMENT_COLUMN_GROUP } from '@udecode/plate-layout';
import { ELEMENT_LINK } from '@udecode/plate-link';
import {
ELEMENT_LI,
Expand All @@ -56,6 +57,8 @@ import { CodeBlockElement } from '@/registry/default/plate-ui/code-block-element
import { CodeLeaf } from '@/registry/default/plate-ui/code-leaf';
import { CodeLineElement } from '@/registry/default/plate-ui/code-line-element';
import { CodeSyntaxLeaf } from '@/registry/default/plate-ui/code-syntax-leaf';
import { ColumnElement } from '@/registry/default/plate-ui/column-element';
import { ColumnGroupElement } from '@/registry/default/plate-ui/column-group-element';
import { CommentLeaf } from '@/registry/default/plate-ui/comment-leaf';
import { ExcalidrawElement } from '@/registry/default/plate-ui/excalidraw-element';
import { HeadingElement } from '@/registry/default/plate-ui/heading-element';
Expand Down Expand Up @@ -116,6 +119,8 @@ export const createPlateUI = (
[ELEMENT_TOGGLE]: ToggleElement,
[ELEMENT_TR]: TableRowElement,
[ELEMENT_EXCALIDRAW]: ExcalidrawElement,
[ELEMENT_COLUMN_GROUP]: ColumnGroupElement,
[ELEMENT_COLUMN]: ColumnElement,
[MARK_BOLD]: withProps(PlateLeaf, { as: 'strong' }),
[MARK_CODE]: CodeLeaf,
[MARK_HIGHLIGHT]: HighlightLeaf,
Expand Down
2 changes: 2 additions & 0 deletions apps/www/src/registry/default/example/playground-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import { createIndentPlugin } from '@udecode/plate-indent';
import { createIndentListPlugin } from '@udecode/plate-indent-list';
import { createJuicePlugin } from '@udecode/plate-juice';
import { createKbdPlugin } from '@udecode/plate-kbd';
import { createLayoutPlugin } from '@udecode/plate-layout';
import { createLineHeightPlugin } from '@udecode/plate-line-height';
import { createLinkPlugin } from '@udecode/plate-link';
import { createListPlugin, createTodoListPlugin } from '@udecode/plate-list';
Expand Down Expand Up @@ -324,6 +325,7 @@ export const usePlaygroundPlugins = ({
createDeserializeDocxPlugin({ enabled: !!enabled.deserializeDocx }),
createDeserializeMdPlugin({ enabled: !!enabled.deserializeMd }),
createJuicePlugin({ enabled: !!enabled.juice }),
createLayoutPlugin(),
],
{
components,
Expand Down
28 changes: 28 additions & 0 deletions apps/www/src/registry/default/plate-ui/column-element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import { cn, withRef } from '@udecode/cn';
import { PlateElement, useElement, withHOC } from '@udecode/plate-common';
import { TColumnElement } from '@udecode/plate-layout';
import { ResizableProvider } from '@udecode/plate-resizable';
import { useReadOnly } from 'slate-react';

export const ColumnElement = withHOC(
ResizableProvider,
withRef<typeof PlateElement>(({ className, children, ...props }, ref) => {
const readOnly = useReadOnly();
const { width } = useElement<TColumnElement>();

return (
<PlateElement
ref={ref}
style={{ width }}
className={cn(
className,
!readOnly && 'rounded-lg border border-dashed border-slate-300 p-1.5'
)}
{...props}
>
{children}
</PlateElement>
);
})
);
17 changes: 17 additions & 0 deletions apps/www/src/registry/default/plate-ui/column-group-element.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { cn, withRef } from '@udecode/cn';
import { PlateElement } from '@udecode/plate-common';

import { LayoutToolbarPopover } from './column-toolbar-popover';

export const ColumnGroupElement = withRef<typeof PlateElement>(
({ className, children, ...props }, ref) => {
return (
<PlateElement ref={ref} className={cn(className, 'my-2')} {...props}>
<LayoutToolbarPopover>
<div className={cn('flex size-full gap-4 rounded')}>{children}</div>
</LayoutToolbarPopover>
</PlateElement>
);
}
);
94 changes: 94 additions & 0 deletions apps/www/src/registry/default/plate-ui/column-toolbar-popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react';
import { useRemoveNodeButton } from '@udecode/plate-common';
import { useColumnState, useDebouncePopoverOpen } from '@udecode/plate-layout';
import { useReadOnly } from 'slate-react';

import { Icons, iconVariants } from '@/components/icons';

import { Button } from './button';
import { Popover, PopoverAnchor, PopoverContent } from './popover';
import { Separator } from './separator';

export interface LayoutToolbarPopoverProps {}

export function LayoutToolbarPopover({
children,
}: React.PropsWithChildren<LayoutToolbarPopoverProps>) {
const readOnly = useReadOnly();

const {
element,
setDoubleColumn,
setDoubleSideDoubleColumn,
setLeftSideDoubleColumn,
setRightSideDoubleColumn,
setThreeColumn,
} = useColumnState();

const { props: buttonProps } = useRemoveNodeButton({ element });

const isOpen = useDebouncePopoverOpen();

if (readOnly) return <>{children}</>;

return (
<Popover open={isOpen} modal={false}>
<PopoverAnchor>{children}</PopoverAnchor>
<PopoverContent
align="center"
side="top"
sideOffset={10}
className="w-auto p-1"
onOpenAutoFocus={(e) => e.preventDefault()}
>
<div className="box-content flex h-9 items-center gap-1">
<Button
variant="ghost"
size="sms"
// tooltip="doubleColumn"
onClick={setDoubleColumn}
>
<Icons.doubleColumn />
</Button>
<Button
variant="ghost"
size="sms"
// tooltip="threeColumn"
onClick={setThreeColumn}
>
<Icons.threeColumn />
</Button>
<Button
variant="ghost"
size="sms"
// tooltip="rightSideDoubleColumn"
onClick={setRightSideDoubleColumn}
>
<Icons.rightSideDoubleColumn />
</Button>
<Button
variant="ghost"
size="sms"
// tooltip="plugins.layout.leftSideDoubleColumn"
onClick={setLeftSideDoubleColumn}
>
<Icons.leftSideDoubleColumn />
</Button>
<Button
variant="ghost"
size="sms"
// tooltip="plugins.layout.doubleSideDoubleColumn"
onClick={setDoubleSideDoubleColumn}
>
<Icons.doubleSideDoubleColumn />
</Button>

<Separator orientation="vertical" className="my-1" />
<Button variant="ghost" size="sms" {...buttonProps}>
<Icons.delete className={iconVariants({ variant: 'toolbar' })} />
</Button>
</div>
</PopoverContent>
</Popover>
);
}
3 changes: 3 additions & 0 deletions packages/layout/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__tests__
__test-utils__
__mocks__
1 change: 1 addition & 0 deletions packages/layout/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Plate Column plugin
Loading