Skip to content

Commit

Permalink
feat: Add StudioList component (#13819)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasEng authored Oct 20, 2024
1 parent 6013fdd commit 74bf97f
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { RenderResult } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import type { ForwardedRef } from 'react';
import React from 'react';
import type { StudioListRootProps } from './StudioList';
import { StudioList } from './StudioList';
import { testRootClassNameAppending } from '../../test-utils/testRootClassNameAppending';
import { testRefForwarding } from '../../test-utils/testRefForwarding';
import { testCustomAttributes } from '../../test-utils/testCustomAttributes';

type TestCase = {
renderList: (props?: StudioListRootProps, ref?: ForwardedRef<HTMLDivElement>) => RenderResult;
};

const testCases: Record<string, TestCase> = {
UnorderedList: {
renderList: renderUnorderedList,
},
OrderedList: {
renderList: renderOrderedList,
},
};

describe.each(Object.keys(testCases))('%s', (listType) => {
const { renderList } = testCases[listType];

it('Renders a list', () => {
renderList();
expect(screen.getByRole('list')).toBeInTheDocument();
});

it('Renders list items', () => {
renderList();
expect(screen.getAllByRole('listitem')).toHaveLength(3);
});

it('Applies class name to the root', () => {
testRootClassNameAppending((className) => renderList({ className }));
});

it('Forwards the ref to the root element if given', () => {
testRefForwarding<HTMLDivElement>((ref) => renderList({}, ref));
});

it('Appends custom attributes to the root element', () => {
testCustomAttributes<HTMLDivElement>(renderList);
});
});

function renderUnorderedList(
props: StudioListRootProps = {},
ref?: ForwardedRef<HTMLDivElement>,
): RenderResult {
return render(
<StudioList.Root {...props} ref={ref}>
<StudioList.Unordered>
<ListItems />
</StudioList.Unordered>
</StudioList.Root>,
);
}

function renderOrderedList(
props: StudioListRootProps = {},
ref?: ForwardedRef<HTMLDivElement>,
): RenderResult {
return render(
<StudioList.Root {...props} ref={ref}>
<StudioList.Ordered>
<ListItems />
</StudioList.Ordered>
</StudioList.Root>,
);
}

function ListItems() {
return (
<>
<StudioList.Item>Item 1</StudioList.Item>
<StudioList.Item>Item 2</StudioList.Item>
<StudioList.Item>Item 3</StudioList.Item>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type {
ListHeadingProps,
ListItemProps,
ListUnorderedProps,
} from '@digdir/designsystemet-react';
import { List } from '@digdir/designsystemet-react';
import { StudioListRoot } from './StudioListRoot';

type StudioListComponent = typeof List;

export const StudioList: StudioListComponent = {
...List,
Root: StudioListRoot,
};

StudioList.Root.displayName = 'StudioList.Root';
StudioList.Item.displayName = 'StudioList.Item';
StudioList.Heading.displayName = 'StudioList.Heading';
StudioList.Ordered.displayName = 'StudioList.OrderedList';
StudioList.Unordered.displayName = 'StudioList.UnorderedList';

export type { StudioListRootProps } from './StudioListRoot';

export type StudioListItemProps = ListItemProps;
export type StudioListUnorderedProps = ListUnorderedProps;
export type StudioListOrderedProps = ListUnorderedProps;
export type StudioListHeadingProps = ListHeadingProps;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import type { Meta, StoryFn } from '@storybook/react';
import { StudioList } from './StudioList';

type Story = StoryFn<typeof StudioList.Root>;

const meta: Meta = {
title: 'Components/StudioList/Ordered',
component: StudioList.Root,
argTypes: {
size: {
control: 'select',
options: ['sm', 'md', 'lg'],
},
},
};
export const Preview: Story = (args): React.ReactElement => <StudioList.Root {...args} />;

Preview.args = {
children: (
<>
<StudioList.Heading>Lorem ipsum</StudioList.Heading>
<StudioList.Ordered>
<StudioList.Item>Nunc cursus turpis eget ligula blandit lobortis.</StudioList.Item>
<StudioList.Item>Donec et mauris id sapien laoreet placerat.</StudioList.Item>
<StudioList.Item>
Proin quam tortor, ullamcorper at justo nec, iaculis dapibus nisi.
</StudioList.Item>
</StudioList.Ordered>
</>
),
size: 'sm',
};
export default meta;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { ListProps } from '@digdir/designsystemet-react';
import { List } from '@digdir/designsystemet-react';
import React, { forwardRef } from 'react';

export type StudioListRootProps = ListProps;

export const StudioListRoot = forwardRef<HTMLDivElement, StudioListRootProps>((props, ref) => {
return <List.Root size='sm' {...props} ref={ref} />;
});

StudioListRoot.displayName = 'StudioList.Root';
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import type { Meta, StoryFn } from '@storybook/react';
import { StudioList } from './StudioList';

type Story = StoryFn<typeof StudioList.Root>;

const meta: Meta = {
title: 'Components/StudioList/Unordered',
component: StudioList.Root,
argTypes: {
size: {
control: 'select',
options: ['sm', 'md', 'lg'],
},
},
};
export const Preview: Story = (args): React.ReactElement => <StudioList.Root {...args} />;

Preview.args = {
children: (
<>
<StudioList.Heading>Lorem ipsum</StudioList.Heading>
<StudioList.Unordered>
<StudioList.Item>
Vivamus magna turpis, ornare in lectus eget, lacinia vehicula mauris.
</StudioList.Item>
<StudioList.Item>In hac habitasse platea dictumst.</StudioList.Item>
<StudioList.Item>Aliquam luctus mi erat, quis mattis sem aliquam eu.</StudioList.Item>
</StudioList.Unordered>
</>
),
size: 'sm',
};
export default meta;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './StudioList';
1 change: 1 addition & 0 deletions frontend/libs/studio-components/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export * from './StudioInputTable';
export * from './StudioLabelAsParagraph';
export * from './StudioLabelWrapper';
export * from './StudioLink';
export * from './StudioList';
export * from './StudioModal';
export * from './StudioNativeSelect';
export * from './StudioNotFoundPage';
Expand Down

0 comments on commit 74bf97f

Please sign in to comment.