From e28b5959815cf7cf46e72ab0e6fbb23d75f1f2ab Mon Sep 17 00:00:00 2001
From: Nathalia <64925426+nathalia-84@users.noreply.github.com>
Date: Mon, 18 Mar 2024 00:23:02 -0300
Subject: [PATCH] feat: create toggle component (#77)
* feat: Implement toggle component adhering to Material Design with animated switch and external event listeners
fix #71
* feat: Implement toggle component adhering to Material Design with animated switch and external event listeners
fix #71
* Made some adjustments according to reviews
* Write modifiers according to BEM
* Adjust Toggle function
* Solved conflicts
* Make adjustments according to reviews
* Made adjustments according to reviews, changed scss file structure
* Create setToggle function
* Adjust scss and setToggle method structure
---
src/components/Toggle/index.js | 35 ++++++++++++++++++++
src/components/Toggle/index.scss | 55 ++++++++++++++++++++++++++++++++
src/stories/Toggle.stories.js | 17 ++++++++++
src/styles/colors.scss | 1 +
4 files changed, 108 insertions(+)
create mode 100644 src/components/Toggle/index.js
create mode 100644 src/components/Toggle/index.scss
create mode 100644 src/stories/Toggle.stories.js
diff --git a/src/components/Toggle/index.js b/src/components/Toggle/index.js
new file mode 100644
index 00000000..ce759b72
--- /dev/null
+++ b/src/components/Toggle/index.js
@@ -0,0 +1,35 @@
+import './index.scss';
+import { Component, createIDFactory } from 'pet-dex-utilities';
+
+const generateID = createIDFactory('toggle');
+
+const events = ['toggle'];
+
+const html = `
+
+
+
+
+`;
+
+export default function Toggle({ checked = false } = {}) {
+ Component.call(this, { html, events });
+
+ const id = generateID();
+ this.selected.get('toggle-input').setAttribute('id', id);
+ this.selected.get('toggle-label').setAttribute('for', id);
+
+ this.setToggle(checked, false);
+
+ this.selected.get('toggle-input').addEventListener('change', () => this.emitToggle());
+}
+
+Toggle.prototype = Object.assign(Toggle.prototype, Component.prototype, {
+ emitToggle() {
+ this.emit('toggle', this.selected.get('toggle-input').checked);
+ },
+ setToggle(checked, emit = true) {
+ this.selected.get('toggle-input').checked = checked;
+ if (emit) this.emitToggle();
+ },
+});
diff --git a/src/components/Toggle/index.scss b/src/components/Toggle/index.scss
new file mode 100644
index 00000000..f87991f1
--- /dev/null
+++ b/src/components/Toggle/index.scss
@@ -0,0 +1,55 @@
+@use '~styles/colors.scss' as colors;
+
+.toggle-container {
+ display: inline-block;
+
+ position: relative;
+
+ &__input {
+ width: 0;
+ height: 0;
+
+ position: absolute;
+
+ opacity: 0;
+
+ &:checked + .toggle-container__label {
+ background-color: colors.$blue500;
+
+ &::after {
+ transform: translateX(100%);
+ }
+ }
+ }
+
+ &__label {
+ min-width: 4.4rem;
+ min-height: 2.4rem;
+
+ display: flex;
+
+ align-items: center;
+
+ background-color: colors.$gray100;
+ border-radius: 3.4rem;
+
+ transition: background-color 0.3s;
+
+ cursor: pointer;
+
+ &::after {
+ width: 41%;
+ height: 75%;
+
+ position: absolute;
+ left: 10%;
+
+ background-color: colors.$appContentColor;
+ border-radius: 50%;
+
+ transition: transform 0.3s;
+
+ content: '';
+ }
+ }
+}
diff --git a/src/stories/Toggle.stories.js b/src/stories/Toggle.stories.js
new file mode 100644
index 00000000..c08e0ed8
--- /dev/null
+++ b/src/stories/Toggle.stories.js
@@ -0,0 +1,17 @@
+import Toggle from '../components/Toggle';
+
+export default {
+ title: 'Components/Toggle',
+
+ render: (args) => {
+ const $container = document.createElement('div');
+ const toggle = new Toggle(args);
+ toggle.mount($container);
+ return $container;
+ },
+ argTypes: {
+ checked: { control: 'boolean', default: false },
+ },
+};
+
+export const Default = {};
diff --git a/src/styles/colors.scss b/src/styles/colors.scss
index d4f494ee..7ada4499 100644
--- a/src/styles/colors.scss
+++ b/src/styles/colors.scss
@@ -1,5 +1,6 @@
$appColor: rgb(0, 52, 89);
$appContentColor: rgb(255, 255, 255);
+$gray100: rgba(217, 223, 230);
$grey150: rgb(236, 239, 242);
$gray800: rgb(57, 67, 79);
$gray600: rgb(128, 139, 154);