npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@webselect/editor

v6.1.0

Published

A text editor UI built on top of TipTap

Downloads

37

Readme

Webselect text editor

The editor is a UI built on top of TipTap, which itself is a high-level abstraction of ProseMirror.

Table of Contents

Installation

npm i @webselect/editor

Usage

ESM environments

This can be implemented natively in the browser:

<link rel="stylesheet" href="./path/to/editor.css">

<script type="module">
    import { Editor } from './path/to/editor.mjs';

    const editor = new Editor({ ... });
</script>

Or as part of a build pipeline / bundler:

// Optional depending on setup.
// Explained in the "Styling" section.
import './path/to/editor.css';

import { Editor } from '@webselect/editor';

const editor = new Editor({ ... });

Legacy environments

This works in a similar way to libraries such as jQuery, which expose a global variable. In this case that variable is WebselectEditor.

<script src="./path/to/editor.browser.js"></script>

<script>
    document.addEventListener("DOMContentLoaded", () => {
        const editor = new WebselectEditor.Editor({ ... });
    });
</script>

Creating a new Editor

const editor = new Editor({
    element: document.querySelector('.editor'),
});

The Editor constructor takes a single options object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | element | Element | - | The Element that the Editor will be injected into. | | ❌ | editorClasses | string | - | Additional classes to be added to the TipTap editor. | | ❌ | controls | string[] | ["bold", "italic", "underline", "link", "textColour", "fontFamily", "fontSize", "heading", "orderedList", "bulletList", "alignLeft", "alignMiddle", "alignRight", "alignJustify", "customStyles", "clearFormatting"] | Defining controls. | | ❌ | content | string | - | Initial HTML content to populate the Editor with on instantiation. | | ❌ | swatches | string[] | - | Swatches that will be shown in the colour picker. | | ❌ | fontFamilies | FontFamilyOption[] | - | Font families. | | ❌ | fontSizes | FontSizeOptions | - | Font sizes. | | ❌ | fontWeights | FontWeightOption[] | - | Font weights. | | ❌ | headings | HeadingOptions | - | Headings. | | ❌ | textFormatting | TextFormattingOptions | - | Text formatting. | | ❌ | customStyles | CustomStyleOption[] | - | Custom styles. | | ❌ | customLinkStyles | CustomLinkStyle[] | - | Custom link styles. | | ❌ | transforms | Record<string, boolean> | - | Transforms. | | ❌ | elementBindings | Element | Element[] | - | Any Element(s) that will be automatically bound to the value of the Editor. | | ❌ | onUpdate | (editor: Editor) ⇒ void | - | Callback function that fires whenever the state of the Editor is changed. |

Defining controls

The controls option is a simple string array which can contain any of the following:

  • alignLeft
  • alignMiddle
  • alignRight
  • alignJustify
  • bold
  • bulletList
  • clearFormatting
  • customStyles
  • fontFamily
  • fontSize
  • textFormatting
  • heading
  • italic
  • link
  • orderedList
  • textColour
  • underline

You can also use a pipe character (|) to create a divider/separator between controls.

The order in which items are defined corresponds to their order in the toolbar.

Font families

The fontFamilies option takes a FontFamilyOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | families | FontFamily[] | - | An array of font families. | | ❌ | defaultFontFamily | string | families[0] | The default font family. Defaults to the first item in families. | | ❌ | defaultValueTemplate | string | '{{name}} (default)' | The template used to render the default option. Template syntax ({{prop}}) can be used here to reference any properties of FontFamily. |

FontFamily

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | name | string | - | The name shown in the toolbar. | | ✅ | cssValue | string | - | The CSS value that will be applied to the HTML. |

Example:

fontFamilies: {
    //defaultValueTemplate: '{{name}} (default)',
    families: [
        {
            name: 'Arial (default)',
            cssValue: 'Arial, sans-serif',
            isDefault: true,
        },
        {
            name: 'Times New Roman',
            cssValue: '"Times New Roman", serif',
        },
    ]
}

