Skip to content

Commit

Permalink
Merge pull request #113 from fortanix/mkrause/250121-biome-fixes
Browse files Browse the repository at this point in the history
Fix Biome linter errors + TS errors + accessibility violations
  • Loading branch information
mkrause authored Jan 22, 2025
2 parents 5812a06 + d37fc77 commit 1fc2eaa
Show file tree
Hide file tree
Showing 45 changed files with 329 additions and 202 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/storybook_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ name: Storybook Tests

on:
push:
branches: [ "**" ]
branches:
- "master"

jobs:
build:

runs-on: ubuntu-latest

strategy:
Expand Down
3 changes: 3 additions & 0 deletions .storybook/test-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const config: TestRunnerConfig = {
await injectAxe(page);
},
async postVisit(page, context) {
// Workaround for https://github.com/dequelabs/axe-core/issues/3426
await new Promise(resolve => setTimeout(resolve, 200));

// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);

Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@
"files.eol": "\n",
"javascript.preferences.quoteStyle": "single",
"typescript.tsdk": "node_modules/typescript/lib", // Use the TypeScript SDK from the current project
"typescript.preferences.autoImportFileExcludePatterns": [
"storybook/internal/**/*"
],
}
13 changes: 9 additions & 4 deletions biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,24 @@
},
"linter": {
"enabled": true,
"include": ["app/**/*", "src/**/*", "tests/**/*"],
"include": ["app", "src", "tests"],

"ignore": [
"node_modules",
"dist",
"src/components/tables/MultiSearch/MultiSearch.tsx", // Ignore for now (need to focus on type errors first)
"tests/installation/**/*"
],
"tests/installation"
],
"rules": {
"recommended": true,
"correctness": {
//"useExhaustiveDependencies": "off"
},
"complexity": {
"noBannedTypes": "off",
"noForEach": "off",
"useOptionalChain": "off"
"useOptionalChain": "off",
"useLiteralKeys": "off"
},
"style": {
"useImportType": "off",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"test": "npm run check:types && npm run lint:style",
"test-ui": "vitest --ui",
"coverage": "vitest run --coverage",
"test:storybook": "test-storybook --failOnConsole --browsers chromium",
"test:storybook": "test-storybook --failOnConsole --browsers chromium --maxWorkers=1",
"test:storybook-ci": "\n npx playwright install --with-deps chromium && npx concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"npm run storybook:build --quiet && npx http-server storybook-static --port 6006 --silent\" \"npx wait-on tcp:6006 && npm run test:storybook\"\n ",
"start": "npm run storybook:serve",
"prepare": "npm run build"
Expand Down
3 changes: 2 additions & 1 deletion package.json.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ const packageConfig = {

// Browser automation tests
// https://github.com/storybookjs/test-runner?tab=readme-ov-file#2-running-against-locally-built-storybooks-in-ci
'test:storybook': 'test-storybook --failOnConsole --browsers chromium', // For text only: FORCE_COLOR=false
'test:storybook': 'test-storybook --failOnConsole --browsers chromium --maxWorkers=1', // For text only: FORCE_COLOR=false
// Note: the following assumes `localhost:6006` is free, so don't run it if a dev server is already running
'test:storybook-ci': `
npx playwright install --with-deps chromium\
&& npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue"\
Expand Down
5 changes: 3 additions & 2 deletions src/components/actions/Link/Link.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import * as React from 'react';

import type { Meta, StoryObj } from '@storybook/react';
import { DummyLink } from '../../../util/storybook/StorybookLink.tsx';
import { OverflowTester } from '../../../util/storybook/OverflowTester.tsx';

import { Link } from './Link.tsx';
import { OverflowTester } from '../../../util/storybook/OverflowTester.tsx';


type LinkArgs = React.ComponentProps<typeof Link>;
Expand Down Expand Up @@ -45,7 +46,7 @@ export const Descenders: Story = {
export const Scroll: Story = {
render: (args) => (
<>
<a id="anchor" href="/" onClick={evt => { evt.preventDefault(); }}>Anchor</a>
<DummyLink id="anchor">Anchor</DummyLink>
<OverflowTester openDefault/>
<Link {...args} href="#anchor"/>
<OverflowTester openDefault/>
Expand Down
16 changes: 6 additions & 10 deletions src/components/containers/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ const ActionButton = (props: ActionButtonProps) => {
<Button trimmed
{...props}
className={cx(cl['bk-banner__action'], cl['bk-banner__action--button'], props.className)}
onClick={event => {
event.stopPropagation(); // Prevent this from triggering any click handlers on the Banner itself (e.g. toasts)
props.onClick?.(event);
}}
// Prevent clicks from triggering any click handlers on the Banner itself (e.g. to prevent toast dismissal)
onClick={event => { event.stopPropagation(); props.onClick?.(event); }}
/>
);
};
Expand All @@ -69,10 +67,8 @@ const ActionIcon = ({ tooltip, ...buttonProps }: ActionIconProps) => {
<Button trimmed
{...buttonProps}
className={cx(cl['bk-banner__action'], cl['bk-banner__action--icon'], buttonProps.className)}
onClick={event => {
event.stopPropagation(); // Prevent this from triggering any click handlers on the Banner itself (e.g. toasts)
buttonProps.onClick?.(event);
}}
// Prevent clicks from triggering any click handlers on the Banner itself (e.g. to prevent toast dismissal)
onClick={event => { event.stopPropagation(); buttonProps.onClick?.(event); }}
/>
</TooltipProvider>
);
Expand Down Expand Up @@ -153,7 +149,7 @@ export const Banner = Object.assign(
)}
>
{/* Apply `bk-theme--light` on all children (but not the box itself). */}
<header className={cx('bk-theme--light', cl['bk-banner__header'])}>
<div className={cx('bk-theme--light', cl['bk-banner__header'])}>
<div className={cx(cl['bk-banner__header__text'])}>
<strong className={cx(cl['bk-banner__title'])}>
<BannerVariantIcon variant={variant} className={cx(cl['bk-banner__title__icon'])}/>
Expand All @@ -178,7 +174,7 @@ export const Banner = Object.assign(
</ActionIcon>
}
</div>
</header>
</div>

{!compact && children &&
<article className={cx('bk-body-text', 'bk-theme--light', cl['bk-banner__message'])}>{children}</article>
Expand Down
4 changes: 3 additions & 1 deletion src/components/forms/controls/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export default {
tags: ['autodocs'],
argTypes: {
},
args: {},
args: {
'aria-label': 'Test checkbox',
},
decorators: [
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,14 @@ export const DateTimePicker = (props: DateTimePickerProps) => {
)}
>
<DatePicker
aria-label="Date input"
selected={date}
onChange={onChange}
dateFormat={dateFormat}
placeholderText={placeholderText}
/>
<TimePicker
aria-label="Time input"
time={time}
onUpdate={onTimeUpdate}
className={cx(cl['bk-date-time-picker--time-picker'])}
Expand Down
7 changes: 5 additions & 2 deletions src/components/forms/controls/Input/Input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ export const InvalidInput: Story = {
async play({ canvasElement }) {
const canvas = within(canvasElement);
const input = canvas.getByPlaceholderText('Example');
const form = input.closest('form');
if (!form) { throw new Error(`Missing <form> element`); }

await delay(100);
await userEvent.type(input, 'invalid');
await delay(100);
await userEvent.keyboard('{Enter}');
await fireEvent.submit(input.closest('form')!);
await userEvent.click(input.closest('form')!);
await fireEvent.submit(form);
await userEvent.click(form);
},
};
4 changes: 3 additions & 1 deletion src/components/forms/controls/Radio/Radio.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export default {
tags: ['autodocs'],
argTypes: {
},
args: {},
args: {
'aria-label': 'Test radio button',
},
decorators: [
Story => <form onSubmit={event => { event.preventDefault(); }}><Story/></form>,
],
Expand Down
5 changes: 2 additions & 3 deletions src/components/forms/controls/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ export const Option = (props: OptionProps) => {
cl['bk-select__option'],
propsRest.className,
)}
{...getItemProps({
onClick: () => { selectOption(option); },
})}
{...getItemProps()}
onPress={() => { selectOption(option); }}
>
{label ?? propsRest.children}
</Button>
Expand Down
1 change: 1 addition & 0 deletions src/components/forms/controls/Switch/Switch.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default {
tags: ['autodocs'],
argTypes: {},
args: {
'aria-label': 'Test switch',
defaultChecked: true,
},
decorators: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const TimePickerStory: Story = {

return (
<div>
<TimePicker time={time} onUpdate={setTime}/>
<TimePicker aria-label="Example time picker" time={time} onUpdate={setTime}/>
<p>
The selected time is: {time.hours}:{time.minutes}
</p>
Expand Down
101 changes: 57 additions & 44 deletions src/components/navigations/Stepper/Stepper.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,62 @@
.bk-stepper {
@include bk.component-base(bk-stepper);

--bk-stepper-indicator-size: #{bk.rem-from-px(28)};
display: flex;

> ol {
display: contents;
}

&.bk-stepper--horizontal {
display: flex;
gap: bk.$spacing-9;
flex-direction: row;
column-gap: bk.$spacing-9;
}

&.bk-stepper--vertical {
.bk-stepper__item {
&:not(:first-child) {
margin-top: bk.$spacing-9;
flex-direction: column;
row-gap: bk.$spacing-9;

.bk-stepper__item__circle {
&::before {
position: absolute;
content: '';
width: 0;
height: bk.$spacing-9;
top: -42px;
left: 50%;
border: 0.5px solid #{bk.$theme-stepper-border-disabled};
}
}
// Draw a line between subsequent items
li + li .bk-stepper__item__indicator {
&::before {
content: '';
position: absolute;
top: calc(-1 * bk.$spacing-9 - bk.$size-2);
left: calc(50% - bk.$size-2 / 2);
width: 0;
height: bk.$spacing-9;
border-left: bk.$size-2 solid bk.$theme-stepper-border-disabled;
}
}
}

.bk-stepper__item {
cursor: pointer;

display: flex;
align-items: center;
color: #{bk.$theme-stepper-text-disabled};
cursor: pointer;
color: bk.$theme-stepper-text-disabled;

.bk-stepper__item__circle {
display: flex;
align-items: center;
justify-content: center;
position: relative;
.bk-stepper__item__indicator {
position: relative; // Needed for the vertical line `position: absolute`
flex-shrink: 0;

margin-right: bk.$spacing-3;
border: 2px solid #{bk.$theme-stepper-border-disabled};
aspect-ratio: 1;
width: var(--bk-stepper-indicator-size);

border: bk.$size-2 solid #{bk.$theme-stepper-border-disabled};
border-radius: 50%;
width: 28px;
height: 28px;
font-weight: bk.$font-weight-bold;
font-size: bk.$font-size-m;
}

.bk-stepper__item__circle__icon {
font-size: bk.$font-size-xs;

display: grid;
place-content: center;

.bk-stepper__item__indicator__icon {
font-size: bk.$font-size-xs;
}
}

.bk-stepper__item__title {
Expand All @@ -65,22 +74,26 @@
margin-left: bk.$spacing-2;
font-size: bk.$font-size-xs;
}

&[aria-selected="true"] {
color: #{bk.$theme-stepper-text-selected};

.bk-stepper__item__circle {
border-color: #{bk.$theme-stepper-border-default};
background-color: #{bk.$theme-stepper-background-default};
color: #{bk.$theme-stepper-text-selected-number};
}
}
}

// Any steps we've already visited
.bk-stepper__item--checked {
color: bk.$theme-stepper-text-selected;

&.bk-stepper__item--checked {
color: #{bk.$theme-stepper-text-selected};
.bk-stepper__item__indicator {
border-color: bk.$theme-stepper-border-default;
}
}

// The currently active step
[aria-current="true"] {
.bk-stepper__item {
color: bk.$theme-stepper-text-selected;

.bk-stepper__item__circle {
border-color: #{bk.$theme-stepper-border-default};
.bk-stepper__item__indicator {
border-color: bk.$theme-stepper-border-default;
background-color: bk.$theme-stepper-background-default;
color: bk.$theme-stepper-text-selected-number;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/navigations/Stepper/Stepper.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Meta, StoryObj } from '@storybook/react';

import * as React from 'react';

import { Stepper, Step } from './Stepper.tsx';
import { type Step, Stepper } from './Stepper.tsx';


type StepperArgs = React.ComponentProps<typeof Stepper>;
Expand All @@ -27,7 +27,7 @@ export default {
const defaultSteps: Step[] = [1,2,3,4].map(index => {
return {
stepKey: `${index}`,
title: `Step${index}`,
title: `Step ${index}`,
isOptional: index === 4,
};
});
Expand Down
Loading

0 comments on commit 1fc2eaa

Please sign in to comment.