Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NO JIRA][BpkSwitch]: Remove label and just ship switch #3582

Merged
merged 6 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions examples/bpk-component-aria-live/examples.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@
flex: 0.5;
}

&__switch {
flex: 0.3;
&__switch-wrapper {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
align-items: center;
flex: 0.2;
}

&__chip {
Expand Down
49 changes: 27 additions & 22 deletions examples/bpk-component-aria-live/examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { BpkCode } from '../../packages/bpk-component-code';
import BpkFieldset from '../../packages/bpk-component-fieldset';
// @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
import BpkSelect from '../../packages/bpk-component-select';
// @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
import BpkSwitch from '../../packages/bpk-component-switch';
import { cssModules } from '../../packages/bpk-react-utils';

Expand Down Expand Up @@ -78,7 +77,7 @@ const AriaLiveDemo = ({
);

class SelectExample<SProps extends {}> extends Component<
SProps,
SProps,
{ destination: string; direct: boolean }
> {
constructor(props: SProps) {
Expand Down Expand Up @@ -131,12 +130,16 @@ SProps,
<option value="Panjin">Panjin</option>
</BpkSelect>
</BpkFieldset>
<BpkSwitch
className={getClassName('bpk-storybook-aria-live-demo__switch')}
label="Direct flights only"
checked={direct}
onChange={this.toggleDirectness}
/>
<div
className={getClassName('bpk-storybook-aria-live-demo__switch-wrapper')}
>
<span>Direct flights only</span>
<BpkSwitch
ariaLabel="Direct flights only"
checked={direct}
onChange={this.toggleDirectness}
/>
</div>
</div>
</div>
<AriaLiveDemo
Expand Down Expand Up @@ -186,7 +189,7 @@ class ChipsExample<CProps extends {}> extends Component<

id = 'aria-live-chips-example';

toggleCategory = (category: "Flights" | "Hotels" | "Car hire") => {
toggleCategory = (category: 'Flights' | 'Hotels' | 'Car hire') => {
this.setState((prevState) => {
const nextState = prevState;
nextState.categories[category] = !prevState.categories[category];
Expand All @@ -213,19 +216,21 @@ class ChipsExample<CProps extends {}> extends Component<
<BpkCode>aria-controls=&quot;{this.id}&quot;</BpkCode> to link it to
the ARIA live region below with the same ID.
</p>
{(Object.keys(categories) as Array<keyof typeof categories>).map((category) => (
<BpkChip
className={getClassName('bpk-storybook-aria-live-demo__chip')}
aria-controls={this.id}
selected={categories[category]}
accessibilityLabel={category}
onClick={() => {
this.toggleCategory(category);
}}
>
{category}
</BpkChip>
))}
{(Object.keys(categories) as Array<keyof typeof categories>).map(
(category) => (
<BpkChip
className={getClassName('bpk-storybook-aria-live-demo__chip')}
aria-controls={this.id}
selected={categories[category]}
accessibilityLabel={category}
onClick={() => {
this.toggleCategory(category);
}}
>
{category}
</BpkChip>
),
)}
</div>
<AriaLiveDemo
id={this.id}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* @flow strict */

import BpkSwitch from '../../packages/bpk-component-switch';

const DefaultExample = ({ ...rest }: {}) => (
<BpkSwitch {...rest} label="Backpack" />
type Props = {
checked?: boolean,
[rest: string]: any
};

const DefaultExample = ({ ...rest }: Props) => (
<BpkSwitch {...rest} ariaLabel="Activate Backpack" />
);

const SmallExample = ({ ...rest }: {}) => (
<BpkSwitch small {...rest} label="Backpack" />
const SmallExample = ({ ...rest }: Props) => (
<BpkSwitch small {...rest} ariaLabel="Activate Backpack" />
);

// Putting the switch in a container which we know is too small to contain the label and the switch
const ReducedSpaceExample = ({ ...rest }: {}) => (
const ReducedSpaceExample = ({ ...rest }: Props) => (
<div style={{ width: "4rem" }}>
<BpkSwitch {...rest} label="Backpack" />
<BpkSwitch {...rest} label="Backpack" small />
<BpkSwitch {...rest} ariaLabel="Activate Backpack" />
<BpkSwitch {...rest} ariaLabel="Activate Backpack" small />
</div>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ export const Small = SmallExample;
export const ReducedSpace = ReducedSpaceExample;

export const VisualTest = MixedExample;
export const VisualTestWithZoom = VisualTest.bind({});
VisualTestWithZoom.args = {
zoomEnabled: true
};
export const VisualTestWithZoom = {
render: VisualTest,
args: {
zoomEnabled: true
}
}
53 changes: 0 additions & 53 deletions packages/bpk-component-switch/src/BpkSwitch-test.js

This file was deleted.

59 changes: 59 additions & 0 deletions packages/bpk-component-switch/src/BpkSwitch-test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Backpack - Skyscanner's Design System
*
* Copyright 2016 Skyscanner Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { render, screen } from '@testing-library/react';

import BpkSwitch from './BpkSwitch';

describe('BpkSwitch', () => {
it('should render correctly', () => {
const { container } = render(<BpkSwitch ariaLabel="Switch" />);
expect(screen.getByRole('checkbox')).toBeInTheDocument();
expect(screen.getByRole('checkbox')).toHaveAttribute('aria-label', 'Switch');
expect(container.querySelectorAll(".bpk-switch__switch")[0].className).toBe("bpk-switch__switch");
});

it('should render small switch', () => {
const { container } = render(<BpkSwitch ariaLabel="Switch" small />);
expect(screen.getByRole('checkbox')).toBeInTheDocument();
expect(container.querySelectorAll(".bpk-switch__checkbox")[0].className).toBe("bpk-switch__checkbox");
expect(container.querySelectorAll(".bpk-switch__switch--small")[0].className).toBe("bpk-switch__switch bpk-switch__switch--small");
});

it('should render correctly when checked', () => {
const { container } = render(
<BpkSwitch checked onChange={() => {}} ariaLabel="Switch" />,
);
expect(screen.getByRole('checkbox')).toBeInTheDocument();
expect(container.querySelectorAll(".bpk-switch__checkbox")[0]).toHaveAttribute('checked');
});

it('should support custom class names', () => {
const { container } = render(
<BpkSwitch ariaLabel="Switch" className="custom-classname" />,
);
expect(screen.getByRole('checkbox')).toBeInTheDocument();
expect(container.querySelectorAll(".custom-classname")[0]).toBeInTheDocument();
});

it('should support arbitrary props', () => {
render(<BpkSwitch ariaLabel="Switch" data-testid="my-switch" />);
expect(screen.getByRole('checkbox')).toBeInTheDocument();
expect(screen.getAllByTestId('my-switch')).toHaveLength(1);
});
});
6 changes: 0 additions & 6 deletions packages/bpk-component-switch/src/BpkSwitch.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,6 @@ $border-width: tokens.$bpk-one-pixel-rem * 2;
}
}

&__label {
/* stylelint-disable backpack/use-typography-styles */
line-height: $height;
margin-inline-end: tokens.bpk-spacing-md();
}

// The 'track'.
&__switch {
position: relative;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* @flow strict */

import PropTypes from 'prop-types';
import type { Node } from 'react';

import { cssModules } from '../../bpk-react-utils';

Expand All @@ -27,44 +23,34 @@ import STYLES from './BpkSwitch.module.scss';
const getClassName = cssModules(STYLES);

export type Props = {
label: Node,
className: ?string,
ariaLabel: string;
className?: string | null;
small?: boolean;
[rest: string]: any;
};

const BpkSwitch = (props: Props) => {
const { className, label, small, ...rest } = props;

const BpkSwitch = ({
ariaLabel,
className = null,
small = false,
...rest
}: Props) => {
const switchClassNames = getClassName(
'bpk-switch__switch',
small && 'bpk-switch__switch--small',
);

return (
<label className={getClassName('bpk-switch', className)}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this still need to be wrapped in a label?

Copy link
Member Author

@olliecurtis olliecurtis Aug 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking a look yes it still needs to be a label so that the component is still fully selectable and operational as a switch with a Assistive Tech, otherwise looks like this and when even using the component without an AT then becomes unclickable

Screenshot 2024-08-12 at 13 16 45

{/* $FlowFixMe[cannot-spread-inexact] - inexact rest. See 'decisions/flowfixme.md'. */}
<input
type="checkbox"
className={getClassName('bpk-switch__checkbox')}
aria-label={label}
aria-label={ariaLabel}
{...rest}
/>
<span aria-hidden className={getClassName('bpk-switch__label')}>
{label}
</span>
<span aria-hidden className={switchClassNames} />
</label>
);
};

BpkSwitch.propTypes = {
label: PropTypes.node.isRequired,
className: PropTypes.string,
small: PropTypes.bool,
};

BpkSwitch.defaultProps = {
className: null,
small: false,
};

export default BpkSwitch;
Loading
Loading