src/components/atoms/Toggle/index.tsx   A
last analyzed

Complexity

Total Complexity 1
Complexity/F 0

Size

Lines of Code 114
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 1
eloc 61
mnd 1
bc 1
fnc 0
dl 0
loc 114
ccs 24
cts 24
cp 1
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1 1
import "./styles.css";
2
import { ToggleComponent } from "./types";
3 1
import React from "react";
4 1
import classNames from "classnames";
5
6 1
import { buildBoxComponent } from "../../../utils";
7
8
const DEFAULT_ICON = (
9 1
  <svg
10
    x={0}
11
    y={0}
12
    viewBox="0 0 64 64"
13
    xmlSpace="preserve"
14
    width="30px"
15
    height="30px"
16
  >
17
    <circle cx={32} cy={32} r={32} fill="var(--svgexternalcolor)" />
18
    <g className="wrapper">
19
      <path
20
        className="external"
21
        d="M32 52c-9.9 0-18-8.1-18-18 0-6.4 3.4-12.3 8.9-15.5 1-.6 2.2-.2 2.7.7.6 1 .2 2.2-.7 2.7C20.7 24.4 18 29.1 18 34c0 7.7 6.3 14 14 14s14-6.3 14-14c0-5.1-2.7-9.7-7.2-12.2-1-.5-1.3-1.8-.8-2.7.5-1 1.8-1.3 2.7-.8C46.5 21.5 50 27.5 50 34c0 9.9-8.1 18-18 18z"
22
      />
23
    </g>
24
    <g className="wrapper">
25
      <path
26
        className="external"
27
        d="M32 36c-1.1 0-2-.9-2-2V14c0-1.1.9-2 2-2s2 .9 2 2v20c0 1.1-.9 2-2 2z"
28
      />
29
    </g>
30
    <path
31
      className="internal"
32
      d="M39.8 18c4.9 2.7 8.2 8 8.2 14 0 8.8-7.2 16-16 16s-16-7.2-16-16c0-5.9 3.2-11 7.9-13.8M32 32V12"
33
    />
34
  </svg>
35
);
36
37
/**
38
 * A compact Toggle switcher, customized to reflect its actual status
39
 *
40
 * @since 1.1.0
41
 * 
42
 * @param {boolean} value toggle status (true - on/false - off)
43
 * @param {JSX.Element | Element } icon custom toggle icon, used as a default icon
44
 * @param {JSX.Element | Element } onIcon custom toggle "on" icon (`value` === `true`)
45
 * @param {JSX.Element | Element } offIcon custom toggle "off" icon (`value` === `false`)
46
 * @param {(newValue:boolean)=>void} onChange calllback triggered when changing Toggle status
47
 * @param {string} className `common modular-ui prop` - custom className (to better customize it)
48
 * @param {boolean} unstyled `common modular-ui prop` - Style/unstyle component (to better customize it)
49
 * @param {string} id `common modular-ui prop` - `data-id` parameter (for testing purpose, to easily find the component into the DOM)
50
 * @param {boolean} dark `common modular-ui prop` - Enable/disable dark mode
51
 * @param {boolean} hide `common modular-ui prop` - Hide/show component
52
 * @param {boolean} shadow `common modular-ui prop` - Enable/disable shadow behind component (to better customize it)
53
 *
54
 * @example <caption>Example Toggle usage</caption>
55
 * import { render } from "react-dom";
56
 * import { Toggle } from '@cianciarusocataldo/modular-ui';
57
 *
58
 * render(<Toggle value={true} />, document.getElementById("root"));
59
 *
60
 * @see https://cianciarusocataldo.github.io/modular-ui/components/atoms/Toggle
61
 *
62
 * @author Cataldo Cianciaruso <https://github.com/CianciarusoCataldo>
63
 *
64
 * @copyright 2022 Cataldo Cianciaruso
65
 */
66 1
const Toggle: ToggleComponent = ({
67 5
  value,
68 5
  icon,
69 5
  onChange,
70 5
  className,
71 5
  shadow,
72 5
  label,
73 5
  offIcon,
74 5
  onIcon,
75 5
  ...commonProps
76
}) => {
77 5
  const toggleIcon = icon || DEFAULT_ICON;
78 5
  const iconOn = onIcon || toggleIcon;
79 5
  const iconOff = offIcon || toggleIcon;
80 5
  const iconToShow = value === true ? iconOn : iconOff;
81
82 5
  return buildBoxComponent<boolean>({
83 5
    callBack: (status, setStatus) => ({
84
      name: "modular-toggle",
85
      Component: (
86
        <div
87
          className={classNames("toggle-icon", {
88
            flip: !status,
89
            "flip-back": status,
90
          })}
91
        >
92
          {iconToShow}
93
        </div>
94
      ),
95
      commonProps,
96
      additionalProps: {
97
        onClick: () => {
98 2
          onChange && onChange(!status);
99 1
          setStatus(status);
100
        },
101
        className: classNames("container", className, {
102
          off: !status,
103
          shadowed: shadow,
104
        }),
105
      },
106
    }),
107
    defaultValue: true,
108
    value,
109
    label,
110
  });
111
};
112
113
export default Toggle;
114