Skip to content

Commit

Permalink
feat:indent-toodo
Browse files Browse the repository at this point in the history
  • Loading branch information
fengjue committed Mar 24, 2024
1 parent 3dd1934 commit 3374f5a
Show file tree
Hide file tree
Showing 20 changed files with 296 additions and 29 deletions.
2 changes: 2 additions & 0 deletions apps/www/src/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {
Settings,
Settings2,
Smile,
Square,
Strikethrough,
Subscript,
SunMedium,
Expand Down Expand Up @@ -255,6 +256,7 @@ const yarn = (props: LucideProps) => (
);

export const Icons = {
todo: Square,
add: Plus,
alignCenter: AlignCenter,
alignJustify: AlignJustify,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ColorDropdownMenu } from '@/registry/default/plate-ui/color-dropdown-me
import { CommentToolbarButton } from '@/registry/default/plate-ui/comment-toolbar-button';
import { EmojiDropdownMenu } from '@/registry/default/plate-ui/emoji-dropdown-menu';
import { IndentListToolbarButton } from '@/registry/default/plate-ui/indent-list-toolbar-button';
import { IndentTodoToolbarButton } from '@/registry/default/plate-ui/indent-todo-toolbar-button';
import { IndentToolbarButton } from '@/registry/default/plate-ui/indent-toolbar-button';
import { LineHeightDropdownMenu } from '@/registry/default/plate-ui/line-height-dropdown-menu';
import { LinkToolbarButton } from '@/registry/default/plate-ui/link-toolbar-button';
Expand Down Expand Up @@ -115,6 +116,7 @@ export function PlaygroundFixedToolbarButtons({ id }: { id?: ValueId }) {
<>
<IndentListToolbarButton nodeType={ListStyleType.Disc} />
<IndentListToolbarButton nodeType={ListStyleType.Decimal} />
<IndentTodoToolbarButton />
</>
)}

Expand Down
4 changes: 4 additions & 0 deletions apps/www/src/lib/plate/demo/values/indentListValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ jsx;
export const indentListValue: any = (
<fragment>
<hh2>Indent List</hh2>
<hp indent={1} listStyleType="todo" checked={true}>
Decimal 112
</hp>
<hp>
Create indented lists with multiple levels of indentation and customize
the list style type for each level.
Expand All @@ -23,6 +26,7 @@ export const indentListValue: any = (
<hp indent={3} listStyleType="decimal" listStart={2}>
Decimal 112
</hp>

{/* <hp indent={3} listStyleType="lower-latin"> */}
{/* 7K-T */}
{/* </hp> */}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
useIndentTodoToolBarButton,
useIndentTodoToolBarButtonState,
} from '@udecode/plate-indent-list';
import { withRef } from '@udecode/react-utils';

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

import { ToolbarButton } from './toolbar';

export const IndentTodoToolbarButton = withRef<typeof ToolbarButton>(
(rest, ref) => {
const state = useIndentTodoToolBarButtonState({ nodeType: 'todo' });
const { props } = useIndentTodoToolBarButton(state);

return (
<ToolbarButton ref={ref} tooltip="Todo" {...props} {...rest}>
<Icons.todo />
</ToolbarButton>
);
}
);
4 changes: 3 additions & 1 deletion packages/indent-list/src/createIndentListPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import { withIndentList } from './withIndentList';
export const KEY_LIST_STYLE_TYPE = 'listStyleType';
export const KEY_LIST_START = 'listStart';
export const KEY_LIST_RESTART = 'listRestart';
export const KEY_LIST_CHECKED = 'checked';
export const KEY_TODO_STYLE_TYPE = 'todo';

export interface IndentListPlugin {
getSiblingIndentListOptions?: GetSiblingIndentListOptions<TElement>;

/**
/**x
* Map html element to list style type.
*/
getListStyleType?: (element: HTMLElement) => ListStyleType;
Expand Down
1 change: 1 addition & 0 deletions packages/indent-list/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

export * from './someIndentList';
export * from './useIndentListToolbarButton';
export * from './useIndentTodoToolbarButton';
5 changes: 3 additions & 2 deletions packages/indent-list/src/hooks/someIndentList.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PlateEditor, someNode, Value } from '@udecode/plate-common';

import { KEY_LIST_STYLE_TYPE, ListStyleType } from '../index';
import { KEY_LIST_CHECKED, KEY_LIST_STYLE_TYPE, ListStyleType } from '../index';

export const someIndentList = <V extends Value>(
editor: PlateEditor<V>,
Expand All @@ -12,7 +12,8 @@ export const someIndentList = <V extends Value>(
match: (n) => {
const list = n[KEY_LIST_STYLE_TYPE];
if (type === ListStyleType.Disc) return list === ListStyleType.Disc;
return !!list && list !== ListStyleType.Disc;
const isHasProperty = n.hasOwnProperty(KEY_LIST_CHECKED);
return !!list && list !== ListStyleType.Disc && !isHasProperty;
},
})
);
Expand Down
21 changes: 21 additions & 0 deletions packages/indent-list/src/hooks/someIndentTodo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PlateEditor, someNode, Value } from '@udecode/plate-common';

