All Projects → vasturiano → kapsule

vasturiano / kapsule

Licence: MIT license
Kapsule - A closure based Web Component library

Programming Languages

javascript
184084 projects - #8 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to kapsule

Vaadin Date Picker
The Web Component providing a date selection field with scrollable month calendar. Part of the Vaadin components.
Stars: ✭ 158 (+267.44%)
Mutual labels:  web-component
vuecket
Power of Vue.JS married with magic of Apache Wicket
Stars: ✭ 31 (-27.91%)
Mutual labels:  web-framework
geronimo
Mirror of Apache Geronimo
Stars: ✭ 35 (-18.6%)
Mutual labels:  web-framework
poggit
GitHub application for managing PocketMine-family plugins, and website for sharing plugins.
Stars: ✭ 96 (+123.26%)
Mutual labels:  web-framework
fano
Pascal web application framework
Stars: ✭ 90 (+109.3%)
Mutual labels:  web-framework
InDiv
an angular like web mvvm framework.一个类 angular 前端框架。https://dimalilongji.github.io/InDiv
Stars: ✭ 88 (+104.65%)
Mutual labels:  web-framework
Ion Phaser
A web component to use Phaser Framework with Angular, React, Vue, etc 🎮
Stars: ✭ 152 (+253.49%)
Mutual labels:  web-component
Middleman-NPM
Middleman is an intuitive Express performance monitor for all your middleware 🎉
Stars: ✭ 13 (-69.77%)
Mutual labels:  d3js
get-css-data
A micro-library for collecting stylesheet data from link and style nodes
Stars: ✭ 29 (-32.56%)
Mutual labels:  web-component
effectiveweb.training
Repository for Effective Web Online Course / airhacks.io
Stars: ✭ 17 (-60.47%)
Mutual labels:  d3js
ddplot
Create D3 based SVG graphics easily from R
Stars: ✭ 43 (+0%)
Mutual labels:  d3js
farrow
A Type-Friendly Web Framework for Node.js
Stars: ✭ 748 (+1639.53%)
Mutual labels:  web-framework
react-native-d3multiline-chart
Animated Android and iOS multiline/line/scatterPoint chart based on d3.js 🤘😎🤘
Stars: ✭ 43 (+0%)
Mutual labels:  d3js
React Web Component
Create Web Components with React
Stars: ✭ 221 (+413.95%)
Mutual labels:  web-component
resizable-panels
Web Component that allows to resize its childrens vertically or horizontally
Stars: ✭ 18 (-58.14%)
Mutual labels:  web-component
Html Midi Player
🎹 Play and display MIDI files on the web
Stars: ✭ 158 (+267.44%)
Mutual labels:  web-component
JavaLambdaTutorial
Java Lambda Tutorial
Stars: ✭ 17 (-60.47%)
Mutual labels:  closure
rollup-plugin-closure-compiler-js
Rollup plugin for optimizing JavaScript with google-closure-compiler-js.
Stars: ✭ 31 (-27.91%)
Mutual labels:  closure
whistle
Experiment to build single page apps in Elixir
Stars: ✭ 52 (+20.93%)
Mutual labels:  web-framework
go-zero
A cloud-native Go microservices framework with cli tool for productivity.
Stars: ✭ 23,294 (+54072.09%)
Mutual labels:  web-framework

Kapsule

NPM package Build Size NPM Downloads

A closure based Web Component library, inspired by the reusable charts pattern commonly found in D3 components.

See also react-kapsule for direct integration with React.

Quick start

import Kapsule from 'kapsule';

or using a script tag

<script src="//unpkg.com/kapsule"></script>

Usage example

Define the component

const ColoredText = Kapsule({
    
  props: {
    color: { default: 'red' },
    text: {}
  },

  init(domElement, state) {
    state.elem = document.createElement('span');
    domElement.appendChild(state.elem);
  },

  update(state) {
    state.elem.style.color = state.color;
    state.elem.textContent = state.text;
  }

});

Instantiate the component

const myText = ColoredText();

Render

myText(<myDOMElement>)
  .color('blue')
  .text('foo');

API Reference

Generation

Kapsule([config])

This returns a new closure component that can be instantiated by calling as a regular function, with an optional options object as argument. The options object gets passed verbatim to the init object for interpretation. The component's instance is an object of methods (defined by its config props and methods) that can be called for interacting with the component. Besides these methods, the instance also acts as an initialization function which should be called to attach the component to a DOM node, with the DOM element as sole argument. This triggers the internal init method as specified in the config.

Example:

