Skip to content

Commit

Permalink
Toggle > Remove indent-list dependency, finalize documentation, add t…
Browse files Browse the repository at this point in the history
…est to autoformat toggle, fix typing of plugin
  • Loading branch information
Liboul committed Jan 31, 2024
1 parent 3b10a98 commit 31b025d
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 51 deletions.
108 changes: 90 additions & 18 deletions apps/www/content/docs/toggle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,23 @@ docs:
## Plugin dependencies

- [Indent](/docs/indent)
- [Indent List](/docs/indent-list)
- [Node id](/docs/node-id)

</PackageInfo>

## Installation

```bash
npm install @udecode/plate-indent @udecode/plate-indent-list @udecode/plate-node-id @udecode/plate-toggle
npm install @udecode/plate-indent @udecode/plate-node-id @udecode/plate-toggle
```

## Usage

```tsx
// ...
import { createIndentPlugin } from '@udecode/plate-indent';
import { createIndentListPlugin } from '@udecode/plate-indent-list';
import { createNodeIdPlugin } from '@udecode/plate-node-id';
import { createTogglePlugin } from '@udecode/plate-toggle';
import { createTogglePlugin, ELEMENT_TOGGLE } from '@udecode/plate-toggle';

const plugins = [
// ...otherPlugins,
Expand All @@ -46,14 +44,7 @@ const plugins = [
createIndentPlugin({
inject: {
props: {
validTypes: [ELEMENT_PARAGRAPH, ELEMENT_H1],
},
},
}),
createIndentListPlugin({
inject: {
props: {
validTypes: [ELEMENT_PARAGRAPH, ELEMENT_H1],
validTypes: [ELEMENT_TOGGLE, ELEMENT_PARAGRAPH, ELEMENT_H1],
},
},
}),
Expand All @@ -66,22 +57,45 @@ const plugins = [

### createTogglePlugin

<APIOptions>
{/* TODO */}
</APIOptions>

### openNextToggles

Marks the block at the current selection as an open toggle.
Use this function right before inserting a block so that the toggle is expanded upon insertion.

<APIParameters>
<APIItem name="editor" type="TEditor">
The editor instance.
</APIItem>
</APIParameters>

{/* TODO Add API DOC */}
### toggleIds

Toggles the open state of toggles.

<APIParameters>
<APIItem name="editor" type="TEditor">
The editor instance.
</APIItem>
<APIItem name="toggleIds" type="string[]">
An array of element ids.
</APIItem>
<APIItem name="force" type="boolean" optional>
Set to true if you want to expand all toggles regardless of their current
state. Set to false if you want to collapse all toggles regardless of their
current state.
</APIItem>
</APIParameters>

## API Components

### useToggleToolbarButtonState

<APIReturns>
<APIItem name="pressed" type="boolean">
A boolean indicating whether the button is pressed or not.
</APIItem>
</APIReturns>

### useToggleToolbarButton

A behavior hook for the toggle toolbar button.
Expand All @@ -103,8 +117,66 @@ A behavior hook for the toggle toolbar button.
the toggle of the specified node type in the editor and focuses the
editor.
</APISubListItem>
<APISubListItem parent="props" name="onMouseDown" type="function">
A callback function to handle the mouse down event of the button. It
just prevents default so that focus is not lost when clicking on the
button.
</APISubListItem>
</APISubList>
</APIItem>
</APIReturns>

{/* TODO Add components DOC */}
### useToggleButtonState

<APIParameters>
<APIItem name="toggleId" type="string">
The id of the toggle element.
</APIItem>
</APIParameters>

<APIReturns>
<APIItem name="toggleId" type="string">
The id of the toggle element.
</APIItem>
<APIItem name="open" type="boolean">
A boolean indicating whether the toggle is open (expanded) or not
(collapsed).
</APIItem>
</APIReturns>

### useToggleButton

A behavior hook for the toggle button that expands or collapses a toggle element.

<APIParameters>
<APIItem name="toggleId" type="string">
The id of the toggle element.
</APIItem>
<APIItem name="open" type="boolean">
A boolean indicating whether the toggle is open (expanded) or not
(collapsed).
</APIItem>
</APIParameters>

<APIReturns>
<APIItem name="toggleId" type="string">
The id of the toggle element.
</APIItem>
<APIItem name="open" type="boolean">
A boolean indicating whether the toggle is open (expanded) or not
(collapsed).
</APIItem>
<APIItem name="buttonProps" type="object">
<APISubList>
<APISubListItem parent="buttonProps" name="onClick" type="function">
A callback function to handle the click event of the button. It toggles
the open state of the toggle.
</APISubListItem>
<APISubListItem parent="buttonProps" name="onMouseDown" type="function">
A callback function to handle the mouse down event of the button. It
just prevents default so that focus is not lost when clicking on the
button.
</APISubListItem>
</APISubList>
</APIItem>
</APIReturns>
23 changes: 5 additions & 18 deletions apps/www/src/registry/default/plate-ui/toggle-element.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,17 @@ import { Icons } from '@/components/icons';
export const ToggleElement = withRef<typeof PlateElement>(
({ children, ...props }, ref) => {
const element = useElement();
const state = useToggleButtonState(element.id);
const state = useToggleButtonState(element.id as string);
const { open, buttonProps } = useToggleButton(state);

// TODO use tailwind instead of inline styles
return (
<PlateElement ref={ref} asChild {...props}>
<div style={{ position: 'relative', paddingLeft: '24px' }}>
<div className="relative pl-6">
<span
contentEditable={false}
style={{
position: 'absolute',
left: '-4px',
top: '-4px',
cursor: 'pointer',
padding: '4px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '2px',
transition: 'background-color 0.3s ease',
'&:hover': {
backgroundColor: '#D4DBF1',
},
}}
className={
'absolute -left-0.5 -top-0.5 cursor-pointer select-none p-0.25 flex justify-center items-center rounded-sm hover:bg-slate-200 transition-colors'
}
{...buttonProps}
>
{open ? <Icons.chevronDown /> : <Icons.chevronRight />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { jsx } from '@udecode/plate-test-utils';
import { withReact } from 'slate-react';
import { autoformatPlugin } from 'www/src/lib/plate/demo/plugins/autoformatPlugin';

import { AutoformatBlockRule } from '../../../types';
import { withAutoformat } from '../../../withAutoformat';

jsx;
Expand Down Expand Up @@ -133,4 +134,49 @@ describe('when [x].space', () => {
});
});

// TODO Add toggle test
describe('when |>space', () => {
it('should format to a toggle', () => {
const input = (
<editor>
<hp>
{'|>'}
<cursor />
hello
</hp>
</editor>
) as any;

const output = (
<editor>
<htoggle>hello</htoggle>
</editor>
) as any;

// See useHooksToggle.ts, we overload the plugin with a `setOpenIds` function until there's a JOTAI layer in plate-core,
// so here we need to remove the `preformat` property of the autoformat rule that uses this overload.

const autoformatPluginRulesWitoutTogglePreformat =
autoformatPlugin.options!.rules!.map((rule) => {
const { preFormat, ...rest } = rule as AutoformatBlockRule;
if (rule.match === '|> ') return rest;
return rule;
});

const autoformatPluginWitoutTogglePreformat: typeof autoformatPlugin = {
...autoformatPlugin,
options: {
...autoformatPlugin.options,
rules: autoformatPluginRulesWitoutTogglePreformat as any,
},
};

let editor = withAutoformat(
withReact(input),
mockPlugin(autoformatPluginWitoutTogglePreformat)
);

editor.insertText(' ');

expect(input.children).toEqual(output.children);
});
});
1 change: 0 additions & 1 deletion packages/plate/src/__tests__/all-plugins.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// TODO add toggle
import React from 'react';
import { render } from '@testing-library/react';
import { createAlignPlugin } from '@udecode/plate-alignment';
Expand Down
1 change: 0 additions & 1 deletion packages/serializer-html/src/serializeHtml.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// TODO serialize toggle?
import React from 'react';
import {
EDescendant,
Expand Down
4 changes: 2 additions & 2 deletions packages/toggle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# @udecode/plate-indent-list
# @udecode/plate-toggle

## 30.1.2

TODO ANNOUNCEMENT
TODO release
9 changes: 9 additions & 0 deletions packages/toggle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ It's similar to the indent list plugin, in that it relies on the indent of sibli

Check out [Toggle](https://platejs.org/docs/toggle).

## Ideas to improve this plugin

1. Adding an option `initialValue` of open `toggleIds` and a callback `onChange`, for instance to store the state of open toggles in local storage and remember the state upon browser refresh.
2. Adding an option `defaultOpen`. Currently, toggles are closed on initial rendering.
3. Adding an option to specify how to get the indent value of elements, right now we are relying on this being the default `KEY_ELEMENT` from the `indent` plugin
4. An option to specify how to get the id of elements, right now we are using the default id attribute from the `node-id` plugin.
5. Adding a placeholder below the toggle, like Notion does, when the toggle is expanded without any elements below.
6. Make toggle button more accessible

## License

[MIT](../../LICENSE)
1 change: 0 additions & 1 deletion packages/toggle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
"dependencies": {
"@udecode/plate-common": "30.1.2",
"@udecode/plate-indent": "30.1.2",
"@udecode/plate-indent-list": "30.1.2",
"@udecode/plate-node-id": "30.1.2"
},
"peerDependencies": {
Expand Down
1 change: 0 additions & 1 deletion packages/toggle/src/createTogglePlugin.spec.tsx

This file was deleted.

6 changes: 1 addition & 5 deletions packages/toggle/src/createTogglePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import { ToggleControllerProvider } from './store';
import { ELEMENT_TOGGLE, TogglePlugin } from './types';
import { withToggle } from './withToggle';

export const createTogglePlugin = createPluginFactory<
TogglePlugin,
Value,
PlateEditor<Value>
>({
export const createTogglePlugin = createPluginFactory<TogglePlugin>({
key: ELEMENT_TOGGLE,
isElement: true,
inject: { aboveComponent: injectToggle },
Expand Down
4 changes: 3 additions & 1 deletion packages/toggle/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {
Value,
} from '@udecode/plate-common';
import { KEY_INDENT, TIndentElement } from '@udecode/plate-indent';
import { KEY_LIST_STYLE_TYPE } from '@udecode/plate-indent-list';

import { ELEMENT_TOGGLE, TogglePlugin } from './types';

// Duplicate constant instead of importing from "plate-indent-list" to avoid a dependency.
const KEY_LIST_STYLE_TYPE = 'listStyleType';

export const {
toggleControllerStore,
ToggleControllerProvider,
Expand Down
1 change: 0 additions & 1 deletion packages/toggle/src/withToggle.spec.tsx

This file was deleted.

1 change: 0 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6946,7 +6946,6 @@ __metadata:
dependencies:
"@udecode/plate-common": "npm:30.1.2"
"@udecode/plate-indent": "npm:30.1.2"
"@udecode/plate-indent-list": "npm:30.1.2"
"@udecode/plate-node-id": "npm:30.1.2"
peerDependencies:
react: ">=16.8.0"
Expand Down

0 comments on commit 31b025d

Please sign in to comment.