From 8df5c90b7030db8f815ce48fb832ef82dc629b78 Mon Sep 17 00:00:00 2001 From: Timmy Huang Date: Fri, 5 Apr 2024 14:07:42 -0700 Subject: [PATCH] feat: Controlled InputToggle --- .../styles-dictionary/css/variables.css | 225 +++++++++--------- .../__storybook__/index.stories.tsx | 18 ++ .../__storybook__/stories/controlled.tsx | 15 ++ .../components/src/core/InputToggle/index.tsx | 14 +- .../styles-dictionary/css/variables.css | 215 +++++++++-------- 5 files changed, 262 insertions(+), 225 deletions(-) create mode 100644 packages/components/src/core/InputToggle/__storybook__/stories/controlled.tsx diff --git a/packages/components/src/common/styles-dictionary/css/variables.css b/packages/components/src/common/styles-dictionary/css/variables.css index d4226e663..e4f47f0b6 100644 --- a/packages/components/src/common/styles-dictionary/css/variables.css +++ b/packages/components/src/common/styles-dictionary/css/variables.css @@ -1,155 +1,154 @@ :root { - --sds-border-negative-default: 1px solid #dc132c; - --sds-border-base-divider: 1px solid #eaeaea; - --sds-border-base-table: 1px solid #cccccc; - --sds-border-base-disabled: 1px solid #cccccc; + --sds-border-negative-default: 1px solid #DC132C; + --sds-border-base-divider: 1px solid #EAEAEA; + --sds-border-base-table: 1px solid #CCCCCC; + --sds-border-base-disabled: 1px solid #CCCCCC; --sds-border-base-default: 1px solid #999999; --sds-border-base-black: 2px dashed #000000; --sds-border-base-hover: 2px dashed #000000; --sds-border-base-dashed: 2px dashed #999999; --sds-border-link-dashed: 1px dashed; --sds-border-link-solid: 1px solid; - --sds-border-accent-disabled: 1px solid #a6c9ff; - --sds-border-accent-default: 1px solid #0b68f8; - --sds-border-accent-hover: 1px solid #0142a4; - --sds-border-accent-dashed: 2px dashed #0b68f8; - --sds-border-info-default: 1px solid #0b68f8; - --sds-border-beta-default: 1px solid #7a41ce; - --sds-border-positive-default: 1px solid #3cb371; - --sds-border-notice-default: 1px solid #f5a623; + --sds-border-accent-disabled: 1px solid #A6C9FF; + --sds-border-accent-default: 1px solid #0B68F8; + --sds-border-accent-hover: 1px solid #0142A4; + --sds-border-accent-dashed: 2px dashed #0B68F8; + --sds-border-info-default: 1px solid #0B68F8; + --sds-border-beta-default: 1px solid #7A41CE; + --sds-border-positive-default: 1px solid #3CB371; + --sds-border-notice-default: 1px solid #F5A623; --sds-border-none: none; --sds-color-primitive-common-black: #000000; - --sds-color-primitive-common-white: #ffffff; - --sds-color-primitive-blue-100: #f5f9ff; - --sds-color-primitive-blue-200: #e9f1ff; - --sds-color-primitive-blue-300: #a6c9ff; - --sds-color-primitive-blue-400: #0b68f8; - --sds-color-primitive-blue-500: #0142a4; + --sds-color-primitive-common-white: #FFFFFF; + --sds-color-primitive-blue-100: #F5F9FF; + --sds-color-primitive-blue-200: #E9F1FF; + --sds-color-primitive-blue-300: #A6C9FF; + --sds-color-primitive-blue-400: #0B68F8; + --sds-color-primitive-blue-500: #0142A4; --sds-color-primitive-blue-600: #002660; - --sds-color-primitive-gray-100: #f8f8f8; - --sds-color-primitive-gray-200: #eaeaea; - --sds-color-primitive-gray-300: #cccccc; + --sds-color-primitive-gray-100: #F8F8F8; + --sds-color-primitive-gray-200: #EAEAEA; + --sds-color-primitive-gray-300: #CCCCCC; --sds-color-primitive-gray-400: #999999; --sds-color-primitive-gray-500: #767676; --sds-color-primitive-gray-600: #545454; - --sds-color-primitive-green-100: #ecf5f0; - --sds-color-primitive-green-200: #e6f7ed; - --sds-color-primitive-green-400: #3cb371; - --sds-color-primitive-green-500: #349a61; - --sds-color-primitive-green-600: #1c7f48; - --sds-color-primitive-purple-100: #f4f0f9; - --sds-color-primitive-purple-200: #f0ebf6; - --sds-color-primitive-purple-400: #7a41ce; - --sds-color-primitive-purple-500: #703cbe; - --sds-color-primitive-purple-600: #693bac; - --sds-color-primitive-red-100: #fef2f2; - --sds-color-primitive-red-200: #f8e8e8; - --sds-color-primitive-red-400: #dc132c; - --sds-color-primitive-red-500: #c61128; - --sds-color-primitive-red-600: #b70016; - --sds-color-primitive-yellow-100: #fcf6ec; - --sds-color-primitive-yellow-200: #fff3e1; - --sds-color-primitive-yellow-400: #f5a623; - --sds-color-primitive-yellow-500: #d8921f; + --sds-color-primitive-green-100: #ECF5F0; + --sds-color-primitive-green-200: #E6F7ED; + --sds-color-primitive-green-400: #3CB371; + --sds-color-primitive-green-500: #349A61; + --sds-color-primitive-green-600: #1C7F48; + --sds-color-primitive-purple-100: #F4F0F9; + --sds-color-primitive-purple-200: #F0EBF6; + --sds-color-primitive-purple-400: #7A41CE; + --sds-color-primitive-purple-500: #703CBE; + --sds-color-primitive-purple-600: #693BAC; + --sds-color-primitive-red-100: #FEF2F2; + --sds-color-primitive-red-200: #F8E8E8; + --sds-color-primitive-red-400: #DC132C; + --sds-color-primitive-red-500: #C61128; + --sds-color-primitive-red-600: #B70016; + --sds-color-primitive-yellow-100: #FCF6EC; + --sds-color-primitive-yellow-200: #FFF3E1; + --sds-color-primitive-yellow-400: #F5A623; + --sds-color-primitive-yellow-500: #D8921F; --sds-color-primitive-yellow-600: #946314; --sds-color-primitive-overlay-100: rgba(0, 0, 0, 0.08); --sds-color-primitive-overlay-200: rgba(0, 0, 0, 0.03); --sds-color-semantic-text-base-primary: #000000; --sds-color-semantic-text-base-secondary: #767676; - --sds-color-semantic-text-base-disabled: #cccccc; - --sds-color-semantic-text-base-on-fill: #ffffff; + --sds-color-semantic-text-base-disabled: #CCCCCC; + --sds-color-semantic-text-base-on-fill: #FFFFFF; --sds-color-semantic-text-base-on-fill-disabled: #999999; --sds-color-semantic-text-base-accent: #002660; - --sds-color-semantic-text-action-default: #0b68f8; - --sds-color-semantic-text-action-hover: #0142a4; + --sds-color-semantic-text-action-default: #0B68F8; + --sds-color-semantic-text-action-hover: #0142A4; --sds-color-semantic-text-action-pressed: #002660; - --sds-color-semantic-text-beta: #693bac; + --sds-color-semantic-text-beta: #693BAC; --sds-color-semantic-text-info: #002660; - --sds-color-semantic-text-negative: #b70016; + --sds-color-semantic-text-negative: #B70016; --sds-color-semantic-text-notice: #946314; - --sds-color-semantic-text-positive: #1c7f48; - --sds-color-semantic-component-base-fill: #ffffff; - --sds-color-semantic-component-base-fill-hover: #f8f8f8; - --sds-color-semantic-component-base-fill-pressed: #f8f8f8; - --sds-color-semantic-component-base-fill-open: #f8f8f8; + --sds-color-semantic-text-positive: #1C7F48; + --sds-color-semantic-component-base-fill: #FFFFFF; + --sds-color-semantic-component-base-fill-hover: #F8F8F8; + --sds-color-semantic-component-base-fill-pressed: #F8F8F8; + --sds-color-semantic-component-base-fill-open: #F8F8F8; --sds-color-semantic-component-base-fill-selected: #000000; - --sds-color-semantic-component-base-fill-disabled: #cccccc; + --sds-color-semantic-component-base-fill-disabled: #CCCCCC; --sds-color-semantic-component-base-on-fill-disabled: #999999; - --sds-color-semantic-component-base-surface: #ffffff; - --sds-color-semantic-component-base-surface-primary: #ffffff; - --sds-color-semantic-component-base-surface-secondary: #f8f8f8; - --sds-color-semantic-component-base-surface-tertiary: #eaeaea; - --sds-color-semantic-component-base-divider: #eaeaea; + --sds-color-semantic-component-base-surface: #FFFFFF; + --sds-color-semantic-component-base-surface-primary: #FFFFFF; + --sds-color-semantic-component-base-surface-secondary: #F8F8F8; + --sds-color-semantic-component-base-surface-tertiary: #EAEAEA; + --sds-color-semantic-component-base-divider: #EAEAEA; --sds-color-semantic-component-base-border: #999999; --sds-color-semantic-component-base-border-hover: #000000; - --sds-color-semantic-component-base-border-disabled: #cccccc; + --sds-color-semantic-component-base-border-disabled: #CCCCCC; --sds-color-semantic-component-base-icon: #767676; --sds-color-semantic-component-base-icon-hover: #000000; --sds-color-semantic-component-base-icon-pressed: #000000; - --sds-color-semantic-component-base-icon-disabled: #cccccc; - --sds-color-semantic-component-accent-fill: #0b68f8; - --sds-color-semantic-component-accent-fill-hover: #0142a4; + --sds-color-semantic-component-base-icon-disabled: #CCCCCC; + --sds-color-semantic-component-accent-fill: #0B68F8; + --sds-color-semantic-component-accent-fill-hover: #0142A4; --sds-color-semantic-component-accent-fill-pressed: #002660; - --sds-color-semantic-component-accent-fill-on-fill: #ffffff; - --sds-color-semantic-component-accent-fill-disabled: #a6c9ff; - --sds-color-semantic-component-accent-surface: #e9f1ff; - --sds-color-semantic-component-accent-border: #0b68f8; - --sds-color-semantic-component-accent-border-hover: #0142a4; - --sds-color-semantic-component-accent-border-open: #0b68f8; - --sds-color-semantic-component-accent-border-focus: #0b68f8; - --sds-color-semantic-component-accent-border-selected: #0b68f8; - --sds-color-semantic-component-accent-border-disabled: #a6c9ff; - --sds-color-semantic-component-accent-icon: #0b68f8; - --sds-color-semantic-component-beta-fill: #7a41ce; - --sds-color-semantic-component-beta-fill-hover: #703cbe; - --sds-color-semantic-component-beta-fill-pressed: #693bac; - --sds-color-semantic-component-beta-fill-on-fill: #ffffff; - --sds-color-semantic-component-beta-surface: #f0ebf6; - --sds-color-semantic-component-beta-border: #7a41ce; - --sds-color-semantic-component-beta-icon: #7a41ce; - --sds-color-semantic-component-info-fill: #0b68f8; - --sds-color-semantic-component-info-fill-hover: #0142a4; + --sds-color-semantic-component-accent-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-accent-fill-disabled: #A6C9FF; + --sds-color-semantic-component-accent-surface: #E9F1FF; + --sds-color-semantic-component-accent-border: #0B68F8; + --sds-color-semantic-component-accent-border-hover: #0142A4; + --sds-color-semantic-component-accent-border-open: #0B68F8; + --sds-color-semantic-component-accent-border-focus: #0B68F8; + --sds-color-semantic-component-accent-border-selected: #0B68F8; + --sds-color-semantic-component-accent-border-disabled: #A6C9FF; + --sds-color-semantic-component-accent-icon: #0B68F8; + --sds-color-semantic-component-beta-fill: #7A41CE; + --sds-color-semantic-component-beta-fill-hover: #703CBE; + --sds-color-semantic-component-beta-fill-pressed: #693BAC; + --sds-color-semantic-component-beta-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-beta-surface: #F0EBF6; + --sds-color-semantic-component-beta-border: #7A41CE; + --sds-color-semantic-component-beta-icon: #7A41CE; + --sds-color-semantic-component-info-fill: #0B68F8; + --sds-color-semantic-component-info-fill-hover: #0142A4; --sds-color-semantic-component-info-fill-pressed: #002660; - --sds-color-semantic-component-info-fill-on-fill: #ffffff; - --sds-color-semantic-component-info-surface: #e9f1ff; - --sds-color-semantic-component-info-border: #0b68f8; - --sds-color-semantic-component-info-icon: #0b68f8; - --sds-color-semantic-component-negative-fill: #dc132c; - --sds-color-semantic-component-negative-fill-hover: #c61128; - --sds-color-semantic-component-negative-fill-pressed: #b70016; - --sds-color-semantic-component-negative-fill-on-fill: #ffffff; - --sds-color-semantic-component-negative-surface: #f8e8e8; - --sds-color-semantic-component-negative-border: #dc132c; - --sds-color-semantic-component-negative-icon: #dc132c; + --sds-color-semantic-component-info-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-info-surface: #E9F1FF; + --sds-color-semantic-component-info-border: #0B68F8; + --sds-color-semantic-component-info-icon: #0B68F8; + --sds-color-semantic-component-negative-fill: #DC132C; + --sds-color-semantic-component-negative-fill-hover: #C61128; + --sds-color-semantic-component-negative-fill-pressed: #B70016; + --sds-color-semantic-component-negative-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-negative-surface: #F8E8E8; + --sds-color-semantic-component-negative-border: #DC132C; + --sds-color-semantic-component-negative-icon: #DC132C; --sds-color-semantic-component-neutral-fill: #999999; --sds-color-semantic-component-neutral-fill-hover: #767676; --sds-color-semantic-component-neutral-fill-pressed: #545454; - --sds-color-semantic-component-neutral-fill-on-fill: #ffffff; - --sds-color-semantic-component-neutral-surface: #eaeaea; + --sds-color-semantic-component-neutral-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-neutral-surface: #EAEAEA; --sds-color-semantic-component-neutral-border: #999999; --sds-color-semantic-component-neutral-icon: #999999; - --sds-color-semantic-component-notice-fill: #f5a623; - --sds-color-semantic-component-notice-fill-hover: #d8921f; + --sds-color-semantic-component-notice-fill: #F5A623; + --sds-color-semantic-component-notice-fill-hover: #D8921F; --sds-color-semantic-component-notice-fill-pressed: #946314; - --sds-color-semantic-component-notice-fill-on-fill: #ffffff; - --sds-color-semantic-component-notice-surface: #fff3e1; - --sds-color-semantic-component-notice-border: #f5a623; - --sds-color-semantic-component-notice-icon: #f5a623; - --sds-color-semantic-component-positive-fill: #3cb371; - --sds-color-semantic-component-positive-fill-hover: #349a61; - --sds-color-semantic-component-positive-fill-pressed: #1c7f48; - --sds-color-semantic-component-positive-fill-on-fill: #ffffff; - --sds-color-semantic-component-positive-surface: #e6f7ed; - --sds-color-semantic-component-positive-border: #3cb371; - --sds-color-semantic-component-positive-icon: #3cb371; + --sds-color-semantic-component-notice-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-notice-surface: #FFF3E1; + --sds-color-semantic-component-notice-border: #F5A623; + --sds-color-semantic-component-notice-icon: #F5A623; + --sds-color-semantic-component-positive-fill: #3CB371; + --sds-color-semantic-component-positive-fill-hover: #349A61; + --sds-color-semantic-component-positive-fill-pressed: #1C7F48; + --sds-color-semantic-component-positive-fill-on-fill: #FFFFFF; + --sds-color-semantic-component-positive-surface: #E6F7ED; + --sds-color-semantic-component-positive-border: #3CB371; + --sds-color-semantic-component-positive-icon: #3CB371; --sds-corner-l: 20px; --sds-corner-m: 4px; --sds-corner-s: 2px; --sds-corner-none: 0px; - --sds-drop-shadow-l: 0px 2px 12px 0px rgba(0, 0, 0, 0.3); - --sds-drop-shadow-m: 0px 2px 10px 0px rgba(0, 0, 0, 0.15), - 0px 2px 4px 0px rgba(0, 0, 0, 0.15); - --sds-drop-shadow-s: 0px 2px 4px 0px rgba(0, 0, 0, 0.25); + --sds-drop-shadow-l: 0.0px 2.0px 12.0px 0px rgba(0, 0, 0, 0.3); + --sds-drop-shadow-m: 0.0px 2.0px 10.0px 0px rgba(0, 0, 0, 0.15), 0.0px 2.0px 4.0px 0px rgba(0, 0, 0, 0.15); + --sds-drop-shadow-s: 0.0px 2.0px 4.0px 0px rgba(0, 0, 0, 0.25); --sds-drop-shadow-none: none; --sds-font-color: black; --sds-font-font-family-body: "Inter", sans-serif; @@ -183,13 +182,13 @@ --sds-font-body-l-600-letter-spacing: 0px; --sds-font-caps-xxxxs-600-font: 600 10px/14px "Inter", sans-serif; --sds-font-caps-xxxxs-600-letter-spacing: 0.5px; - --sds-font-caps-xxxxs-600-text-transform: uppercase; + --sds-font-caps-xxxxs-600-text-transform: uppercase; --sds-font-caps-xxxs-600-font: 600 11px/16px "Inter", sans-serif; --sds-font-caps-xxxs-600-letter-spacing: 0.5px; - --sds-font-caps-xxxs-600-text-transform: uppercase; + --sds-font-caps-xxxs-600-text-transform: uppercase; --sds-font-caps-xxs-600-font: 600 12px/18px "Inter", sans-serif; --sds-font-caps-xxs-600-letter-spacing: 0.5px; - --sds-font-caps-xxs-600-text-transform: uppercase; + --sds-font-caps-xxs-600-text-transform: uppercase; --sds-font-header-xxxs-600-font: 600 11px/16px "Inter", sans-serif; --sds-font-header-xxxs-600-letter-spacing: 0.1px; --sds-font-header-xxs-600-font: 600 12px/18px "Inter", sans-serif; diff --git a/packages/components/src/core/InputToggle/__storybook__/index.stories.tsx b/packages/components/src/core/InputToggle/__storybook__/index.stories.tsx index f6ff375cf..418a4199b 100644 --- a/packages/components/src/core/InputToggle/__storybook__/index.stories.tsx +++ b/packages/components/src/core/InputToggle/__storybook__/index.stories.tsx @@ -4,6 +4,7 @@ import { BADGE } from "@geometricpanda/storybook-addon-badges"; import { InputToggle } from "./stories/default"; import { INPUT_TOGGLE_EXCLUDED_CONTROLS } from "./constants"; import { LivePreviewDemo } from "./stories/livePreview"; +import { ControlledDemo } from "./stories/controlled"; export default { argTypes: { @@ -43,6 +44,23 @@ export const LivePreview = { render: (args: Args) => , }; +// Controlled + +export const Controlled = { + parameters: { + controls: { + exclude: INPUT_TOGGLE_EXCLUDED_CONTROLS, + }, + snapshot: { + /** + * (thuang): Take snapshot to ensure the controlled demo is working as expected. + */ + skip: false, + }, + }, + render: (args: Args) => , +}; + // Test export const Test = { diff --git a/packages/components/src/core/InputToggle/__storybook__/stories/controlled.tsx b/packages/components/src/core/InputToggle/__storybook__/stories/controlled.tsx new file mode 100644 index 000000000..18f350eb7 --- /dev/null +++ b/packages/components/src/core/InputToggle/__storybook__/stories/controlled.tsx @@ -0,0 +1,15 @@ +import { Args } from "@storybook/react"; +import { useState } from "react"; +import RawInputToggle from "src/core/InputToggle"; + +export const ControlledDemo = (props: Args): JSX.Element => { + const [isChecked, setIsChecked] = useState(true); + + function handleChange() { + setIsChecked((currentChecked) => !currentChecked); + } + + return ( + + ); +}; diff --git a/packages/components/src/core/InputToggle/index.tsx b/packages/components/src/core/InputToggle/index.tsx index 7e5cdb868..139d562e7 100644 --- a/packages/components/src/core/InputToggle/index.tsx +++ b/packages/components/src/core/InputToggle/index.tsx @@ -5,19 +5,25 @@ import { InputToggleExtraProps, Toggle } from "./style"; * @see https://mui.com/material-ui/react-switch/ */ const InputToggle = (props: InputToggleExtraProps) => { + const isControlled = props.checked !== undefined; + const [checked, setChecked] = useState(false); + const finalChecked = isControlled ? props.checked : checked; + const { offLabel = "Off", onChange, onLabel = "On", ...rest } = props; - const labelValue = checked ? onLabel : offLabel; + + const labelValue = finalChecked ? onLabel : offLabel; const handleChange = (e: React.ChangeEvent) => { - setChecked(!checked); - if (onChange) onChange(e); + setChecked((currentChecked) => !currentChecked); + + onChange?.(e); }; return (