const Comp = Kapsule(compConfig);

const myInstance = Comp({ /* options */ })
  (<myDOMElement>)
  .prop1('someVal')
  .prop2('anotherVal');

Component configuration

The config object passed to Kapsule supports 5 properties: props, methods, stateInit, init and update. All of these are optional and not required for the component to work, however calling Kapsule({}) generates a dumb component that has no functionality nor interaction.

Extended example:

const Comp = Kapsule({
  props: {
    propName: propConfig,
    ...
  },
  methods: {
    methodName: function(state, ...args) { ... },
    ...
  },
  stateInit() {
    return {
      stateItem: initVal,
      ...
    }
  },
  init(domNode, state, componentOptions) {
    ...
  },
  update(state) {
    ...
  }
});

props: { propName: propConfig, ... }

Each registered prop inside props will declare its own getter/setter method in the component's instance state. This method will have the signature: myInstance.propName([propVal]).

If called without an argument, the method will function as a getter, returning the current value of the prop. If called with a value it will act as a setter, setting the value in the component's internal state, and returning the component's instance for convenience of method chaining. If the value passed in the setter is undefined, the default value will be applied.

The propConfig object supports 3 properties: default, triggerUpdate and onChange.

Extended prop example:

{
  props: {
    propName: {
      default: 6,
      triggerUpdate: false,
      onChange: function(newVal, state) { ... }
    }
  }
}
default

(default: null)

This defines the default value of the prop if it's not set by the instance consumer.

triggerUpdate

(default: true)

This defines whether changes to this prop should trigger the component's update method. Generally, if the update method does not take this prop into account, you can save some performance by setting this to false.

onChange(newVal, state, prevVal)

(default: null)

Here you can specify an event handler that gets triggered whenever this property is modified by the instance consumer. In some circumstances it's useful to keep update changes here instead of in the update method to isolate prop-specific functionality. The previous value is also included for convenience.

The this context of this method is set to the component's instance.

methods: { methodName: function(state, ...args) { ... }, ... }

Each registered method inside methods will expose an additional method in the component's instance. These methods can be seen as a more generic version of the getter/setters in props, and allows the specification of more custom component interactions. The exposed method will have the signature: myInstance.methodName(...args)

The this context of each of this methods is set to the component's instance. If the method does not naturally return a value, it's advised to end the method with return this; so that it can be used in method chaining.

stateInit(componentOptions)

Use this method's return object to initialize the values of any internal state. This should only be used for state that is not exposed externally via props. This state initialization gets ran as soon as the component is instantiated, and before the init method is called.

Example:

function stateInit() {
  return {
   stateItem: initVal,
    ...
  }
}

init(domNode, state, componentOptions)

This method initializes the web component by attaching it to a DOM element. This method gets triggered only when the instance is called by the consumer as myInstance(<domElement>). This is generally only called once for the whole lifecycle of the component's instance.

This is where DOM operations should be performed for the static parts of the document that do not change throughout its lifecycle.

Example:

function init(domNode, state, { label: '' }) {
  state.elem = document.createElement('div'); // static scaffolding div
  domElement.appendChild(state.elem);

  const labelElem = document.createElement('span');
  labelElem.textContent = label; // static label from component options
  state.elem.appendChild(labelElem);
}

An internal state variable initialised indicates whether the instance has been through its init method or not. state.initialised is set to true right after the first init method call.

The this context of this method is set to the component's instance. Returning a value from this method has no effect.

update(state, changedProps)

This method is triggered once right after the init method finishes, and afterwards whenever a prop changes. This method should contain the DOM operations for the dynamic parts of the document that change according to the component props.

Example:

function update(state) {
  state.elem.style.width = state.pxWidth + 'px';
}

Note that multiple calls to update() due to prop changes are internally debounced for performance optimization. This is so that the consumer can request multiple chained prop changes without each one triggering an update, but it instead being batched as one update.

The props that were updated since the last update cycle (or all if it's the first update) are included in the second argument changedProps. This is an object that lists all the updated props and their previous value. For example:

{
  pxWidth: 10, // previous value of pxWidth
  color: 'blue'
}

When applying the initial default values, the previous prop value is referenced as undefined.

The this context of this method is set to the component's instance. Returning a value from this method has no effect.

Other methods

resetProps()

Each instance will get automatically exposed a convenience function resetProps, which when called will reset the internal state of all the props to their defined default values. This will trigger an update call immediately after the props have been reset.

Example:

myInstance
  .propA('someVal')
  .resetProps(); // propA gets reset to its default value
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].