import {
KEY_LIST_CHECKED,
KEY_LIST_STYLE_TYPE,
KEY_TODO_STYLE_TYPE,
} from '../index';

export const someIndentTodo = <V extends Value>(
editor: PlateEditor<V>,
type: string
) => {
return someNode(editor, {
at: editor.selection!,
match: (n) => {
const list = n[KEY_LIST_STYLE_TYPE];
const isHasProperty = n.hasOwnProperty(KEY_LIST_CHECKED);
return n.type === 'p' && isHasProperty && list === KEY_TODO_STYLE_TYPE;
},
});
};
37 changes: 37 additions & 0 deletions packages/indent-list/src/hooks/useIndentTodoToolbarButton.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useEditorRef, useEditorSelector } from '@udecode/plate-common';

import { ListStyleType, toggleIndentList } from '../index';
import { someIndentTodo } from './someIndentTodo';

export const useIndentTodoToolBarButtonState = ({
nodeType = ListStyleType.Disc,
}: { nodeType?: string } = {}) => {
const pressed = useEditorSelector(
(editor) => someIndentTodo(editor, nodeType),
[nodeType]
);
return {
pressed,
nodeType,
};
};

export const useIndentTodoToolBarButton = ({
nodeType,
pressed,
}: ReturnType<typeof useIndentTodoToolBarButtonState>) => {
const editor = useEditorRef();
return {
props: {
pressed,
onMouseDown: (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
},
onClick: () => {
toggleIndentList(editor, {
listStyleType: nodeType,
});
},
},
};
};
47 changes: 45 additions & 2 deletions packages/indent-list/src/injectIndentListComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React from 'react';
import {
findNodePath,
InjectComponentProps,
InjectComponentReturnType,
setNodes,
} from '@udecode/plate-common';
import { clsx } from 'clsx';

import { KEY_LIST_START, KEY_LIST_STYLE_TYPE } from './createIndentListPlugin';
import {
KEY_LIST_CHECKED,
KEY_LIST_START,
KEY_LIST_STYLE_TYPE,
KEY_TODO_STYLE_TYPE,
} from './createIndentListPlugin';
import { ListStyleType } from './types';

