content logo

React Buttons:

Dynamic Circular Numeric Buttons Generator with Settings Panel using React

In this post, you will see the numeric buttons. These buttons are not normally visible, and by clicking on the color button in the middle of the page, the other buttons will appear. Each button has a number on it. The color button normally has a plus icon and by clicking on it the icon changes to a cross.

#

Circular React Button Code

#

Numeric React Button Generator

#

HTML Button Settings

#

HTML Animating Buttons

<!-- This script got from frontendfreecode.com -->
    <div id="app"></div><a style="font-size: 8pt; text-decoration: none" target="_blank" href="http://frontendfreecode.com">Free Frontend</a>
                                                                            
* {
  box-sizing: border-box;
}
body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f2f2f2;
}
.dial-button {
  --base-bg: #fff;
  position: relative;
}
.dial-button > label:not(.dial-button__cloak) {
  background: var(--base-bg);
  border-radius: 50%;
  display: block;
  height: calc(var(--parent, 44) * 1px);
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: calc(var(--parent, 44) * 1px);
  z-index: 4;
}
.dial-button > input {
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
}
.dial-button > :checked ~ label:first-of-type {
  --shadow-offset: 0;
}
.dial-button > :checked ~ button {
  --opacity: 1;
  --scale: 1;
  --translation: calc((var(--parent) / 2) + (var(--child) / 2) + var(--radius));
  z-index: 2;
}
.dial-button > :checked ~ .dial-button__cloak {
  bottom: 0;
  left: 0;
  position: fixed;
  right: 0;
  top: 0;
}
.dial-button button {
  --opacity: 0;
  --rotation: calc(var(--offset, 0) + ((var(--bounds) / var(--kids)) * var(--index)));
  --scale: 0;
  --translation: 0;
  background: var(--base-bg);
  border: 0;
  border-radius: 100%;
  height: calc(var(--child, 44) * 1px);
  left: 50%;
  position: absolute;
  top: 50%;
  opacity: var(--opacity);
  transform: translate(-50%, -50%) rotate(calc(var(--rotation) * 1deg)) translate(0, calc(var(--translation, 0) * 1px)) rotate(calc(var(--rotation) * -1deg)) scale(var(--scale, 1));
  transition: transform calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), opacity calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), box-shadow 0.1s;
  width: calc(var(--child, 44) * 1px);
}
.dial-button button,
.dial-button label:first-of-type {
  --shadow-offset: 4;
  border: 2px solid #000;
  box-shadow: 0px calc(var(--shadow-offset, 0) * 1px) 0 0 #333;
  cursor: pointer;
  outline: transparent;
}
.dial-button button {
  background: hsl(0, 0%, calc(var(--shade, 100) * 1%));
  font-weight: bold;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.dial-button button:hover {
  --shade: 90;
}
.dial-button button:active {
  --shadow-offset: 0;
}
.dial-button :checked ~ label:first-of-type {
  --rotation: -45;
}
.dial-button label:first-of-type {
  background: hsl(var(--hue, 25), 100%, 50%);
}
.dial-button label:first-of-type svg {
  height: 65%;
  width: 65%;
  fill: #fff;
  top: 50%;
  left: 50%;
  position: absolute;
  transform: translate(-50%, -50%) rotate(calc(var(--rotation, 0) * 1deg));
  transition: transform 0.1s ease;
}
.dg.ac {
  z-index: 9999 !important;
}
const {
  dat: { GUI },
  React,
  React: { useEffect, useRef, useState },
  ReactDOM: { render } } =
window;
const copyToClipboard = (content, msg) => {
  const input = document.createElement('input');
  input.setAttribute('type', 'text');
  input.value = content;
  document.body.appendChild(input);
  input.select();
  input.setSelectionRange(0, 99999);
  document.execCommand('copy');
  if (msg) alert(msg);
  input.remove();
};
const CONFIG = {
  CONFIG: {
    buttons: 5,
    radius: 40,
    offset: 25,
    bounds: 360 },
  SPEED: {
    delayStep: 0,
    transition: 0.2 },
  SIZING: {
    parent: 56,
    child: 44 },
  copyHTML: () => {
    copyToClipboard(
    document.querySelector('.dial-button').outerHTML,
    'Markup copied 👍');
  },
  copyCSS: () => {
    const CSS = `
    .dial-button {
      --base-bg: #fff;
      position: relative;
    }
    .dial-button > label:not(.dial-button__cloak) {
      background: var(--base-bg);
      border-radius: 50%;
      display: block;
      height: calc(var(--parent, 44) * 1px);
      left: 50%;
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      width: calc(var(--parent, 44) * 1px);
      z-index: 4;
    }
    .dial-button > input {
      left: 50%;
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      z-index: 3;
    }
    .dial-button > :checked ~ label:first-of-type {
      --shadow-offset: 0;
    }
    .dial-button > :checked ~ button {
      --opacity: 1;
      --scale: 1;
      --translation: calc((var(--parent) / 2) + (var(--child) / 2) + var(--radius));
      z-index: 2;
    }
    .dial-button > :checked ~ .dial-button__cloak {
      bottom: 0;
      left: 0;
      position: fixed;
      right: 0;
      top: 0;
    }
    .dial-button button {
      --opacity: 0;
      --rotation: calc(var(--offset, 0) + ((var(--bounds) / var(--kids)) * var(--index)));
      --scale: 0;
      --translation: 0;
      background: var(--base-bg);
      border: 0;
      border-radius: 100%;
      height: calc(var(--child, 44) * 1px);
      left: 50%;
      position: absolute;
      top: 50%;
      opacity: var(--opacity);
      transform: translate(-50%, -50%) rotate(calc(var(--rotation) * 1deg)) translate(0, calc(var(--translation, 0) * 1px)) rotate(calc(var(--rotation) * -1deg)) scale(var(--scale, 1));
      transition: transform calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), opacity calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), box-shadow 0.1s;
      width: calc(var(--child, 44) * 1px);
    }
    `;
    copyToClipboard(CSS, 'CSS copied 👍');
  } };
const BOUNDS = {
  CONFIG: {
    buttons: [1, 10],
    radius: [0, 250],
    offset: [0, 360],
    bounds: [90, 360, 10] },
  SPEED: {
    transition: [0.1, 2, 0.01],
    delayStep: [0, 0.5, 0.01] },
  SIZING: {
    parent: [44, 100],
    child: [44, 100] } };
const App = () => {
  const [model, setModel] = useState(0);
  const datRef = useRef(null);
  useEffect(() => {
    document.documentElement.style.setProperty('--hue', Math.random() * 360);
    if (!datRef.current) {
      datRef.current = new GUI({ name: 'Dial Button Config' });
      for (const CATEGORY in BOUNDS) {
        const FOLDER = datRef.current.addFolder(CATEGORY);
        for (const spec in BOUNDS[CATEGORY]) {
          FOLDER.add(
          CONFIG[CATEGORY],
          spec,
          BOUNDS[CATEGORY][spec][0],
          BOUNDS[CATEGORY][spec][1],
          BOUNDS[CATEGORY][spec][2] ? BOUNDS[CATEGORY][spec][2] : 1).
          onChange(() => setModel(new Date().getTime()));
        }
      }
      datRef.current.add(CONFIG, 'copyHTML').name('COPY MARKUP');
      datRef.current.add(CONFIG, 'copyCSS').name('COPY CSS');
    }
  }, [model]);
  return /*#__PURE__*/(
    React.createElement("div", {
      className: "dial-button",
      htmlFor: "dial",
      style: {
        '--kids': CONFIG.CONFIG.buttons,
        '--radius': CONFIG.CONFIG.radius,
        '--offset': CONFIG.CONFIG.offset,
        '--bounds': CONFIG.CONFIG.bounds,
        '--delay': CONFIG.SPEED.delayStep,
        '--transition': CONFIG.SPEED.transition,
        '--child': CONFIG.SIZING.child,
        '--parent': CONFIG.SIZING.parent } }, /*#__PURE__*/
    React.createElement("input", { type: "checkbox", id: "dial" }),
    new Array(CONFIG.CONFIG.buttons).fill().map((_, index) => /*#__PURE__*/
    React.createElement("button", {
      key: `dial-button-${model}--${index}`,
      style: {
        '--index': index } },
    index)), /*#__PURE__*/
    React.createElement("label", { htmlFor: "dial" }, /*#__PURE__*/
    React.createElement("svg", { viewBox: "0 0 24 24" }, /*#__PURE__*/
    React.createElement("path", { d: "M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" }))), /*#__PURE__*/
    React.createElement("label", { className: "dial-button__cloak", htmlFor: "dial" })));
};
render( /*#__PURE__*/React.createElement(App, null), document.getElementById('app'));
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
        <script src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js'></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- This script got from frontendfreecode.com -->

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
        <script src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js'></script>
<style>
* {
  box-sizing: border-box;
}
body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f2f2f2;
}
.dial-button {
  --base-bg: #fff;
  position: relative;
}
.dial-button > label:not(.dial-button__cloak) {
  background: var(--base-bg);
  border-radius: 50%;
  display: block;
  height: calc(var(--parent, 44) * 1px);
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: calc(var(--parent, 44) * 1px);
  z-index: 4;
}
.dial-button > input {
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
}
.dial-button > :checked ~ label:first-of-type {
  --shadow-offset: 0;
}
.dial-button > :checked ~ button {
  --opacity: 1;
  --scale: 1;
  --translation: calc((var(--parent) / 2) + (var(--child) / 2) + var(--radius));
  z-index: 2;
}
.dial-button > :checked ~ .dial-button__cloak {
  bottom: 0;
  left: 0;
  position: fixed;
  right: 0;
  top: 0;
}
.dial-button button {
  --opacity: 0;
  --rotation: calc(var(--offset, 0) + ((var(--bounds) / var(--kids)) * var(--index)));
  --scale: 0;
  --translation: 0;
  background: var(--base-bg);
  border: 0;
  border-radius: 100%;
  height: calc(var(--child, 44) * 1px);
  left: 50%;
  position: absolute;
  top: 50%;
  opacity: var(--opacity);
  transform: translate(-50%, -50%) rotate(calc(var(--rotation) * 1deg)) translate(0, calc(var(--translation, 0) * 1px)) rotate(calc(var(--rotation) * -1deg)) scale(var(--scale, 1));
  transition: transform calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), opacity calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), box-shadow 0.1s;
  width: calc(var(--child, 44) * 1px);
}
.dial-button button,
.dial-button label:first-of-type {
  --shadow-offset: 4;
  border: 2px solid #000;
  box-shadow: 0px calc(var(--shadow-offset, 0) * 1px) 0 0 #333;
  cursor: pointer;
  outline: transparent;
}
.dial-button button {
  background: hsl(0, 0%, calc(var(--shade, 100) * 1%));
  font-weight: bold;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.dial-button button:hover {
  --shade: 90;
}
.dial-button button:active {
  --shadow-offset: 0;
}
.dial-button :checked ~ label:first-of-type {
  --rotation: -45;
}
.dial-button label:first-of-type {
  background: hsl(var(--hue, 25), 100%, 50%);
}
.dial-button label:first-of-type svg {
  height: 65%;
  width: 65%;
  fill: #fff;
  top: 50%;
  left: 50%;
  position: absolute;
  transform: translate(-50%, -50%) rotate(calc(var(--rotation, 0) * 1deg));
  transition: transform 0.1s ease;
}
.dg.ac {
  z-index: 9999 !important;
}
</style>

</head>
<body>
    <div id="app"></div><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Free Frontend</a></div>
<script>
const {
  dat: { GUI },
  React,
  React: { useEffect, useRef, useState },
  ReactDOM: { render } } =
window;
const copyToClipboard = (content, msg) => {
  const input = document.createElement('input');
  input.setAttribute('type', 'text');
  input.value = content;
  document.body.appendChild(input);
  input.select();
  input.setSelectionRange(0, 99999);
  document.execCommand('copy');
  if (msg) alert(msg);
  input.remove();
};
const CONFIG = {
  CONFIG: {
    buttons: 5,
    radius: 40,
    offset: 25,
    bounds: 360 },
  SPEED: {
    delayStep: 0,
    transition: 0.2 },
  SIZING: {
    parent: 56,
    child: 44 },
  copyHTML: () => {
    copyToClipboard(
    document.querySelector('.dial-button').outerHTML,
    'Markup copied 👍');
  },
  copyCSS: () => {
    const CSS = `
    .dial-button {
      --base-bg: #fff;
      position: relative;
    }
    .dial-button > label:not(.dial-button__cloak) {
      background: var(--base-bg);
      border-radius: 50%;
      display: block;
      height: calc(var(--parent, 44) * 1px);
      left: 50%;
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      width: calc(var(--parent, 44) * 1px);
      z-index: 4;
    }
    .dial-button > input {
      left: 50%;
      position: absolute;
      top: 50%;
      transform: translate(-50%, -50%);
      z-index: 3;
    }
    .dial-button > :checked ~ label:first-of-type {
      --shadow-offset: 0;
    }
    .dial-button > :checked ~ button {
      --opacity: 1;
      --scale: 1;
      --translation: calc((var(--parent) / 2) + (var(--child) / 2) + var(--radius));
      z-index: 2;
    }
    .dial-button > :checked ~ .dial-button__cloak {
      bottom: 0;
      left: 0;
      position: fixed;
      right: 0;
      top: 0;
    }
    .dial-button button {
      --opacity: 0;
      --rotation: calc(var(--offset, 0) + ((var(--bounds) / var(--kids)) * var(--index)));
      --scale: 0;
      --translation: 0;
      background: var(--base-bg);
      border: 0;
      border-radius: 100%;
      height: calc(var(--child, 44) * 1px);
      left: 50%;
      position: absolute;
      top: 50%;
      opacity: var(--opacity);
      transform: translate(-50%, -50%) rotate(calc(var(--rotation) * 1deg)) translate(0, calc(var(--translation, 0) * 1px)) rotate(calc(var(--rotation) * -1deg)) scale(var(--scale, 1));
      transition: transform calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), opacity calc(var(--transition, 0.25) * 1s) calc((var(--delay, 0) * var(--index)) * 1s), box-shadow 0.1s;
      width: calc(var(--child, 44) * 1px);
    }
    `;
    copyToClipboard(CSS, 'CSS copied 👍');
  } };
const BOUNDS = {
  CONFIG: {
    buttons: [1, 10],
    radius: [0, 250],
    offset: [0, 360],
    bounds: [90, 360, 10] },
  SPEED: {
    transition: [0.1, 2, 0.01],
    delayStep: [0, 0.5, 0.01] },
  SIZING: {
    parent: [44, 100],
    child: [44, 100] } };
const App = () => {
  const [model, setModel] = useState(0);
  const datRef = useRef(null);
  useEffect(() => {
    document.documentElement.style.setProperty('--hue', Math.random() * 360);
    if (!datRef.current) {
      datRef.current = new GUI({ name: 'Dial Button Config' });
      for (const CATEGORY in BOUNDS) {
        const FOLDER = datRef.current.addFolder(CATEGORY);
        for (const spec in BOUNDS[CATEGORY]) {
          FOLDER.add(
          CONFIG[CATEGORY],
          spec,
          BOUNDS[CATEGORY][spec][0],
          BOUNDS[CATEGORY][spec][1],
          BOUNDS[CATEGORY][spec][2] ? BOUNDS[CATEGORY][spec][2] : 1).
          onChange(() => setModel(new Date().getTime()));
        }
      }
      datRef.current.add(CONFIG, 'copyHTML').name('COPY MARKUP');
      datRef.current.add(CONFIG, 'copyCSS').name('COPY CSS');
    }
  }, [model]);
  return /*#__PURE__*/(
    React.createElement("div", {
      className: "dial-button",
      htmlFor: "dial",
      style: {
        '--kids': CONFIG.CONFIG.buttons,
        '--radius': CONFIG.CONFIG.radius,
        '--offset': CONFIG.CONFIG.offset,
        '--bounds': CONFIG.CONFIG.bounds,
        '--delay': CONFIG.SPEED.delayStep,
        '--transition': CONFIG.SPEED.transition,
        '--child': CONFIG.SIZING.child,
        '--parent': CONFIG.SIZING.parent } }, /*#__PURE__*/
    React.createElement("input", { type: "checkbox", id: "dial" }),
    new Array(CONFIG.CONFIG.buttons).fill().map((_, index) => /*#__PURE__*/
    React.createElement("button", {
      key: `dial-button-${model}--${index}`,
      style: {
        '--index': index } },
    index)), /*#__PURE__*/
    React.createElement("label", { htmlFor: "dial" }, /*#__PURE__*/
    React.createElement("svg", { viewBox: "0 0 24 24" }, /*#__PURE__*/
    React.createElement("path", { d: "M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" }))), /*#__PURE__*/
    React.createElement("label", { className: "dial-button__cloak", htmlFor: "dial" })));
};
render( /*#__PURE__*/React.createElement(App, null), document.getElementById('app'));
</script>

</body>
</html>
Preview