For consistency, the default font family should also be defined in the CSS:

:root {
    --wse-editor-font-family: Arial, sans-serif;
}

Font sizes

The fontSizes option takes a FontSizeOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | sizes | FontSize[] \| (createRange) ⇒ FontSize[] | - | An array of font sizes, or a function that returns an array of font sizes. The FontSize object signature is detailed below, and functions are called with a createRange helper method which is also detailed below. | | ❌ | defaultFontSize | string | '16px' | The default font size. This should correspond to a FontSize. | | ❌ | defaultValueTemplate | string | '{{name}} (default)' | The template used to render the default option. Template syntax ({{prop}}) can be used here to reference any properties of FontSize. |

FontSize

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | cssValue | string | - | The CSS value applied to the HTML. | | ❌ | name | string | cssValue | The name shown in the dropdown. |

createRange(options: CreateRangeOptions) ⇒ FontSize[]

Convenience method to help create a range of items. Takes a CreateRangeOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | from | number | - | The start of the range. | | ✅ | to | number | - | The end of the range. | | ✅ | transformer | (index: number) ⇒ FontSize | - | Method that returns a FontSize. | | ❌ | step | number | 1 | The increment between values. |

Example using the createRange helper:

fontSizes: {
    //defaultFontSize: '16px',
    //defaultValueTemplate: '{{name}} (default)',
    sizes: (createRange) =>
        createRange({
            from: 10,
            to: 72,
            transformer: (i) => ({
                //name: `${i}px`,
                cssValue: `${i}px`,
            }),
        }),
    },

For consistency, the default font size should also be defined in the CSS:

:root {
    --wse-editor-font-size: 16px;
}

Font weights

The fontWeights option takes a FontWeightOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | weights | FontWeight[] | - | An array of font weights. | | ❌ | defaultFontWeight | string | '400' | The default font size. This should correspond to a FontWeight. | | ❌ | defaultValueTemplate | string | '{{name}} (default)' | The template used to render the default option. Template syntax ({{prop}}) can be used here to reference any properties of FontWeight. |

FontWeight

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | cssValue | string | - | The CSS value applied to the HTML. | | ❌ | name | string | - | The name shown in the dropdown. | | ❌ | isBold | boolean | - | Marks the option as "default" bold. Rather than applying CSS styles, text will be wrapped with <strong> tags, for semantically correct and accessible HTML. This isn't mandatory and can be ignored. |

Example:

fontWeights: {
    //defaultFontWeight: '400',
    //defaultValueTemplate: '{{name}} (default)',
    weights: [
        {
            //name: '100',
            cssValue: '100',
            //isBold: false,
        },
        {
            //name: '400',
            cssValue: '400',
            //isBold: false,
        },
        {
            //name: '700',
            cssValue: '700',
            isBold: true,
        },
        {
            //name: '900',
            cssValue: '900',
            //isBold: false,
        },
    ],
},

Headings

The headings option takes a HeadingOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | levels | Record<number, HeadingSize> | - | A number-keyed object, where the key represents the heading level, and the value is a HeadingSize object, which is detailed below. | | ❌ | defaultFontWeight | string | '700' | The default heading weight. This can be overridden by individual heading levels. | | ❌ | sizeListNameTemplate | string | 'Default ({{cssValue}})' | The template used to render the current heading level in the font size dropdown (if applicable). Template syntax can be used here to reference any properties of HeadingSize. |

HeadingSize

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | name | string | - | The name shown in the dropdown. | | ✅ | cssValue | string | - | The CSS value applied to the HTML. | | ❌ | defaultFontWeight | string | HeadingOptions[defaultWeight] | A level-specific weight override. |

Example:

