Coder Social home page Coder Social logo

slate-deep-table's Introduction

slate-deep-table

npm version Linux Build Status

A Slate plugin to handle tables with nested block content. Forked from the excellent slate-edit-table implementation, but retooled to work with deep content.

Demo: https://jasonphillips.github.io/slate-deep-table/

Install

npm install slate-deep-table

Features

  • Pressing Up and Down, move the cursor to next/previous row
  • Pressing Tab, move the select to next cell
  • Pressing Shift+Tab, move the select to previous cell
  • Permits nested block content within table cells
  • Optionally create headerless tables

Compatibility

Slate is a fast-moving library, so check the CHANGELOG for information on the currently supported version.

Simple Usage

import DeepTable from 'slate-deep-table'

const plugins = [
  DeepTable({ /* options object here; see below */ })
]

// now instantiate your Slate Editor with these plugins, according to slate documentation

Options

  • [typeTable: String] — type for table default: 'table'
  • [typeRow: String] — type for the rows default: 'table_row'
  • [typeCell: String] — type for the cells default: 'table_cell'
  • [typeContent: String] — type for the default blocks within cells default: 'paragraph'

Queries and Commands

slate-deep-table exports queries and commands that you can invoke on your editor instance:

// anywhere where 'editor' is passed as an argument, or using the react Component's ref, 
// you may directly invoke any of the exported functions below, e.g:
const inATable = editor.isSelectionInTable();

if (!inATable) {
  editor.insertTable();
}

Check example/main.js for usage in a typical context.

query isSelectionInTable()

editor.isSelectionInTable() => Boolean

Return true if current cursor position is inside a table.

query getTablePosition()

editor.getTablePosition() => null || TablePosition

Returns null if cursor is not in a table, else returns an object you can use to query the current cell and row location:

const position = editor.getTablePosition()

position.getRowIndex() // returns row id (0-indexed)
position.getColumnIndex() // return column index (0-indexed)
position.getWidth() // returns count of columns
position.getHeight() // returns count of rows

command insertTable()

editor.insertTable(columns: Number?, rows: Number?) => Editor

Insert a new empty table.

command insertTableByKey/Path()

editor.insertTableByKey(key: String, index: Number?, columns: Number?, rows: Number?) => Editor

editor.insertTableByPath(path: List, index: Number?, columns: Number?, rows: Number?) => Editor

Insert a new empty table by Key/Path, follows insertNodeByKey/Path()'s insertion procedure. Index defaults to 0 if empty.

command insertRow()

editor.insertRow(at: Number?) => Editor

Insert a new row after the current one or at the specific index (at).

command insertColumn()

editor.insertColumn(at: Number?) => Editor

Insert a new column after the current one or at the specific index (at).

command removeTable()

editor.removeTable() => Editor

Remove current table.

command removeRow()

editor.removeRow(at: Number?) => Editor

Remove current row or the one at a specific index (at).

command removeColumn()

editor.removeColumn(at: Number?) => Editor

Remove current column or the one at a specific index (at).

command moveTableSelection()

editor.moveTableSelection(column: Number, row: Number) => Editor

Move the selection to a specific position in the table.

command moveTableSelectionBy()

editor.moveTableSelectionBy(column: Number, row: Number) => Editor

Move the selection by the given amount of columns and rows.

command toggleTableHeaders()

editor.toggleTableHeaders() => Editor

Toggles whether the table will render the first row as a header row (within a thead) or as a regular row.

slate-deep-table's People

Contributors

adamszeptycki avatar aunswjx avatar dependabot[bot] avatar elliottsj avatar eugene-preply avatar ingro avatar jasonphillips avatar mklabs avatar samypesse avatar soreine avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

slate-deep-table's Issues

Copy cell content and paste will create nested table

Hi! I found when I did copy/paste content within a table cell will cause unexpected table nesting. What I have done:

  1. insert a 2x2 table
  2. type "slate is wonderful" in any cell
  3. select any characters within the cell (e.g. select "wonder") and ctrl-c copy
  4. then paste in any cells. A new table is inserted in the cell with the selected content, which expected only the copied characters are pasted.

The above can be replicated from official demo: https://jasonphillips.github.io/slate-deep-table/

Maybe it's because of the nested table feature? If so how can I avoid this?

How to use setColumnAlign ?

Hi.

I tried to use setColumnAlign but with no joy.
Should I refer to it using Editor object or plugin itself ?

Thanks.

How to serialise table?

Hi,

THANK YOU for adding thead support in this release, really much appreciated.

