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);