headings: {
    //defaultFontWeight: '700',
    defaultFontFamily: 'Times',
    //sizeListNameTemplate: 'Default ({{cssValue}})',
    levels: {
        1: {
            name: 'Heading 1',
            cssValue: '3rem',
            //defaultFontWeight: '700',
            //defaultFontFamily: 'Times',
        },
        2: {
            name: 'Heading 2',
            cssValue: '2.5rem',
            //defaultFontWeight: '700',
            //defaultFontFamily: 'Times',
        },
        3: {
            name: 'Heading 3',
            cssValue: '2rem',
            //defaultFontWeight: '700',
            //defaultFontFamily: 'Times',
        },
    },
},

For consistency, heading sizes should also be defined in the CSS:

:root {
    --wse-editor-font-size-h1: 3rem;
    --wse-editor-font-size-h2: 2.5rem;
    --wse-editor-font-size-h3: 2rem;
    ...
}

Relationship between font sizes and headings

In instances where both font sizes and headings are defined, without some kind of synchronisation between the two, the UI can become a bit confusing. Let's say the default font size of the editor is 16px, and the corresponding name in the dropdown is "16px (default)". If you select a heading variant which is, for example, 3rem, the HTML markup will change accordingly and visually you'll see the difference, but the font size dropdown will still show "16px (default)". Technically this is correct, but it's not very intuitive. In these instances, a new option will be appended to the font size dropdown to represent the selected heading level.

The value of this option is controlled via the aforementioned sizeListNameTemplate property.

Lastly, the defaultValueTemplate property in FontSizeOptions is ignored whilst a heading is selected.

Text formatting

The textFormatting option takes a TextFormattingOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ❌ | letterSpacing | LetterSpacingOptions | - | Letter spacing options, as detailed below. | | ❌ | lineHeight | LineHeightOptions | - | Line height options, as detailed below. | | ❌ | lineHeightFix | boolean | false | Apply a line height fix to the editor, see Issues with line height. |

Letter spacing

The letterSpacing option takes a LetterSpacingOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | min | number | - | The minimum value. | | ✅ | max | number | - | The maximum value. | | ✅ | step | number | - | The increment between values. | | ❌ | defaultValue | number | 0 | The default letter spacing. | | ❌ | unit | string | 'px' | The unit of measurement used. |

In the unlikely event that the default letter spacing is not 0, the default value should also be defined in the CSS:

:root {
    --wse-editor-letter-spacing: 1ch;
}
Line height

The lineHeight option takes a LineHeightOptions object:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | min | number | - | The minimum value. | | ✅ | max | number | - | The maximum value. | | ✅ | step | number | - | The increment between values. | | ✅ | defaultValue | number | - | The default line height. | | ❌ | headingOverrides | Record<number \| 'all', Partial<LineHeightOptions>> | - | Global or level-specific heading overrides, as detailed below. |

Heading overrides

The headingOverrides option takes an object whose keys are either numerical, representing individual heading levels, or the keyword 'all', which encompases all heading levels. Any property of LineHeightOptions can be overridden, but for obvious reasons headingOverrides is ignored. Missing properties are inherited.

Example with a global heading override:

{
    defaultValue: 1.5,
    headingOverrides: {
        all: {
            defaultValue: 1.2,
        },
    },
}

For consistency, line heights should also be defined in the CSS:

:root {
    --wse-editor-line-height: 1.5;
    --wse-editor-line-height-heading: 1.2;
}

Line heights can also be defined for individual heading levels, should they differ from one another:

:root {
    --wse-editor-line-height-h6: 1.6;
    ...
}
Issues with line height

Mixing line height with headings can be problematic.

The way Tiptap works is that, when a style ("mark") is added to a paragraph or heading ("node"), a <span> element is created, for example:

<h1>
    <span style="line-height: 1;">Hello world</span>
</h1>

This seems like it would work, but more often than not the <h1> will have its own line height set, whether implicitly or explicitly via custom CSS or a UI library. Let's say the line height of the <h1> is 1.4, but the <span>'s line height is 1. It'll actually look as if the <span>'s value of 1 is being ignored. It isn't, but because its parent has a line height of 1.4, the invisible "tracks" completely encompass that of the <span>. It's as if each line has a min-height rule applied.

