• Stars
    star
    305
  • Rank 136,879 (Top 3 %)
  • Language
    JavaScript
  • License
    GNU Affero Genera...
  • Created about 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

UI knobs controllers for JS/CSS live manipulation of various parameters


Knobs

Knobs ๐ŸŽ›๏ธ UI controllers for JS/CSS manipulation

๐Ÿ‘‰ Demo ๐Ÿ‘ˆ

Minified 54kb
Brotli 13.5kb
GZIP 15kb

What is this:

Started as something I needed for my many Codepens - A way to provide viewers, and myself, a set of controllers, for manipulating the DOM instantaneously.

Imagine certain aspects of a web page, or a specific *component*, which you would like to add the ability to control on-the-fly. Change the visual looks or certain javascript parameters with a move or a slider.

CSS-variables (custom properties) are a great match for this script as they compute in real-time. Javascript is of course a benefitor because every knobs can be attached with a callback that recieves the current value, and additional data, as to what that value should be applied on.

It's so easy & quick to use Knobs, about 1 minute!

โš ๏ธ Supported only in modern browsers

Features:

  • range input (wheel-supported)
  • color input with awesome custom color picker
  • checkbox input
  • radio inputs group
  • select dropdown (native)
  • Custom HTML-Knobs (add your own buttons or whatever)
  • Resset all knobs (to defaults)
  • Reset individual knob
  • Labels - group all the knobb defined after a certain label
  • Expand/Collapse knobs groups
  • Apply changes live, on-the-fly, or with an Apply button
  • Auto-detect CSS variables defined in knobs as their initialvalues, if possible
  • Knobs are completely isolated within an iframe (unaffected by your page styles)
  • Allows 3 states of visibility:
    • 0 - Starts as hidden
    • 1 - Starts as visible
    • 2 - Always visible
  • Knobs component placement position (relative to window viewport):
    • top right (default)
    • bottom right
    • top left
    • bottom left
  • Allows theme customization (currently very limited)

Configuration:

All is needed is to include the knobs script on the page, and set it up.

new Knobs(settings)

Settings