I'm struggling to use this within a serialiser, as I'm finding the tbody and thead tags being stripped out. Is there a recommended method for this?

I'm using a fairly standard implementation of the seraliser as seen in the docs.

Here's an (abridged) version:

const rules = [
  {
    deserialize(el, next) {
      const type = BLOCK_TAGS[el.tagName.toLowerCase()]
      if (type) {
        return {
          object: 'block',
          type: type,
          nodes: next(el.childNodes),
        }
      }
    },
    serialize(obj, children) {
      if (obj.object == 'block') {
        switch (obj.type) {
            case 'table': return (<table>{children}</table>);
            case 'table_row':   return (<tr>{children}</tr>);
            case 'table_cell':  return (<td>{children}</td>);
[...]
        }
      }
    },
  }
];

Something like the above will strip out the thead and tbody, and if I add cases for them in the switch statement, they're not ever seen by the seralizer.

I appreciate this isn't a support forum, so I understand if you remove this issue, although any pointers appreciated :)

Toggle headers and deserialization

Hi there !

I'm trying to deserialize the table, it works but the headers part (thead => headless) doesn't work.

Here is the code :

   const type = BLOCK_TAGS[el.tagName.toLowerCase()];
      if (type) {
        const headless = el.firstChild
          ? el.firstChild.nodeName === "THEAD"
          : false;
...
return {
          object: "block",
          type: type,
          data: {
            className: el.getAttribute("class"),
            align,
            color,
            headless
          },
          nodes: next(el.childNodes)

Thanks 👍

Is this package alive?

Firstly, we are pretty much thankful to you for this package, but the issues have been opened since a while and they're not getting cleared. Maybe the creators have been busy but at least to keep it alive, it would be better if there are at least a few discussions going on.

InsertTableByKey/Path

Problem:
We are currently using this plugin for our project to facilitate table creation and edit.

While the insertTable() seems to work fine on the default slate document schema, we are running into the problem of inserting the Table in its own block since it uses editor.insertBlock().

Our schema structure consist of a custom type block that wraps paragraph block and other custom block within it and editor.insertBlock() will just Insert a new block at the same level as the current block, which is within the custom block.

Proposal:
Having a InsertTableByKey/Path that utilises insertNodeByKey/Path command to insert at document level by obtaining the document key.
This also gives more flexibility to user who might want to insert deep within the slate tree if they have a complex document schema.

I can create the function and make a PR for it. Would love for you guys to support it.

Colspan and rowspan handling

How complicated would this be to add?

Haven't looked into the source code much, but if you think it's feasible for a new contributor to build, I'd like to give it a shot since it's something we need at work in order to use this plugin.

Focus on first element when [New row] tab

At the moment, when we create a new row by tabbing the last element, the editor focus on the last element of the newly created row. In google docs/word, the default behavior is to focus on the first element instead of the last.

Support for v0.5

Is there going to be an upgrade to slate v0.5? Really hoping so. Cheers

onKeyDown swallows events

The onKeyDown implementation stops event propagation, leading to some whacky behavior as we integrate this plugin to Slate.

One way to prevent this is by calling next() when the current selection is not in the table, letting other onKeyDown implementations handle the event. I'm happy to create a pull request that does the following:

    /**
     * User is pressing a key in the editor
     */
    function onKeyDown(event, change, next) {
        const { value } = change;
        // Only handle events in cells
        if (!isSelectionInTable(value)) {
            return next();
        }

        // Build arguments list
        const args = [ event, change, opts ];

        switch (event.key) {
            case KEY_TAB:
                return onTab(...args);
            case KEY_DOWN:
            case KEY_UP:
                return onUpDown(...args);
        }
    }

Captions for tables

Hey, I am looking forward to implementing captions for tables. To implement captions, I need to define the schema for tables which I cannot access from slate-deep-table. Please let me know how I can implement captions for slate-deep-table!
This is the sandbox where I have a working example for image captions and tried a few things with slate-deep-table but didn't work out.
sandbox

Undo/Redo on removeNodeByKey

History is not recovered when trying to undo a row/column deletion, or redo a row/column insertion.
case 1:

  1. delete a row/column
  2. press ctrl/cmd-z
  3. no response

case 2:

  1. insert a new row/column
  2. press ctrl/cmd-z, the insertion will be undone
  3. then press ctrl/cmd-shift-z, redo will fail with no response

I've tested on the given schema, but seems the problem doesn't relate to normalisation. I can't verify if this is possibly a bug on slate regarding history management. Since both the above operations are dealing with removeNodeByKey.

I am using Slate 0.47.4 slate-deep-table 0.9.6.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.