export const injectIndentListComponent = (
Expand All @@ -16,7 +23,11 @@ export const injectIndentListComponent = (
const listStyleType = element[KEY_LIST_STYLE_TYPE] as string;
const listStart = element[KEY_LIST_START] as number;

if (listStyleType) {
const isTodo =
element.hasOwnProperty(KEY_LIST_CHECKED) &&
listStyleType === KEY_TODO_STYLE_TYPE;

if (listStyleType && !isTodo) {
let className = clsx(`slate-${KEY_LIST_STYLE_TYPE}-${listStyleType}`);
const style: React.CSSProperties = {
padding: 0,
Expand Down Expand Up @@ -50,4 +61,36 @@ export const injectIndentListComponent = (
);
};
}

if (isTodo) {
console.log(1, 'fj');
const className = clsx('slate-list-todo');
const checked = element[KEY_LIST_CHECKED] as boolean;
const style: React.CSSProperties = {
padding: 0,
margin: 0,
};
return function Ol({ children, editor }) {
return (
<div className={className} style={style}>
<input
contentEditable={false}
data-slate-void
type="checkbox"
style={{
marginRight: 5,
marginLeft: -17,
paddingTop: -10,
}}
checked={checked}
onChange={(v) => {
const path = findNodePath(editor, element);
setNodes(editor, { checked: v.target.checked }, { at: path });
}}
/>
<span>{children}</span>
</div>
);
};
}
};
14 changes: 13 additions & 1 deletion packages/indent-list/src/queries/areEqListStyleType.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { TEditor, TNodeEntry, Value } from '@udecode/plate-common';

import { KEY_LIST_STYLE_TYPE } from '../createIndentListPlugin';
import {
KEY_LIST_CHECKED,
KEY_LIST_STYLE_TYPE,
KEY_TODO_STYLE_TYPE,
} from '../createIndentListPlugin';
import { ListStyleType } from '../types';

export const areEqListStyleType = <V extends Value>(
Expand All @@ -17,6 +21,14 @@ export const areEqListStyleType = <V extends Value>(
for (const entry of entries) {
const [block] = entry;

if (listStyleType === KEY_TODO_STYLE_TYPE) {
if (!block.hasOwnProperty(KEY_LIST_CHECKED)) {
eqListStyleType = false;
break;
}
continue;
}

if (
!block[KEY_LIST_STYLE_TYPE] ||
block[KEY_LIST_STYLE_TYPE] !== listStyleType
Expand Down
13 changes: 11 additions & 2 deletions packages/indent-list/src/queries/getIndentListSiblings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
Value,
} from '@udecode/plate-common';

import { KEY_LIST_STYLE_TYPE } from '../createIndentListPlugin';
import {
KEY_LIST_CHECKED,
KEY_LIST_STYLE_TYPE,
} from '../createIndentListPlugin';
import { getNextIndentList } from './getNextIndentList';
import { getPreviousIndentList } from './getPreviousIndentList';
import { GetSiblingIndentListOptions } from './getSiblingIndentList';
Expand Down Expand Up @@ -37,7 +40,13 @@ export const getIndentListSiblings = <

const [node] = entry;

if (!(node as any)[KEY_LIST_STYLE_TYPE]) return siblings;
// if (!(node as any)[KEY_LIST_STYLE_TYPE]) return siblings;
if (
!(node as any)[KEY_LIST_STYLE_TYPE] &&
// @ts-ignore
!node.hasOwnProperty(KEY_LIST_CHECKED)
)
return siblings;

let iterEntry = entry;

Expand Down
19 changes: 18 additions & 1 deletion packages/indent-list/src/transforms/indentList.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { PlateEditor, Value } from '@udecode/plate-common';
import { setIndent, SetIndentOptions } from '@udecode/plate-indent';

import { KEY_LIST_STYLE_TYPE } from '../createIndentListPlugin';
import {
KEY_LIST_CHECKED,
KEY_LIST_STYLE_TYPE,
} from '../createIndentListPlugin';
import { ListStyleType } from '../types';

export interface IndentListOptions<V extends Value = Value>
Expand All @@ -24,3 +27,17 @@ export const indentList = <V extends Value>(
...options,
});
};

export const indentTodo = <V extends Value>(
editor: PlateEditor<V>,
{ listStyleType = ListStyleType.Disc, ...options }: IndentListOptions<V> = {}
) => {
setIndent(editor, {
offset: 1,
setNodesProps: () => ({
[KEY_LIST_CHECKED]: false,
[KEY_LIST_STYLE_TYPE]: listStyleType,
}),
...options,
});
};
7 changes: 5 additions & 2 deletions packages/indent-list/src/transforms/outdentList.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { PlateEditor, Value } from '@udecode/plate-common';
import { setIndent } from '@udecode/plate-indent';

import { KEY_LIST_STYLE_TYPE } from '../createIndentListPlugin';
import {
KEY_LIST_CHECKED,
KEY_LIST_STYLE_TYPE,
} from '../createIndentListPlugin';
import { IndentListOptions } from './indentList';

/**
Expand All @@ -13,7 +16,7 @@ export const outdentList = <V extends Value>(
) => {
setIndent(editor, {
offset: -1,
unsetNodesProps: [KEY_LIST_STYLE_TYPE],
unsetNodesProps: [KEY_LIST_STYLE_TYPE, KEY_LIST_CHECKED],
...options,
});
};
31 changes: 30 additions & 1 deletion packages/indent-list/src/transforms/setIndentListNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { setElements, TEditor, Value } from '@udecode/plate-common';
import { KEY_INDENT } from '@udecode/plate-indent';
import { Path } from 'slate';

import { KEY_LIST_STYLE_TYPE } from '../createIndentListPlugin';
import {
KEY_LIST_CHECKED,
KEY_LIST_STYLE_TYPE,
KEY_TODO_STYLE_TYPE,
} from '../createIndentListPlugin';
import { ListStyleType } from '../types';

export const setIndentListNode = <V extends Value>(
Expand All @@ -25,3 +29,28 @@ export const setIndentListNode = <V extends Value>(
{ at }
);
};

export const setIndentTodoNode = <V extends Value>(
editor: TEditor<V>,
{
listStyleType = KEY_TODO_STYLE_TYPE,
indent = 0,
at,
}: {
listStyleType?: string;
indent?: number;
at: Path;
}
) => {
const newIndent = indent || indent + 1;

setElements(
editor,
{
[KEY_LIST_STYLE_TYPE]: listStyleType,
[KEY_LIST_CHECKED]: false,
[KEY_INDENT]: newIndent,
},
{ at }
);
};
Loading

0 comments on commit 3374f5a

Please sign in to comment.