Name Type Default Info
theme Object Knobs theme variables. Since the Knobs are encapsulated within an iframe, they cannot be be styled from outside.
live Boolean true Should changes be immediately applied
persist Boolean false Persist changes using the browser's localstorage. Store key/value per knob, where key is the knob's label.
visible Number 0 0 - Starts as hidden
1 - Starts as visible
2 - Always visible
CSSVarTarget Element/NodeList Global HTML element(s) for which to apply the CSS custom properties.
Can also be configured per-knob.
knobsToggle Boolean false if true - adds a checkbox next to each knob, which allows temporarily disabling the knob, reverting to default
knobs Array Array of Objects describing the knobs controllers on-screen
standalone Boolean false if true - does not create an iframe and appends it to the page, but simply gives the developer the DOM node, as is, to inject manually with knobs.DOM.scope node. Note that CSS in also needed ('./src/styles/styles.scss`)
theme (defaults)
{
  styles      : ``,                // optioanlly add any CSS and it will be injected into the iframe
  flow        : 'horizontal',      // use 'compact' to keep things tight
  position    : 'top right',
  primaryColor: '#0366D6',         // mainly for links / range sliders
  'base-color': "rgba(0,0,0,1)",   // mainly for the background color but also for input fields such as text or number
  textColor   : "#CCC",
  border      : 'none'
}
knobs

An array of Objects, where the properties describe a knob.

It is possible to define/update the knobs Array after instance initialization, like so:

var myKnobs = new Knobs({ CSSVarTarget:document.body }) // only if working with CSS variables

myKnobs.knobs = [{...}, ...] // Add/change the knobs. will automatically re-render (see example further below)

All defined knob properties, beside a special few, are attributes that are applied on the HTML input element that controls the knob, so it is up to the developer who set up the knobs to use the appropriate attributes, for each type of of the supported knobs (range, color, checkbox).

The special other properties are:

onChange

Callback which fires on every input event

cssVar

Optional. An array of 3 items:

  1. (String) - CSS variable name
  2. (String) - Units (optional - Ex. % or px)
  3. (HTML NODE) - Reference to an HTML node to apply the knob's CSS variable on (optional)

Sometimes it is wanted for variables to be defined unitless, for calculation-purposes, like so:

div{
  --size: 10;
  /* limits with width to a minimum of 10px by using unitless variable for the "max" function */
  width: calc(Max(50, var(--size)) * 1px);
}

So, when a unitless-variable is desired, but ultimatly it will have a unit, then units (2nd item in the array) should be written with a dash prefix, Ex.: -px, and it will be displayed in the label correctly but ignored when applying the variable.

cssVarsHSLA (boolean)

Applies only to color knobs and if set to true will generate 4 CSS variables for the HSLA version of the color.

--main-color-h, --main-color-s, --main-color-l & --main-color-a.

{
  cssVar: ['main-color'],
  cssVarsHSLA: true,
  label: 'Page background',
  type: 'color',
  defaultFormat: 'hsla',
},

defaultFormat (string)

Applies only to color knobs. Sets the default format displayed to the user and also the value which will be set to the input. Possible values are: hsla, rgba, hex.

label (string)

A text which is displayed alongside the knob

labelTitle (string)

Optional title attribute for the knob's label

value (string, number)

Acts as the initial value of the knob, except for checkbox knobs, in which case, if the knob also has cssVar property set, then the checkbox is checked, that CSS variable value will be the value property of the knob, Ex.

{
  cssVar: ['hide'], // CSS variable name "--hide"
  label: 'Show',
  type: 'checkbox',
  // checked: true,  // not checked by default
  value: 'none', // if checked: --hide: none;
}

Then in your CSS you can write the below, so when --hide is not defined, block is used as the display property value.

display: var(--hide, block);

It is possible to use an already-declared CSS-varaible (on the target element) by emmiting the value prop from the knob decleration. The program will try to get the value using getComputedStyle and getPropertyValue.

Variables which has calc or any other computations might result in NaN. In which case, a console.warn will be presented and a manually typed value property for the knob would be advised.

isToggled (boolean) If this property is set to false, the knob will be toggled off by default.

Will only take affect if knobsToggle setting is set to true

options (array) Used for knobs of type select. An Array of options to render.

[20, 150, [200, '200 nice pixels'], 500]

An option can be split to the actual value it represents and its textual value, as the above example shows.

knobClass (string) Add your own class to the knob (row) element itself (for styling purposes). Remember that in order to add custom styles, the theme.styles setting should be used, because all knobs are encapsulated within an iframe so your page styles won't affect anything that's inside.

render (string) Allows to render anything you want in the knob area. Should return a string of HTML, for example:

{
  render: `
    <button onclick='alert(1)'>1</button>
    <button onclick='alert(2)'>2</button>
  `,
  knobClass: 'custom-actions'
}

script (function) A function to be called which has logic related to the custom HTML in the render property (shown above). The function recieves 2 arguments: The knobs instance referece and the (auto)generated knob name string.

{
  label: 'Custom HTML with label',
  render: `
    <button type='button' class='specialBtn1'>1</button>
    <button type='button' class='specialBtn2'>2</button>
  `,
  script(knobs, name){
    knobs.getKnobElm(name).addEventListener("click", e => {
      if( e.target.tagName == 'BUTTON' )
        alert(e.target.textContent)
    })
  },
},

Install:

npm i @yaireo/knobs

CDN source:

https://unpkg.com/@yaireo/knobs@latest

Example:

When Using with NPM, first import Knobs

import Knobs from '@yaireo/knobs'

Color manipulation methods:

format & CSStoHSLA are defined on Knobs' instances in color property, for example:

const myKnobs = new Knobs({
  ...,
  knobs: [
    {
      cssVar: ['bg'], // alias for the CSS variable
      label: 'Color',
      type: 'color',
      value: '#45FDA9',
      onChange(e, knobData, hsla) => {
        console.log( myKnobs.format(knobData.value, 'rgb') )  // will print a color string in RGBA
      }
    }
  ]
})

myKnobs.color.format()

See color-picker docs

Defining Knobs:

var settings = {
  theme: {
    position: 'bottom right', // default is 'top left'
  },

  // should update immediately (default true)
  live: false,

  // 0 - starts as hidden, 1 - starts as visible, 2 - always visible
  visible: 0,

  CSSVarTarget: document.querySelector('.testSubject'),

  knobs: [
    {
      cssVar: ['width', '-px'], // prefix unit with '-' makes it only a part of the title but not of the variable
      label: 'Width',
      labelTitle: 'Changes the width at steps of 50 pixels',
      type: 'range',
      value: 200,
      min: 0,
      max: 500,
      step: 50,
      onChange: console.log  // javascript callback on every "input" event
    },

    {
      cssVar: ['width', '-px'],
      label: 'Width preset',
      type: 'select',
      options: [20, 150, [200, '200 nice pixels'], 500],
      value: 150, // should be one of the options
      defaultValue: 150 // value for which to reset to (optional)
      isToggled: false, // this knob will not take affect by default
    },

    {
      cssVar: ['height', 'vh'],
      label: 'Height',
      type: 'range',
      // value: 20,  // if a value is not defined, Knobs will try to get it from the CSS ("CSSVarTarget" selector) automatically
      min: 0,
      max: 100,
      onChange: console.log
    },

    {
      cssVar: ['align'],
      label: 'Align boxes',
      type: 'radio',
      name: 'align-radio-group',
      options: [
        { value:'left', hidden:true, label: '<svg ...' },
        { value: 'center', label:'Center' },
        { value:'right', hidden:true, label:'<svg ...' }
      ],
      value: 'center',
      defaultValue: 'left'
    },

    {
      cssVar: ['radius', '%'],
      label: 'Radius of the big square here',
      type: 'range',
      value: 0,
      min: 0,
      max: 50,
      onChange: console.log
    },

    "Label example",

    {
      cssVar: ['bg'], // alias for the CSS variable
      label: 'Color',
      type: 'color',
      defaultFormat: 'hsla',
      cssVarsHSLA: true,
      value: '#45FDA9',
      swatches: ['red', 'gold'],  //  swatches which can be selected inside the color picker
      onChange: (e, knobData, hsla) => console.log(e, knobData, hsla, knobData.value)
    },

    {
      cssVar: ['main-bg', null, document.body], // [alias for the CSS variable, units, applies on element]
      label: 'Background',
      type: 'color',
      value: '#FFFFFF',
      onChange: (e, knobData, hsla) => console.log(e, knobData, hsla, knobData.value)
    },

    ["Label example", false] // group is collapsed by default
    {
      cssVar: ['hide'], // alias for the CSS variable
      label: 'Show',
      type: 'checkbox',
      // checked: true,  // default
      value: 'none',
      onChange: console.log
    },

    {
      label: 'Custom with label',
      render: `
        <button type='button' class='specialBtn1'>1</button>
        <button type='button' class='specialBtn2'>2</button>
      `,
      script(knobs, name){
        knobs.getKnobElm(name).addEventListener("click", e => {
          if( e.target.tagName == 'BUTTON' )
            alert(e.target.textContent)
        })
      },
    },

    {
      render: `
        <button type='button' class='specialBtn3'>๐Ÿ˜Ž</button>
      `,
      script(knobs){
        const elm = knobs.DOM.scope.querySelector('.specialBtn3')
        elm.addEventListener("click", () => alert('๐Ÿ˜Ž'))
      },
      knobClass: 'custom-actions'
    }
  ]
}

var penKnobs = new Knobs(settings)

More Repositories

1

tagify

๐Ÿ”– lightweight, efficient Tags input component in Vanilla JS / React / Angular / Vue
HTML
3,466
star
2

fancyInput

Makes typing in input fields fun with CSS3 effects
CSS
1,928
star
3

photobox

A lightweight CSS3 image viewer that is pretty to look and and easy to use
JavaScript
747
star
4

fakescroll

vanilla-js lightweight custom HTML scrollbar
JavaScript
363
star
5

pathAnimator

Moves a DOM element along an SVG path (or do whatever along a path...)
HTML
261
star
6

validator

HTML form validation. Perfectly made for all scenerios, lightweight, semantic & easy to use
JavaScript
258
star
7

stickyfloat

This plugin makes it possible to have a fixed position element that is relative to itโ€™s parent. A normal fixed positioned element would be โ€œout of contextโ€ and is very difficult to use in the most common situations with fluid designs. This plugin solves that problem with as little code as I could possible get it so it will run in the most optimized way, while also allow you to customize it in many important ways which might suit you best.
CSS
167
star
8

ui-range

Beautiful UI-Range input component, highly customisable, based on CSS variables. including a floating output value, min & max values on the sides & ticks according to the steps
SCSS
101
star
9

console-colors

Browser Console logs with colors
JavaScript
81
star
10

color-picker

Minimal javascript color picker component
JavaScript
61
star
11

relative-time

javascript function to transform timestamp or date to local relative-time
JavaScript
40
star
12

Do-in

Run tasks repeatedly in a fixed duration
HTML
24
star
13

dragsort

Animated drag sorting for horizontal list items
JavaScript
21
star
14

letterer

breaks a DOM node text into separate letters
HTML
16
star
15

touchy

JavaScript
16
star
16

dateRangePicker

pick a range between dates (months) or from presets
JavaScript
13
star
17

hover-carousel

mouse-position relative carousel
JavaScript
12
star
18

title-tooltip

Automatically converts HTML title attributes to nicer better tooltips
JavaScript
12
star
19

jqSwipe

Minimal swipe special event for touch-enabled devices
JavaScript
11
star
20

simpleGrid

the most performant grid system for same-size items
JavaScript
10
star
21

react-bouncer

Delay rendering of a React component with Debounce, Throttle, or any custom method
9
star
22

infinite

smart endless scrolling
JavaScript
9
star
23

listBreaker

split HTML lists into lists chunks
JavaScript
8
star
24

react-number-input

Renders native number input as a locale number (on blur) and reverts back to a workable number (on focus)
JavaScript
8
star
25

position

Position a DOM element at a certain X,Y or next to another element
JavaScript
6
star
26

react-ref-watcher

Watchable refs changes with conditional re-renders
JavaScript
6
star
27

input_indicator

JavaScript
5
star
28

ui-switch

React Switch component based on native checkbox input, using CSS variables (custom properties) as much as possible. Easily customisable and super lightweight.
JavaScript
4
star
29

react-hooks

React Hooks authored by myself
JavaScript
3
star
30

carouselite

basic, light-weight Carousel jQuery plugin
JavaScript
3
star
31

javascript-interview-questions

javascript interview questions
2
star
32

endless

infinite scrolling jQuery plugin
JavaScript
2
star
33

password-unveil

Unveil password input fields on mouse hover
JavaScript
2
star
34

Mini-page-navigation

lets the user navigate through a web page using a "mini-page" helper on the side of the page, so the user could see where he is in relation to page as a whole, (showing the actual page as a small canvas image)
2
star
35

gulp-file-contents-to-keys

convert files into key/value objects where key is filename, value is the content
JavaScript
2
star
36

translation-yaml-manager

A UI-only system which intends to ease the process of managing YAML translations files across multiple languages
1
star
37

gulp-template-compile-es6

Compile template files to ES6 exported functions
JavaScript
1
star
38

saSlider

Super Awesome Slider - jQuery plugin
CSS
1
star
39

sb-issue-performance-essentials-addon

issue report for Storybook slow rendering
JavaScript
1
star
40

self-descriptive-numbers

Generates self-descriptive numbers
HTML
1
star
41

sb-issue--react-client

Strobook issue #17926
JavaScript
1
star
42

tagify-react-test

Basic React test app for "@yaireo/tagify" package
JavaScript
1
star
43

ToDo

JavaScript
1
star
44

jQuery-ajax-delay

Wrapper for jQuery AJAX method which sets a random delay which simulates real-world latency
JavaScript
1
star
45

multi-range-slider

Custom input element for multiple sliders in one range
JavaScript
1
star
46

swc-js-extension-fails-with-jsx-content

For SWC bug report
JavaScript
1
star