If the <span>'s line height is greater than 1.4, then things appear to work again, because it's pushing outside its parents boundaries.

To fix this we can use CSS to query any "node" that contains a <span> with an inline line-height rule, and reset its line height to a base value. That way, any descendants are guaranteed to have a larger line height.

This will also need to be handled on the production side, either with a custom implementation or by copying the source code.

Custom styles

The customStyles option takes an array of CustomStyleOption objects:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | name | string | - | The name shown in the dropdown. | | ✅ | classList | string[] | - | The class(es) to apply to the HTML. |

Custom link styles

The customLinkStyles option takes an array of CustomLinkStyle objects:

| Required | Parameter | Type | Default | Description | | --- | --- | --- | --- | --- | | ✅ | name | string | - | The name shown in the dropdown. | | ✅ | classList | string[] | - | The class(es) to apply to the HTML. |

Transforms

The transforms option specifies a list of key/value pairs. The key is the name of the transform, and the value is a boolean that either enables or disables the transform. Transforms will be applied to content on initialisation and update, both programatically or via user input (ie. paste). The following transforms are available:

| Key | Enabled by default | Description | | --- | --- | --- | | sanitiseNonBreakingSpaces | ❌ | Remove non-breaking spaces. |

Example:

{
    transforms: {
        sanitiseNonBreakingSpaces: true,
    },
}

The Editor instance

The underlying TipTap instance is available as property tiptap.

const editor = new Editor({ ... });

// TipTap instance
editor.tiptap;

The following instance methods are also available. In some cases these simply proxy TipTap methods for ease of use.

destroy() ⇒ void

Destroy the Editor along with its TipTap instance.

getHTML() ⇒ string

Get the Editor contents as HTML. If the Editor is "empty-ish", as in it doesn't contain any meaningful content, but may contain an empty node, an empty string is returned instead. If you require the default behaviour then you can use editor.tiptap.getHTML() instead.

isEmpty() ⇒ boolean

Check if the Editor is empty or not.

setContent(content: string) ⇒ void

Update the Editor with new content.

Example:

editor.setContent('<p>Example text</p>');

closeAllDialogs() ⇒ void

Close any open dialogs.

Styling

If your pipeline/setup allows it, for example using Webpack along with the css-loader plugin, you can import the CSS directly in the module:

import './path/to/editor.css';

Otherwise you'll want to copy editor.css from the package into your distribution folder and reference it in your HTML like normal.

The Editor comes with a basic, neutral layout that is based on CSS variables. These can be overridden to customise the Editor as needed. The following tables lists the available variables and their functions:

Toolbar

| Variable | Default | Description | | --- | --- | --- | | --wse-toolbar-bg-colour | transparent | The background colour of the toolbar. | | --wse-toolbar-text-colour | #000 | The text colour of the toolbar. | | --wse-toolbar-padding | 10px | The toolbar padding. | | --wse-toolbar-gap | 8px | The gap between controls in the toolbar. | | --wse-toolbar-border | 1px solid #999 | The border underneath the toolbar. | | --wse-toolbar-transition-duration | 0.2s | The duration of the toolbar animations. | | --wse-toolbar-transition-timing-function | ease | The timing function of the toolbar animations. |

Toolbar controls

| Variable | Default | Description | | --- | --- | --- | | --wse-control-border | none | The border around toolbar controls. | | --wse-control-radius | 5px | The border radius of toolbar controls. | | --wse-control-padding-x | 6px | The horizontal padding of toolbar controls. | | --wse-control-padding-y | 0px | The vertical padding of toolbar controls. | | --wse-control-bg-colour | #eee | The background colour of toolbar controls. | | --wse-control-text-colour | #000 | The text colour of toolbar controls. | | --wse-control-hover-bg-colour | #ddd | The hover background colour of toolbar controls. | | --wse-control-hover-text-colour | #000 | The hover text colour of toolbar controls. | | --wse-control-highlight-bg-colour | #222 | The highlighted background colour of toolbar controls. | | --wse-control-highlight-text-colour | #fff | The highlighted text colour of toolbar controls. | | --wse-control-icon-size | 16px | The size of toolbar control icons. | | --wse-control-colour-outline | 2px | The size of toolbar control outline (used to indicate a selected colour). | | --wse-control-colour-outline-offset | -2px | The offset of the toolbar control outline. |

