Skip to content

Commit

Permalink
fix(tables): apply table columns sizes when editable=false (#1948)
Browse files Browse the repository at this point in the history
* fix(tables): apply table columns sizes when editable=false. Fixes #1937

* feat(doc): add helper to determine if doc node content is default
  • Loading branch information
whawker committed Nov 25, 2022
1 parent a154c3b commit 8bd49f5
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/flat-kids-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@remirror/extension-doc': minor
'@remirror/core-utils': patch
---

Expose a helper for detecting doc changes from the default
5 changes: 5 additions & 0 deletions .changeset/gold-games-act.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@remirror/extension-tables': patch
---

Apply table columns sizes when view not is editable. Fixes #1937
2 changes: 1 addition & 1 deletion packages/remirror__core-utils/src/core-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ export function isDocNodeEmpty(node: ProsemirrorNode): boolean {
);
}

interface DefaultDocNodeOptions {
export interface DefaultDocNodeOptions {
/**
* When true will not check any of the attributes for any of the nodes.
*/
Expand Down
1 change: 1 addition & 0 deletions packages/remirror__core-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export {
export type {
CreateDocumentNodeProps,
CustomDocumentProps,
DefaultDocNodeOptions,
FragmentStringHandlerOptions,
GetMarkRange,
InvalidContentBlock,
Expand Down
70 changes: 68 additions & 2 deletions packages/remirror__extension-doc/__tests__/doc-extension.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { pmBuild } from 'jest-prosemirror';
import { extensionValidityTest } from 'jest-remirror';
import { createCoreManager } from 'remirror/extensions';
import { extensionValidityTest, renderEditor } from 'jest-remirror';
import { createCoreManager, HeadingExtension } from 'remirror/extensions';

import { DocExtension } from '../';

Expand Down Expand Up @@ -45,3 +45,69 @@ test('supports docAttributes with default values', () => {
],
});
});

describe('helpers', () => {
describe('`isDefaultDocNode`', () => {
it('returns true if the current doc contains the default content', () => {
const { add, nodes, helpers } = renderEditor([new DocExtension()]);
const { doc, p } = nodes;

add(doc(p('')));
expect(helpers.isDefaultDocNode()).toBeTrue();
});

it('returns false if the current doc contains text', () => {
const { add, nodes, helpers } = renderEditor([new DocExtension()]);
const { doc, p } = nodes;

add(doc(p('Remirror!')));
expect(helpers.isDefaultDocNode()).toBeFalse();
});

it('returns false if the current doc contains a different node', () => {
const { add, nodes, helpers } = renderEditor([new DocExtension(), new HeadingExtension()]);
const { doc, heading } = nodes;

add(doc(heading('')));
expect(helpers.isDefaultDocNode()).toBeFalse();
});

it('returns true if the current doc matches the custom content expression', () => {
const { add, nodes, helpers } = renderEditor([
new DocExtension({
content: 'heading block+',
}),
new HeadingExtension(),
]);
const { doc, heading, p } = nodes;

add(doc(heading(''), p('')));
expect(helpers.isDefaultDocNode()).toBeTrue();
});

it('returns false if the current doc with custom content expression contains text', () => {
const { add, nodes, helpers } = renderEditor([new DocExtension(), new HeadingExtension()]);
const { doc, heading, p } = nodes;

add(doc(heading('Remirror!'), p('')));
expect(helpers.isDefaultDocNode()).toBeFalse();
});

it("returns false if the current doc's nodes don't match the custom content expression", () => {
const { add, nodes, attributeNodes, helpers } = renderEditor([
new DocExtension({
content: 'heading block+',
}),
new HeadingExtension(),
]);
const { doc } = nodes;
const { heading } = attributeNodes;

const h1 = heading({ level: 1 });
const h2 = heading({ level: 2 });

add(doc(h1(''), h2('')));
expect(helpers.isDefaultDocNode()).toBeFalse();
});
});
});
20 changes: 20 additions & 0 deletions packages/remirror__extension-doc/src/doc-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import {
ApplySchemaAttributes,
command,
CommandFunction,
DefaultDocNodeOptions,
EditorSchema,
EditorStateProps,
entries,
extension,
ExtensionPriority,
Helper,
helper,
isDefaultDocNode,
isPlainObject,
NodeExtension,
NodeExtensionSpec,
Expand Down Expand Up @@ -144,6 +149,14 @@ export class DocExtension extends NodeExtension<DocOptions> {
return true;
};
}

@helper()
isDefaultDocNode({
state = this.store.getState(),
options,
}: IsDefaultDocNodeHelperOptions = {}): Helper<boolean> {
return isDefaultDocNode(state.doc, options);
}
}

