Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

comfey

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

comfey

Tiny micro mini data binding library inspired by react hook useState

  • 2.2.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

Comfey 2 StandWithUkraine RussianWarship

SWUbanner

Comfey is a tiny javascript state management library inspired by React hook useState.Comfey provides a simple data binding library to update your HTML using simple valid HTML data attributes.

Read more in Comfey Wiki

Features

  • 0 dependencies / Lightweight v1.0.0 is 35 lines of code
  • Looks like react hook useState
  • No loops, event driven
  • (Optional) Simple HTML5 data attributes to bind the html elements to the states
  • Finite State Machine as a plugin

Table of content

Install

Using NPM

npm install comfey

Using Yarn

yarn add comfey

Initialize component

Instantiate Comfey - optionally passing in a ViewUpdater.

import Comfey from 'comfey';
const myComponent = new Comfey();

Initialize state

Use .useState() method to initialize a state, useState() accepts 3 parameters. Returns getter and setter functions

/**
 *
 * @param {string} state name of the state
 * @param {any} initialVal initial value
 * @param {function} watcher watcher function that will be called everytime the value of the state changes
 *
 * @returns {Array<[function, function]>} getterFunction and SetterFunction
 */

Example:

const [count, setCount] = app.useState('count', 3, countWatcher);

Watch

Watch gets newValue, oldValue and name of the state and is invoked everytime the state changes.

function countWatcher(newVal, oldVal, stateName) {
  // Do something when value of count state changes
}

Templating

Comfey offers a DOM updater as a separate library. Which will let you use simple HTML data attributes to bind your state data to your DOM.

Create a new Instance of ComfeyDom by

import Comfey, { ComfeyDom } from 'comfey';
const viewUpdater = new ComfeyDom(document.getElementById('app'), DEBUG);

// Now pass in the viewUpdater (ComfeyDom instance) to Comfey's constructor
const app = new Comfey(viewUpdater);

Bind state value to an element

Use data-bind attribute with stateName as its value to bind the innerHTML of the element to the state's value.

Visibility

  • data-bind-visible
  • data-bind-hidden

Bind visible and hidden accepts value to compare.

Example

data-bind-visible="numberStatus::medium"

means the element will be visible if the state numberStatus is set to medium value.

Class

  • data-bind-class

Bind class accepts value to compare, but will not interpolate the bound value as a classname.

Example

data-bind-class="currentPage::active::home"

means the element will get active class if the state currentPage is set to home value.

More bind-class DEMOs

Bind attributes

You can bind an attribute to a state's value w/ data-bind-attr. Data bind attributes can take values delimited by :: which will make each delimited string an argument. The argument pattern looks like

<state>::<dynamic-attr>::<value>

Example:

data-bind-attr="count::style::font-size: $rem"

means, a dynamic attribute will be added to the HTML element when the state count has a value, the attribute added will be style attribute and the value for the style attribute will be

font-size: <StateValue>rem

Multi Apps

You can have any number of applications on a page. Instanciate a new Comfey whenever you need.

  • Multiple apps can use duplicate state names
  • they will be scoped within each app
  • You will have to scope your javascript as well
  • Just avoid declaring getters and setters globally

Example

import Comfey, { ComfeyDom } from 'comfey';
// scoped code blocks can use same getters / setters, etc names if desired.
// name uniquely if needs to be in the same scope

(() => {
  const view = new ComfeyDom(document.getElementById('app1'), COMFEY_DEBUG);
  const app = new Comfey(view, COMFEY_DEBUG);
  const [, setActive] = app.useState('stateActive', false);

  setInterval(() => {
    setActive(Math.random() > 0.5);
  }, 1000);
})();

(() => {
  const view = new ComfeyDom(document.getElementById('app2'), COMFEY_DEBUG);
  const app = new Comfey(view, COMFEY_DEBUG);
  const [, setActive] = app.useState('stateActive', false);

  setInterval(() => {
    setActive(Math.random() > 0.5);
  }, 1000);
})();

More Multi App DEMOs

Examples

Counter Example

CodeSandbox

<div id="my-component">
  <div>
    Count:
    <span data-bind="count">
      <!--   This placeholder will be updated with value of count state -->
    </span>
  </div>
  <div>Show plus: <span data-bind="showPlus">x</span></div>
  <div>Hide minus: <span data-bind="hideMinus">x</span></div>
  <div class="buttons">
    <!--   Increment button will be visible if showPlus state is set to true   -->
    <button id="increment" data-bind-visible="showPlus">+</button>
    <button id="decrement" data-bind-hidden="hideMinus">-</button>

    <!-- Bind attribute, state :: attr :: value, $ for stateValue placeholder -->
    <button id="increment" data-bind-attr="disablePlus::disabled::">+</button>
    <div>
      Count:<span
        data-bind-attr="count::style::font-size: $rem"
        data-bind="count"
        >x</span
      >
    </div>
    <div>
      NumberStatus:
      <span data-bind-visible="numberStatus::medium">Medium</span>
      <span data-bind-visible="numberStatus::max">Max</span>
      <span data-bind-visible="numberStatus::min">Min</span>
    </div>
  </div>
</div>
import Comfey, { ComfeyDom } from 'comfey';

const app = new Comfey(new ComfeyDom(document.getElementById('app')));

// Select buttons
const btnIncrement = document.getElementById('increment');
const btnDecrement = document.getElementById('decrement');

// Initialize states
const [, setShowPlus] = app.useState('showPlus', true);
const [, setHideMinus] = app.useState('hideMinus', false);
const [count, setCount] = app.useState('count', 3, countWatcher);

function countWatcher(newVal) {
  if (newVal > 4) {
    setShowPlus(false);
  } else {
    setShowPlus(true);
    if (newVal < 1) {
      setHideMinus(true);
    } else {
      setHideMinus(false);
    }
  }
}

// Button behaviours
btnIncrement.addEventListener('click', () => {
  setCount(count() + 1);
});
btnDecrement.addEventListener('click', () => {
  setCount(count() - 1);
});

Comfey - Pokemon buddy game

Codesandbox

Multi level navigation

Codesandbox

Change log

v2.0

  • ViewUpdater abstracted, no more DOM manipulation code in main library.
  • Empty instantiation of Comfey will ignore view update (Headless Mode) as opposed to falling back to document
  • ComfeyDom introduced to support DOM manipulation, which can be optionally passed in to Comfey constructor. See examples above or in /demo/ directory.
  • Comfey is an ESM module

Keywords

FAQs

Package last updated on 06 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc