Skip to content

Commit

Permalink
using bento css. added different stories and mixins.
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeiroguilherme committed Dec 18, 2024
1 parent 3785756 commit 3970ca5
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 69 deletions.
193 changes: 144 additions & 49 deletions packages/lib/src/components/internal/Toggle/Toggle.scss
Original file line number Diff line number Diff line change
@@ -1,64 +1,159 @@
@use 'styles/mixins';
@import 'styles/variable-generator';

.adyen-checkout-toggle {
$component-root: &;
$label-padding: token(toggle-label-padding);

color: inherit;
cursor: pointer;
display: flex;
user-select: none;
width: auto;
}

.adyen-checkout-toggle--label-first {
align-items: flex-start;
flex-direction: row-reverse;
justify-content: flex-end;
}
@include mixins.box-sizing-setter(true);

.adyen-checkout-toggle__input {
cursor: inherit;
opacity: 0;
position: absolute;
}
&--disabled {
cursor: not-allowed;
display: flex;
}

.adyen-checkout-toggle__input:checked+.adyen-checkout-toggle__track {
background-color: #00112c;
border: 0;
padding: 2px;
}
&--readonly {
pointer-events: none;
}

.adyen-checkout-toggle__track {
align-items: center;
background-color: #fff;
border: 1px solid #8d95a3;
border-radius: 12px;
display: flex;
height: 20px;
min-width: 36px;
padding: 2px 4px;
position: relative;
}
&--label-first {
align-items: flex-start;
flex-direction: row-reverse;
justify-content: flex-end;
}

.adyen-checkout-toggle__handle {
align-content: center;
background-color: #00112c;
border-radius: 12px;
color: #00112c;
display: inline-flex;
height: 12px;
justify-content: center;
transition: transform .15s cubic-bezier(.2, 0, .4, .9);
width: 12px;
}
&__input {
cursor: inherit;
opacity: 0;
position: absolute;
}

.adyen-checkout-toggle__input:checked+* .adyen-checkout-toggle__handle {
background-color: #fff;
height: 16px;
transform: translate(100%);
width: 16px;
}
&__track {
align-items: center;
background-color: token(toggle-track-background-color);
border: token(toggle-track-border);
border-radius: token(toggle-track-border-radius);
display: flex;
height: token(toggle-track-height);
min-width: token(toggle-track-width);
padding: token(toggle-track-padding);
position: relative;

#{$component-root}__input:focus-visible + & {
@include mixins.b-focus-ring;
}

#{$component-root}__input:hover:enabled + & {
background-color: token(toggle-track-hover-background-color);
border-color: token(toggle-track-hover-border-color);
}

#{$component-root}__input:active:enabled + & {
background-color: token(toggle-track-active-background-color);
border-color: token(toggle-track-active-border-color);
}

#{$component-root}__input:disabled + & {
background-color: token(toggle-track-disabled-background-color);
border-color: token(toggle-track-disabled-border-color);
cursor: not-allowed;

path {
fill: #8d95a3
}
}

#{$component-root}--readonly #{$component-root}__input + & {
background-color: token(toggle-track-readonly-background-color);
border-color: token(toggle-track-readonly-border-color);
}

#{$component-root}__input:checked + & {
background-color: token(toggle-track-toggled-background-color);
border: token(toggle-track-toggled-border);
padding: token(toggle-track-toggled-padding);
}

#{$component-root}__input:checked:hover:enabled + & {
background-color: token(toggle-track-toggled-hover-background-color);
}

#{$component-root}__input:checked:active:enabled + & {
background-color: token(toggle-track-toggled-active-background-color);
}

#{$component-root}__input:checked:disabled + & {
background-color: token(toggle-track-toggled-disabled-background-color);
}

#{$component-root}--readonly #{$component-root}__input:checked + & {
background-color: token(toggle-track-toggled-readonly-background-color);
}
}

&__handle {
align-content: center;
background-color: token(toggle-handle-background-color);
border-radius: token(toggle-handle-border-radius);
color: token(toggle-handle-toggled-color);
display: inline-flex;
height: token(toggle-handle-height);
justify-content: center;
transition: token(toggle-handle-transition);
width: token(toggle-handle-width);

#{$component-root}__input:disabled + * & {
background-color: token(toggle-handle-disabled-background-color);
cursor: not-allowed;
}

#{$component-root}__input:checked + * & {
background-color: token(toggle-handle-toggled-background-color);
height: token(toggle-handle-toggled-height);
transform: translateX(100%);
width: token(toggle-handle-toggled-width);
}

#{$component-root}__input:checked:disabled + * & {
background-color: token(toggle-handle-toggled-disabled-background-color);
color: token(toggle-handle-toggled-disabled-color);
cursor: not-allowed;
}

#{$component-root}--readonly #{$component-root}__input:checked + * & {
background-color: token(toggle-handle-toggled-readonly-background-color);
}
}

&__label-container {
display: flex;
flex-direction: column;
padding-left: $label-padding;

@include mixins.adyen-checkout-text-body;

#{$component-root}--label-first > & {
padding-left: 0;
padding-right: $label-padding;
}
}

&__label {
vertical-align: baseline;

@include mixins.adyen-checkout-text-body;
}

.adyen-checkout-toggle__label-text {
font-size: 14px;
font-weight: 400;
letter-spacing: 0;
line-height: 20px;
&__description {
color: token(toggle-description-color);
padding-top: token(toggle-description-padding);

@include mixins.adyen-checkout-text-body;
}
}
32 changes: 32 additions & 0 deletions packages/lib/src/components/internal/Toggle/Toggle.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { h } from 'preact';
import { render, screen } from '@testing-library/preact';
import userEvent from '@testing-library/user-event';
import Toggle from './Toggle';

test('should emit correct values', async () => {
const user = userEvent.setup();
const onChangeMock = jest.fn();

render(<Toggle checked={false} onChange={onChangeMock} />);

await user.click(screen.getByRole('switch'));
expect(onChangeMock.mock.calls[0][0]).toBe(true);

await user.click(screen.getByRole('switch'));
expect(onChangeMock.mock.calls[1][0]).toBe(false);
});

test('should render as readonly', () => {
render(<Toggle checked={false} readonly />);
expect(screen.getByRole('switch').getAttribute('aria-readonly')).toBe('true');
});

test('should render as disabled', () => {
render(<Toggle checked={false} disabled />);
expect(screen.getByRole('switch')).toBeDisabled();
});

test('should render description', () => {
render(<Toggle checked={false} label="Save details" description="Save all details" />);
expect(screen.getByText('Save all details')).toBeTruthy();
});
46 changes: 30 additions & 16 deletions packages/lib/src/components/internal/Toggle/Toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
import { h } from 'preact';
import { useCallback, useMemo } from 'preact/hooks';
import cx from 'classnames';
import uuid from '../../../utils/uuid';
import './Toggle.scss';

interface ToggleProps {
label?: string;
labelPosition?: 'before' | 'after';
ariaLabel?: string;
description?: string;
checked: boolean;
onChange?: () => void;
disabled?: boolean;
readonly?: boolean;
onChange?(checked: boolean): void;
}

const Toggle = ({ label, labelPosition, checked, disabled, readonly, onChange }: ToggleProps) => {
const Toggle = ({ label, labelPosition = 'after', ariaLabel, description, checked, disabled = false, readonly = false, onChange }: ToggleProps) => {
const descriptionId = useMemo(() => (description ? `toggle-description-${uuid()}` : null), [description]);
const computedAriaLabel = useMemo(() => ariaLabel ?? label, [ariaLabel, label]);

const conditionalClasses = cx({
'adyen-checkout-toggle--label-first': labelPosition === 'before',
'adyen-checkout-toggle--disabled': disabled,
'adyen-checkout-toggle--readonly': readonly
});

const onInputChange = useCallback(
(event: Event) => {
onChange((event.target as HTMLInputElement).checked);
},
[onChange]
);

return (
<label className={`adyen-checkout-toggle ${conditionalClasses}`}>
<input
disabled={disabled}
checked={checked}
aria-label={label}
onChange={onChange}
aria-describedby={''}
onChange={onInputChange}
aria-label={computedAriaLabel}
aria-readonly={readonly}
aria-describedby={descriptionId}
role="switch"
type="checkbox"
className="adyen-checkout-toggle__input"
Expand All @@ -33,15 +49,7 @@ const Toggle = ({ label, labelPosition, checked, disabled, readonly, onChange }:
<span aria-hidden={true} className="adyen-checkout-toggle__track">
<span className="adyen-checkout-toggle__handle">
{checked && (
<svg
data-v-dd0561f5=""
role="img"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="none"
className="ui-assets-icons-16"
>
<svg role="img" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none">
<path
fill="#00112C"
d="M12.0608 6.00011L11.0001 4.93945L7.00011 8.93945L5.00011 6.93945L3.93945 8.00011L7.00011 11.0608L12.0608 6.00011Z"
Expand All @@ -53,8 +61,14 @@ const Toggle = ({ label, labelPosition, checked, disabled, readonly, onChange }:

{label && (
<span className="adyen-checkout-toggle__label-container">
<span className="adyen-checkout-toggle__label-text">{label}</span>
<span className="adyen-checkout-toggle__description"></span>
<span className="adyen-checkout-toggle__label-text" data-testid="inner-label">
{label}
</span>
{description && (
<span data-testid="description" className="adyen-checkout-toggle__description" id={descriptionId}>
{description}
</span>
)}
</span>
)}
</label>
Expand Down
8 changes: 7 additions & 1 deletion packages/lib/src/styles/mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ $adyen-checkout-media-query-l-min: 1024px;
line-height: token(text-title-line-height);
}

@mixin adyen-checkout-text-body {
font-size: token(text-body-font-size);
font-weight: token(text-body-font-weight);
line-height: token(text-body-line-height);
}

@mixin adyen-checkout-text-caption {
font-size: token(text-caption-font-size);
font-weight: token(text-caption-font-weight);
Expand Down Expand Up @@ -133,4 +139,4 @@ $adyen-checkout-media-query-l-min: 1024px;
margin: -1px;
padding: 0;
position: absolute;
}
}
5 changes: 3 additions & 2 deletions packages/lib/src/styles/variable-generator.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@import '~@adyen/bento-design-tokens/dist/scss-map/bento/aliases';
@import '~@adyen/bento-design-tokens/dist/scss-map/bento/definitions';
@import '~@adyen/bento-design-tokens/dist/scss-map/bento/components';

@function adyen-sdk-generate-css-variables($maps...) {
$adyen-output-map: ();
Expand All @@ -18,9 +19,9 @@
$adyen-tokens-map: ();

@if $generate-css-var {
$adyen-tokens-map: adyen-sdk-generate-css-variables($color, $text, $focus-ring, $border, $spacer, $shadow);
$adyen-tokens-map: adyen-sdk-generate-css-variables($color, $text, $focus-ring, $border, $spacer, $shadow, $toggle);
} @else {
$adyen-tokens-map: map-merge($color, $text, $focus-ring, $border, $spacer, $shadow)
$adyen-tokens-map: map-merge($color, $text, $focus-ring, $border, $spacer, $shadow, $toggle)
}

@return map-get($adyen-tokens-map, '#{$token}');
Expand Down
Loading

0 comments on commit 3970ca5

Please sign in to comment.