Coder Social home page Coder Social logo

icheer / web-spreadsheet Goto Github PK

View Code? Open in Web Editor NEW
10.0 1.0 1.0 208 KB

A simple Excel-like spreadsheet web component built with svelte.

Home Page: https://spread.vercel.app

License: MIT License

JavaScript 61.05% Svelte 26.20% HTML 12.75%
customelement spreadsheet webcomponent svelte

web-spreadsheet's Introduction

web-spreadsheet

A simple Excel-like spreadsheet web component built with svelte.

  • dependency free
  • compatible with any javascript framework/UI library
  • light-weighted (size: 35KB, gzip: ~12KB)
  • multiple cell type supported (input, select, multi-select, image, date, time)
  • support customized validator, formatter and computed function
  • support UNDO/REDO with ctrl+Z & ctrl+Y

Online demo

https://spread.vercel.app

screenshot

How to use

Install with npm:

npm install web-spreadsheet --save

and import it in your code:

import 'web-spreadsheet';

You can also load the code from a CDN such as jsdelivr:

<script src="https://cdn.jsdelivr.net/npm/web-spreadsheet@latest/lib/index.min.js"></script>

then you can use the customElement <spread-sheet></spread-sheet> in your HTML code.

If you're using it in a Vue.js project, you can pass proper props columns and data into customElement such as <spread-sheet :columns="columns" :data="rows"/> Then your spreadsheet will come into view.

The columns and data props look like these:

data() {
  return {
    columns: [
      {
        text: 'Fullname',
        key: 'fullname',
        type: 'input',
        width: '200px',
        props: {
          maxlength: 25
        },
        params: {
          validator: (value, row) => {
            const name = (value || '').trim();
            if (!name) return 'Please enter Fullname';
            if (name.length > 25) return 'Fullname length should less than 25';
          }
        }
      },
      {
        text: 'Department',
        key: 'dept',
        type: 'select',
        width: '8em',
        items: [
          { label: 'Operation', value: 'OP' },
          { label: 'IT Support', value: 'IT' }
        ]
      },
      {
        text: 'Identity type',
        key: 'idType',
        type: 'multi-select',
        width: '6em',
        items: [
          { label: 'ID Card', value: 'ID' },
          { label: 'Passport', value: 'PASSPORT' }
        ]
      },
      {
        text: 'Identity number',
        key: 'idNumber',
        type: 'input',
        width: '9em',
        props: {
          maxlength: 18
        }
      },
      {
        text: 'Fee',
        key: 'fee',
        align: 'right',
        type: 'input',
        width: '5em',
        props: {
          maxlength: 8
        },
        params: {
          validator: str => {
            if (!str) return;
            const num = +str;
            if (Number.isNaN(num)) return 'Please enter a number';
          },
          formatter: str => {
            const num = +str;
            return num.toFixed(2);
          }
        }
      },
      {
        text: 'Total Fee(+10)',
        key: 'totalFee',
        align: 'right',
        type: 'input',
        width: '9em',
        props: {
          maxlength: 8
        },
        params: {
          validator: str => {
            if (!str) return;
            const num = +str;
            if (Number.isNaN(num)) return 'Please enter a number';
          },
          formatter: str => {
            const num = +str;
            return num.toFixed(2);
          },
          computed: (row, column) => {
            const num = +row.fee || 0;
            return (num + 10).toFixed(2);
          }
        }
      },
      {
        text: 'Pictures',
        key: 'pics',
        type: 'image',
        width: '8.5em',
        props: {
          max: 3, // means can upload 3 pics at most
          uploadApi: 'http://192.168.105.11:28080/api/file/common/upload'
        }
      },
      {
        text: 'Update Time',
        key: 'updateTime',
        type: 'date',
        width: '8em'
      }
    ],
    rows: [
      {
        fullName: 'Tony Joe',
        dept: 'OP',
        idType: ['ID', 'PASSPORT'],
        idNumber: '12341122234',
        fee: 33,
        pics: [
          'https://github.blog/wp-content/uploads/2019/03/product-social.png?fit=1201%2C630',
          '//fpoimg.com/400x400?text=Preview&bg_color=000000',
          '//fpoimg.com/400x400?text=Preview&bg_color=ffeeee'
        ],
        updateTime: '2020-02-01'
      },
      {
        fullName: 'Mary Lee',
        dept: 'IT',
        idType: ['ID'],
        idNumber: '6515151374',
        fee: 25,
        pics: [
          '//fpoimg.com/400x400?text=Preview&bg_color=eeffee'
        ],
        updateTime: '2020-02-02'
      }
    ]
  }
}

If you want to use it in pure javascript, you can refer the demo page.

FEATURES

  • cell type: input, select, multi-select, image, date, time (depends on columns array)
  • when the row data changed, it will automaticly emit a "change" event, so you can handle the newest row data
  • validator / formatter / computed functions can be added in column.params object
  • log at most 20 change history in memory, so you can press ctrl+Z/Y to UNDO/REDO
  • right clicking the row head can call the context menu which can insert/delete the row
  • upload images and preview images
  • support sort by column
  • auto switch languages(CN or EN) depends on your <html lang="___">
  • keypress behavior like Excel (arrows, escape, tab, delete, backspace etc)
  • pasted letters by ctrl+V will fill current highlighted input cell
  • for those non-modern browsers which don't support shadowDOM or customElement, you can use polyfill to let them support: just add a <script src="https://cdn.jsdelivr.net/npm/@webcomponents/[email protected]/webcomponents-bundle.min.js"></script> in <head>

TODO

  • column actions such as insert/delete column
  • ...

web-spreadsheet's People

Contributors

icheer avatar idg-mayao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

thundersz

web-spreadsheet's Issues

What license?

Hi,
Great to see this svelte project. Congrats
What is the license?

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.