Skip to content
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
16 changes: 16 additions & 0 deletions .storybook/ignoreNotFoundExportWarningsPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Replaces the unmaintained `ignore-not-found-export-webpack-plugin`, whose only functionality
// is filtering out "export was not found" warnings — its `require('webpack/lib/ModuleDependencyWarning')`
// deep-import breaks on newer webpack 5 versions, where that module moved under `lib/errors/`.
// Matching on `constructor.name` avoids importing the class at all.
const EXPORT_NOT_FOUND = /export.*was not found in/;

module.exports = class IgnoreNotFoundExportWarningsPlugin {
apply(compiler) {
compiler.hooks.done.tap('IgnoreNotFoundExportWarningsPlugin', stats => {
stats.compilation.warnings = stats.compilation.warnings.filter(
warning =>
!(warning.constructor.name === 'ModuleDependencyWarning' && EXPORT_NOT_FOUND.test(warning.message))
);
});
}
};
4 changes: 2 additions & 2 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const path = require('path');
const IgnoreNotFoundExportPlugin = require('ignore-not-found-export-webpack-plugin');
const IgnoreNotFoundExportWarningsPlugin = require('./ignoreNotFoundExportWarningsPlugin');

module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
Expand Down Expand Up @@ -28,7 +28,7 @@ module.exports = {
}
]
},
plugins: [...config.plugins, new IgnoreNotFoundExportPlugin()]
plugins: [...config.plugins, new IgnoreNotFoundExportWarningsPlugin()]
}),
framework: {
name: '@storybook/react-webpack5',
Expand Down
14 changes: 0 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@
"globals": "^17.0.0",
"husky": "^9.1.7",
"identity-obj-proxy": "^3.0.0",
"ignore-not-found-export-webpack-plugin": "^1.0.2",
"jest": "^30.2.0",
"jest-environment-jsdom": "^30.2.0",
"jest-matchmedia-mock": "^1.1.0",
Expand Down
4 changes: 4 additions & 0 deletions src/components/Constrain/Constrain.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
margin: 0 auto;
max-width: map.get(om.$breakpoints, xl);

&--wide {
width: 95%;
}

@include om.breakpoint(md, $prop: max-width) {
width: 100%;
padding: om.spacing(0, 6);
Expand Down
16 changes: 13 additions & 3 deletions src/components/Constrain/Constrain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ import React from 'react';
import classNames from 'classnames';
import './Constrain.scss';

export type ConstrainProps = React.HTMLAttributes<HTMLDivElement>;
export type ConstrainSize = 'medium' | 'wide';

export const Constrain: React.FC<ConstrainProps> = ({ className, children, ...rest }) => (
<div className={classNames('Constrain', className)} {...rest}>
export type ConstrainProps = React.HTMLAttributes<HTMLDivElement> & { size?: ConstrainSize };

export const Constrain: React.FC<ConstrainProps> = ({
className,
children,
size = 'medium',
...rest
}) => (
<div
className={classNames('Constrain', { 'Constrain--wide': size === 'wide' }, className)}
{...rest}
>
{children}
</div>
);
22 changes: 22 additions & 0 deletions src/components/Drawer/Drawer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@use '~@moda/om';

.Drawer {
--drawer-width: 15rem;

flex: 0 0 auto;
width: 0;
overflow: hidden;
visibility: hidden;
transition: width 250ms ease, visibility 0s 250ms;

&--open {
width: var(--drawer-width);
visibility: visible;
transition: width 250ms ease, visibility 0s;
}

&__content {
width: var(--drawer-width);
height: 100%;
}
}
26 changes: 26 additions & 0 deletions src/components/Drawer/Drawer.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useState } from 'react';
import { Button } from '../Button';
import { Text } from '../Text';
import { Drawer } from './Drawer';

export default { title: 'Components/Drawer' };

export const Default = () => {
const [open, setOpen] = useState(false);

return (
<div style={{ display: 'flex' }}>
<Drawer open={open} style={{ backgroundColor: 'lightgray' }}>
<Text>Drawer content</Text>
</Drawer>

<div style={{ flex: 1, padding: '1rem' }}>
<Button onClick={() => setOpen(open => !open)}>{open ? 'Close' : 'Open'} drawer</Button>
<Text>
The drawer pushes this content over when open, rather than overlaying it — no backdrop, no
focus trap.
</Text>
</div>
</div>
);
};
27 changes: 27 additions & 0 deletions src/components/Drawer/Drawer.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { render, screen } from '@testing-library/react';

import { Drawer } from './Drawer';

describe('Drawer', () => {
it('renders its children', () => {
render(<Drawer open>Hello</Drawer>);
expect(screen.getByText('Hello')).toBeVisible();
});

it('toggles the open class based on the open prop', () => {
const { rerender } = render(
<Drawer open={false} data-testid='drawer'>
Hello
</Drawer>
);
expect(screen.getByTestId('drawer')).not.toHaveClass('Drawer--open');

rerender(
<Drawer open data-testid='drawer'>
Hello
</Drawer>
);
expect(screen.getByTestId('drawer')).toHaveClass('Drawer--open');
});
Comment thread
Copilot marked this conversation as resolved.
});
13 changes: 13 additions & 0 deletions src/components/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import classNames from 'classnames';
import './Drawer.scss';

export type DrawerProps = React.HTMLAttributes<HTMLDivElement> & {
open: boolean;
};

export const Drawer: React.FC<DrawerProps> = ({ className, open, children, ...rest }) => (
<div className={classNames('Drawer', { 'Drawer--open': open }, className)} {...rest}>
<div className='Drawer__content'>{children}</div>
</div>
);
1 change: 1 addition & 0 deletions src/components/Drawer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Drawer';
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export * from './CreditCardNumberInput';
export * from './DefinitionList';
export * from './Dialog';
export * from './Divider';
export * from './Drawer';
export * from './Expandable';
export * from './Field';
export * from './Label';
Expand Down