Toolbar dividers

| Variable | Default | Description | | --- | --- | --- | | --wse-toolbar-divider-width | 1px | The width of the dividers. | | --wse-toolbar-divider-height | 60% | The height of the dividers. | | --wse-toolbar-divider-colour | #999 | The colour of the dividers. |

Dialog

| Variable | Default | Description | | --- | --- | --- | | --wse-dialog-bg-colour | #222 | The background colour of control dialogs. | | --wse-dialog-text-colour | #fff | The text colour of control dialogs. | | --wse-dialog-padding | 15px | The padding of control dialogs. | | --wse-dialog-radius | 5px | The border radius of control dialogs. | | --wse-dialog-gap | 6px | The gap between elements inside control dialogs. | | --wse-dialog-shadow | none | The drop shadow underneath control dialogs. | | --wse-dialog-transition-duration | 0.6s | The duration of the dialog animation. | | --wse-dialog-transition-timing-function | cubic-bezier(0.16, 1, 0.3, 1) | The timing function of the dialog animation. |

Select list

| Variable | Default | Description | | --- | --- | --- | | --wse-select-max-height | 400px | The maximum height of the select. | | --wse-select-option-gap | 6px | The gap between options. | | --wse-select-option-padding-x | 8px | The horizontal padding of each option. | | --wse-select-option-padding-y | 6px | The vertical padding of each option. | | --wse-select-option-radius | 5px | The border radius of each option. | | --wse-select-option-highlight-bg-colour | #fff | The highlighted background colour of each option | | --wse-select-option-highlight-text-colour | #222 | The highlighted text colour of each option. | | --wse-select-option-hover-bg-colour | rgb(white, 0.2) | The hover background colour of each option. | | --wse-select-option-hover-text-colour | #fff | The hover text colour of each option. |

Editor

| Variable | Default | Description | | --- | --- | --- | | --wse-editor-bg-colour | #fff | The background colour of the Editor. | | --wse-editor-text-colour | #000 | The default text colour of the Editor. | | --wse-editor-font-family | revert | The default font family of the Editor. | | --wse-editor-font-family-heading | revert | The default heading font family of the Editor. | | --wse-editor-font-family-h[1-6] | revert | Heading-level specific font family overrides. | | --wse-editor-font-size | revert | The default font size of the Editor. | | --wse-editor-font-size-h[1-6] | revert | Heading-level specific font size overrides. | | --wse-editor-letter-spacing | revert | The default letter spacing of the Editor. | | --wse-editor-line-height | revert | The default line height of the Editor. | | --wse-editor-line-height-heading | revert | The default heading line height of the Editor. | | --wse-editor-line-height-h[1-6] | revert | Heading-level specific line height overrides. | | --wse-editor-min-height | 200px | The minimum height of the Editor. | | --wse-editor-max-height | none | The maximum height of the Editor. | | --wse-editor-padding | 20px | The padding of the Editor. | | --wse-editor-border | none | The border around the Editor. | | --wse-editor-radius | 0px | The border radius of the Editor. |

Text colour component

| Variable | Default | Description | | --- | --- | --- | | --wse-default-swatch-radius | 50% | The radius of the swatches. | | --wse-default-swatch-highlight-outline | #fff | The highlight colour of the swatches. | | --wse-default-swatches-per-line | 8 | The number of swatches per row. |

Contributing

TipTap is headless and totally modular, so out of the box it does virtually nothing. You can intitialise it with "extensions", which enable features such as bold or italic text. In some cases this will include markdown functionality, but it does not include any UI. That's down to us to implement ourselves.

