-
-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: @remirror/extension-tables (#254)
This PR provides a minimal implementation for `@remirror/extension-tables`. Based on [prosemirror-tables](https://github.com/ProseMirror/prosemirror-tables) The following will be added at a later date: - `tableHeader` - Merge cell - CSS style - Provide a usable example in `examples/` Closes #49
- Loading branch information
Showing
15 changed files
with
407 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
'@remirror/extension-tables': minor | ||
--- | ||
|
||
This version add a minimal implementation for tables. Based on | ||
[prosemirror-tables](https://github.com/ProseMirror/prosemirror-tables). | ||
|
||
Ses #49 and #254 for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", | ||
"extends": "../../support/api-extractor.json", | ||
"mainEntryPointFilePath": "./lib/index.d.ts", | ||
"apiReport": { | ||
"enabled": true, | ||
"reportFolder": "../../support/api/", | ||
"reportFileName": "remirror__extension-tables.api.md", | ||
"reportTempFolder": "./temp/" | ||
}, | ||
"docModel": { | ||
"enabled": true, | ||
"apiJsonFilePath": "./temp/<unscopedPackageName>.api.json" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
const config = require('../../support/jest/jest.config'); | ||
|
||
module.exports = { | ||
...config, | ||
name: '@remirror/extension-tables', | ||
displayName: 'extension-tables', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"name": "@remirror/extension-tables", | ||
"version": "0.0.0", | ||
"description": "Table extension for the remirror wysiwyg editor", | ||
"homepage": "https://github.com/remirror/remirror/tree/master/@remirror/extension-tables", | ||
"repository": "https://github.com/remirror/remirror/tree/master/@remirror/extension-tables", | ||
"license": "MIT", | ||
"author": "Ocavue <ocavue@gmail.com>", | ||
"files": [ | ||
"internal", | ||
"lib", | ||
"src" | ||
], | ||
"sideEffects": false, | ||
"main": "lib/index.js", | ||
"module": "lib/dist/extension-tables.esm.js", | ||
"types": "lib/index.d.ts", | ||
"dependencies": { | ||
"@babel/runtime": "^7", | ||
"@remirror/core": "^0.9.0", | ||
"@types/prosemirror-commands": "^1.0.1", | ||
"@types/prosemirror-keymap": "^1.0.1", | ||
"@types/prosemirror-state": "^1.2.3", | ||
"@types/prosemirror-transform": "^1.1.0", | ||
"@types/prosemirror-view": "^1.11.2", | ||
"prosemirror-commands": "^1.0.8", | ||
"prosemirror-keymap": "^1.0.2", | ||
"prosemirror-state": "^1.2.4", | ||
"prosemirror-tables": "^1.0.0", | ||
"prosemirror-transform": "^1.1.5", | ||
"prosemirror-view": "^1.12.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"cjs": "lib/dist/extension-tables.cjs.js", | ||
"meta": { | ||
"sizeLimit": "120 KB" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# @remirror/extension-tables | ||
|
||
[![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/@remirror/extension-tables.svg?)](https://bundlephobia.com/result?p=@remirror/extension-tables) | ||
[![npm](https://img.shields.io/npm/dm/@remirror/extension-tables.svg?&logo=npm)](https://www.npmjs.com/package/@remirror/extension-tables) | ||
|
||
## Installation | ||
|
||
```bash | ||
yarn add @remirror/extension-tables | ||
``` | ||
|
||
```ts | ||
import { TableExtension } from '@remirror/extension-tables'; | ||
|
||
new TableExtension(); | ||
``` |
182 changes: 182 additions & 0 deletions
182
@remirror/extension-tables/src/__tests__/table.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
import { fromHTML, toHTML } from '@remirror/core'; | ||
import { BaseKeymapExtension } from '@remirror/core-extensions'; | ||
import { createBaseTestManager } from '@remirror/test-fixtures'; | ||
import { pmBuild } from 'jest-prosemirror'; | ||
import { renderEditor } from 'jest-remirror'; | ||
|
||
import { TableCellExtension, TableExtension, TableRowExtension } from '..'; | ||
|
||
describe('schema', () => { | ||
const { schema } = createBaseTestManager([ | ||
{ extension: new TableExtension() }, | ||
{ extension: new TableRowExtension() }, | ||
{ extension: new TableCellExtension() }, | ||
]); | ||
|
||
const { doc, table, tableRow, tableCell } = pmBuild(schema, { | ||
table: { nodeType: 'table' }, | ||
tableRow: { nodeType: 'tableRow' }, | ||
tableCell: { nodeType: 'tableCell' }, | ||
}); | ||
|
||
const node = table( | ||
tableRow(tableCell('A1'), tableCell('B1')), | ||
tableRow(tableCell('A2'), tableCell('B2')), | ||
tableRow(tableCell('A3'), tableCell('B3')), | ||
); | ||
|
||
const html = `<table><tr><td>A1</td><td>B1</td></tr><tr><td>A2</td><td>B2</td></tr><tr><td>A3</td><td>B3</td></tr></table>`; | ||
|
||
it('dump to html', () => { | ||
expect(toHTML({ node, schema })).toBe(html); | ||
}); | ||
|
||
it('parse from html', () => { | ||
expect(fromHTML({ content: html, schema })).toEqualProsemirrorNode(doc(node)); | ||
}); | ||
}); | ||
|
||
const create = () => | ||
renderEditor({ | ||
plainNodes: [new TableExtension(), new TableRowExtension(), new TableCellExtension()], | ||
others: [{ priority: 10, extension: new BaseKeymapExtension() }], | ||
}); | ||
|
||
describe('command', () => { | ||
const setup = () => { | ||
const { | ||
view, | ||
add, | ||
nodes: { doc, p, table, tableRow, tableCell }, | ||
} = create(); | ||
|
||
const buildRegularTable = (rows: string[][]) => { | ||
// Esnure that all rows have same length | ||
expect(Array.from(new Set(rows.map(row => row.length)))).toHaveLength(1); | ||
|
||
return table(...rows.map(row => tableRow(...row.map(cell => tableCell(cell))))); | ||
}; | ||
|
||
return { | ||
view, | ||
add, | ||
doc, | ||
p, | ||
buildRegularTable, | ||
}; | ||
}; | ||
|
||
let { add, doc, p, buildRegularTable } = setup(); | ||
beforeEach(() => { | ||
({ add, doc, p, buildRegularTable } = setup()); | ||
}); | ||
|
||
test('tableAddColumnAfter', () => { | ||
const table = buildRegularTable([ | ||
['A1', 'B1<cursor>', 'C1'], | ||
['A2', 'B2', 'C2'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableAddColumnAfter()); | ||
expect(state.doc).toEqualRemirrorDocument( | ||
doc( | ||
buildRegularTable([ | ||
['A1', 'B1', '', 'C1'], | ||
['A2', 'B2', '', 'C2'], | ||
]), | ||
), | ||
); | ||
}); | ||
|
||
test('tableAddColumnBefore', () => { | ||
const table = buildRegularTable([ | ||
['A1', 'B1', 'C1'], | ||
['A2', 'B2<cursor>', 'C2'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableAddColumnBefore()); | ||
expect(state.doc).toEqualRemirrorDocument( | ||
doc( | ||
buildRegularTable([ | ||
['A1', '', 'B1', 'C1'], | ||
['A2', '', 'B2', 'C2'], | ||
]), | ||
), | ||
); | ||
}); | ||
|
||
test('tableAddRowAfter', () => { | ||
const table = buildRegularTable([ | ||
['A1<cursor>', 'B1'], | ||
['A2', 'B2'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableAddRowAfter()); | ||
expect(state.doc).toEqualRemirrorDocument( | ||
doc( | ||
buildRegularTable([ | ||
['A1', 'B1'], | ||
['', ''], | ||
['A2', 'B2'], | ||
]), | ||
), | ||
); | ||
}); | ||
|
||
test('tableAddRowBefore', () => { | ||
const table = buildRegularTable([ | ||
['A1', 'B1<cursor>'], | ||
['A2', 'B2'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableAddRowBefore()); | ||
expect(state.doc).toEqualRemirrorDocument( | ||
doc( | ||
buildRegularTable([ | ||
['', ''], | ||
['A1', 'B1'], | ||
['A2', 'B2'], | ||
]), | ||
), | ||
); | ||
}); | ||
|
||
test('tableDeleteColumn', () => { | ||
const table = buildRegularTable([ | ||
['A1', 'B1', 'C1'], | ||
['A2<cursor>', 'B2', 'C2'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableDeleteColumn()); | ||
expect(state.doc).toEqualRemirrorDocument( | ||
doc( | ||
buildRegularTable([ | ||
['B1', 'C1'], | ||
['B2', 'C2'], | ||
]), | ||
), | ||
); | ||
}); | ||
|
||
test('tableDeleteRow', () => { | ||
const table = buildRegularTable([ | ||
['A1', 'B1', 'C1'], | ||
['A2', 'B2<cursor>', 'C2'], | ||
['A3', 'B3', 'C3'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableDeleteRow()); | ||
expect(state.doc).toEqualRemirrorDocument( | ||
doc( | ||
buildRegularTable([ | ||
['A1', 'B1', 'C1'], | ||
['A3', 'B3', 'C3'], | ||
]), | ||
), | ||
); | ||
}); | ||
|
||
test('tableDeleteTable', () => { | ||
const table = buildRegularTable([ | ||
['A1', 'B1', 'C1'], | ||
['A2', 'B2', 'C2'], | ||
['A3', 'B3<cursor>', 'C3'], | ||
]); | ||
const { state } = add(doc(table)).actionsCallback(actions => actions.tableDeleteTable()); | ||
expect(state.doc).toEqualRemirrorDocument(doc(p())); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './table-extension'; | ||
export * from './table-types'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { NodeExtension } from '@remirror/core'; | ||
import { | ||
addColumnAfter, | ||
addColumnBefore, | ||
addRowAfter, | ||
addRowBefore, | ||
deleteColumn, | ||
deleteRow, | ||
deleteTable, | ||
tableEditing, | ||
} from 'prosemirror-tables'; | ||
|
||
import { TableSchemaSpec } from './table-types'; | ||
|
||
export class TableExtension extends NodeExtension { | ||
public readonly name = 'table'; | ||
|
||
public readonly schema: TableSchemaSpec = { | ||
content: 'tableRow+', | ||
tableRole: 'table', | ||
isolating: true, | ||
group: 'block', | ||
parseDOM: [{ tag: 'table' }], | ||
toDOM() { | ||
return ['table', 0]; | ||
}, | ||
}; | ||
|
||
public plugin() { | ||
return tableEditing(); | ||
} | ||
|
||
public commands() { | ||
return { | ||
tableAddColumnAfter: () => addColumnAfter, | ||
tableAddColumnBefore: () => addColumnBefore, | ||
tableAddRowAfter: () => addRowAfter, | ||
tableAddRowBefore: () => addRowBefore, | ||
tableDeleteColumn: () => deleteColumn, | ||
tableDeleteRow: () => deleteRow, | ||
tableDeleteTable: () => deleteTable, | ||
}; | ||
} | ||
} | ||
|
||
export class TableRowExtension extends NodeExtension { | ||
public readonly name = 'tableRow'; | ||
|
||
public readonly schema: TableSchemaSpec = { | ||
content: 'tableCell+', | ||
tableRole: 'row', | ||
parseDOM: [{ tag: 'tr' }], | ||
toDOM() { | ||
return ['tr', 0]; | ||
}, | ||
}; | ||
} | ||
|
||
export class TableCellExtension extends NodeExtension { | ||
public readonly name = 'tableCell'; | ||
|
||
public readonly schema: TableSchemaSpec = { | ||
content: 'inline*', | ||
attrs: { | ||
colspan: { | ||
default: 1, | ||
}, | ||
rowspan: { | ||
default: 1, | ||
}, | ||
colwidth: { | ||
default: null, | ||
}, | ||
}, | ||
tableRole: 'cell', | ||
isolating: true, | ||
parseDOM: [{ tag: 'td' }, { tag: 'th' }], | ||
toDOM() { | ||
return ['td', 0]; | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { NodeExtensionSpec } from '@remirror/core'; | ||
|
||
export interface TableSchemaSpec extends NodeExtensionSpec { | ||
tableRole: 'table' | 'row' | 'cell'; | ||
} |
Oops, something went wrong.