interface SetDocAttrStepJSONValue {
Expand Down Expand Up @@ -226,6 +239,13 @@ export class SetDocAttributeStep extends Step {
}
}

interface IsDefaultDocNodeHelperOptions extends Partial<EditorStateProps> {
/**
* The options passed to the isDefaultDocNode util
*/
options?: DefaultDocNodeOptions;
}

try {
// Register the steps.
Step.jsonID(STEP_TYPE, SetDocAttributeStep);
Expand Down
42 changes: 42 additions & 0 deletions packages/remirror__extension-tables/src/table-extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
CommandFunction,
CommandFunctionProps,
convertCommand,
CreateExtensionPlugin,
EditorState,
EditorView,
extension,
Expand All @@ -12,6 +13,7 @@ import {
findParentNodeOfType,
Helper,
helper,
isElementDomNode,
NodeExtension,
NodeSpecOverride,
nonChainable,
Expand All @@ -38,9 +40,12 @@ import {
setCellAttr,
splitCell,
tableEditing,
// @ts-expect-error TableView is exported
TableView,
toggleHeaderCell,
toggleHeaderColumn,
toggleHeaderRow,
updateColumnsOnResize,
} from '@remirror/pm/tables';

import {
Expand Down Expand Up @@ -144,6 +149,43 @@ export class TableExtension extends NodeExtension<TableOptions> {
return plugins;
}

createPlugin(): CreateExtensionPlugin {
const { resizable, resizeableOptions } = this.options;

if (!resizable) {
return {};
}

if (!this.store.isMounted() || this.store.helpers.isViewEditable()) {
// If the view is editable, we should be using the external columnResizing plugin above
return {};
}

/**
* If the view is not editable, use the updateColumnsOnResize method to ensure col widths are applied
*/

const { cellMinWidth = 25 } = resizeableOptions;

return {
props: {
nodeViews: {
table(node, view, getPos) {
const dom = view.nodeDOM(getPos());

if (!isElementDomNode(dom)) {
return;
}

updateColumnsOnResize(node, dom.firstChild as Element, dom, cellMinWidth);

return new TableView(node, cellMinWidth, view);
},
},
},
};
}

/**
* Create a table in the editor at the current selection point.
*/
Expand Down
39 changes: 39 additions & 0 deletions packages/storybook-react/stories/extension-tables/not-editable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { TableExtension } from 'remirror/extensions';
import { EditorComponent, Remirror, ThemeProvider, useRemirror } from '@remirror/react';

const content = `
<table>
<tr>
<td data-colwidth="113"><p>This</p></td>
<td data-colwidth="162"><p>editor</p></td>
<td><p>is non editable</p></td>
</tr>
<tr>
<td data-colwidth="113"><p>But</p></td>
<td data-colwidth="162"><p>table</p></td>
<td><p>columns widths are still applied</p></td>
</tr>
<tr>
<td data-colwidth="113"><p></p></td>
<td data-colwidth="162"><p></p></td>
<td><p></p></td>
</tr>
</table>
`;

const NotEditable = (): JSX.Element => {
const { manager, state } = useRemirror({ extensions, stringHandler: 'html', content });

return (
<ThemeProvider>
<Remirror manager={manager} initialContent={state} editable={false}>
<EditorComponent />
</Remirror>
</ThemeProvider>
);
};

const extensions = () => [new TableExtension()];

export default NotEditable;
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Basic from './basic';
import NotEditable from './not-editable';

export { Basic };
export { Basic, NotEditable };
export default { title: 'Extensions / Tables (simple)' };
30 changes: 30 additions & 0 deletions website/extension-examples/extension-tables/not-editable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* THIS FILE IS AUTO GENERATED!
*
* Run `pnpm -w generate:website-examples` to regenerate this file.
*/

// @ts-nocheck

import React from 'react';
import CodeBlock from '@theme/CodeBlock';
import BrowserOnly from '@docusaurus/BrowserOnly';
import ComponentSource from '!!raw-loader!../../../packages/storybook-react/stories/extension-tables/not-editable.tsx';

import { StoryExample } from '../../src/components/story-example-component';

const ExampleComponent = (): JSX.Element => {
const story = (
<BrowserOnly>
{() => {
const ComponentStory = require('../../../packages/storybook-react/stories/extension-tables/not-editable').default
return <ComponentStory/>
}}
</BrowserOnly>
);
const source = <CodeBlock className='language-tsx'>{ComponentSource}</CodeBlock>;

return <StoryExample story={story} source={source} />;
};

export default ExampleComponent;

1 comment on commit 8bd49f5

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Published on https://remirror.io as production
🚀 Deployed on https://6380e0431f56593010878a26--remirror.netlify.app

Please sign in to comment.