In most cases the requirements for a feature UI are as follows:

  • Have a button or some kind of interactive element that will invoke the functionality of an "extension".
  • Provide a subsequent UI if needed (eg. a colour picker)
  • The element will react to changes in TipTap's state (eg. a bold button will highlight if the user selects bold text in the Editor).

To that end the Editor is based on class inheritance, with common functionality delegated to abstract classes. These can be found under components/abstract/*.

The base class, Control<T>, does very little other than define methods that must be implemented by subclasses, and expose the current Editor instance. This will probably never need to be touched.

Next in the heirarchy is ControlButton, which represents a clickable item in the Editor toolbar. This is used for simple extensions such as toggling bold or italic text.

Some extensions require additional UI, and this is where ControlButtonWithDialog is useful, as it lets us show a dialog (styled as a dropdown). More on Dialog in the next section.

As a stylised replacement for the native <select> element, we also have ControlButtonWithSelect, which implements ControlButtonWithDialog under the hood, but requires less setup when dealing with simple option lists.

Lastly we have the top-level controls that implement one of the aforementioned abstract classes. These are found under components/Control{Name}.ts (note the Control prefix for consistency).

A simple example is the control for bold text:

import icon from '../../img/bold.svg';

import { highlightIf } from '../utils';
import { ControlButton } from './abstract/ControlButton';

class ControlBold extends ControlButton {
    constructor() {
        super(icon);
    }

    public override update(): void {
        highlightIf(this.tiptap.isActive('bold'), this.element);
    }

    protected override onClick(): void {
        this.tiptap.chain().focus().toggleBold().run();
    }
}

export { ControlBold };

Currently the icons are provided by Flaticon. There's a collection in our account named "Text editor". Any new icons should follow the same style if possible.

The update() method is mandatory and is called when TipTap fires its transaction event, which essentially means the state has changed somehow. This includes the user making selections or simply changing the caret position.

The highlightIf() method is a simple utility function that will apply some styles to the element if the condition is truthy. What's important is the condition itself: this.tiptap.isActive('bold'). If the caret is within the bounds of a block of bold text, or the current selection contains any bold markers, this will return true and our UI element will be highlighted.

The onClick() method is fired when the UI element is clicked. This then hooks directly into the TipTap API to enable bold text. This action will also trigger the transaction event mentioned previously.

Note that not all extensions have the same methods, so you'll need to reference the TipTap docs when implementing any new extensions. The concept, however, is the same.

For a more complex example, it's worth having a look at ControlTextColour.ts, as this requires an additional UI for displaying a colour picker.

In a nutshell, the process for adding a new UI control is as follows:

  • Install the corresponding TipTap extension.
  • Register the extension when initialising TipTap (in main.ts).
  • Find a new icon and add it to the img directory.
  • Create a new Control{Name}.ts that extends one of the abstract Control* classes and implement according to the TipTap docs.
  • Import and add a new instance of the control to the controls array (in main.ts).

The Dialog component

The Dialog component creates a floating dialog beneath a Control. You'll need to pass in the HTML to render in the dialog, but there are a couple of handy conventions to be aware of:

  • If your HTML contains a <form> element then a submit event will automatically be bound to it, which will call event.preventDefault() and then, if you have provided an onSubmit property, it'll be called.
  • If your HTML contains a <button> element with a data-type="clear" attribute (inside a <form> element) then a click event will be automatically bound to it, which will call onClear if you have provided it.

Development mode

Run watch to begin development mode.

Demo pages

Demo pages can be found under the demos directory. You'll need to spin up a server in the project root, and not under demos, so that the distribution files can be referenced properly. I recommend using serve.

Publishing

Before publishing a new version, please make sure to update CHANGELOG.md.

The prePublishOnly task runs automatically and builds the project for production (including code formatting and generating TypeScript types), so you shouldn't have to do any heavy lifting.

Once you're ready, you can run the release script either from the IDE, or manually from a terminal:

npm run release