Skip to content

Commit 8ed0c1e

Browse files
authored
IBX-10573: Shared base for form control list components (#24)
1 parent 0e1569a commit 8ed0c1e

File tree

6 files changed

+168
-0
lines changed

6 files changed

+168
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@use 'functions' as *;
2+
3+
.ids-choice-inputs-list {
4+
$self: &;
5+
6+
.ids-form-control {
7+
&__label-wrapper {
8+
margin-bottom: calculateRem(4px);
9+
}
10+
11+
&__helper-text-wrapper {
12+
margin-top: calculateRem(4px);
13+
}
14+
}
15+
16+
&__items {
17+
display: flex;
18+
flex-direction: column;
19+
20+
& > * {
21+
padding: calculateRem(4px) calculateRem(8px);
22+
}
23+
}
24+
25+
&--horizontal {
26+
#{$self}__items {
27+
flex-direction: row;
28+
flex-wrap: wrap;
29+
gap: calculateRem(12px);
30+
31+
& > * {
32+
padding: calculateRem(4px) 0;
33+
}
34+
}
35+
}
36+
}

packages/assets/src/scss/styles.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
@use 'helper-text';
1111
@use 'icons';
1212
@use 'input';
13+
@use 'inputs-list';
1314
@use 'label';
1415

1516
@use 'inputs/checkbox';
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React from 'react';
2+
3+
import type { Meta, StoryObj } from '@storybook/react';
4+
5+
import BaseInputsList from './BaseInputsList';
6+
import { DIRECTION } from './BaseInputsList.types';
7+
8+
interface ItemType {
9+
id: string;
10+
label: string;
11+
}
12+
13+
const meta: Meta<typeof BaseInputsList<ItemType>> = {
14+
title: 'components/src/base/BaseInputsList',
15+
component: BaseInputsList<ItemType>,
16+
parameters: {
17+
layout: 'centered',
18+
docs: {
19+
controls: { exclude: ['items', 'renderItem', 'labelProps', 'helperTextProps'] },
20+
},
21+
},
22+
tags: ['autodocs', 'foundation', 'base'],
23+
argTypes: {
24+
className: { control: 'text' },
25+
direction: {
26+
control: 'select',
27+
options: Object.values(DIRECTION),
28+
},
29+
},
30+
args: {
31+
items: [
32+
{ id: '1', label: 'Item 1' },
33+
{ id: '2', label: 'Item 2' },
34+
{ id: '3', label: 'Item 3' },
35+
],
36+
renderItem: (item: ItemType) => (
37+
<div key={item.id}>
38+
{item.id}: {item.label}
39+
</div>
40+
),
41+
},
42+
};
43+
44+
export default meta;
45+
46+
type Story = StoryObj<typeof BaseInputsList<ItemType>>;
47+
48+
export const Default: Story = {
49+
name: 'Default',
50+
args: {
51+
labelProps: { children: 'Choice Inputs List Label' },
52+
helperTextProps: { children: 'This is a helper text' },
53+
},
54+
};
55+
56+
export const Horizontal: Story = {
57+
name: 'Horizontal',
58+
args: {
59+
labelProps: { children: 'Choice Inputs List Label' },
60+
helperTextProps: { children: 'This is a helper text' },
61+
direction: DIRECTION.HORIZONTAL,
62+
},
63+
};
64+
65+
export const NoHelper: Story = {
66+
name: 'No Helper',
67+
args: {
68+
labelProps: { children: 'Choice Inputs List Label' },
69+
},
70+
};
71+
72+
export const NoLabel: Story = {
73+
name: 'No Label',
74+
args: {
75+
helperTextProps: { children: 'This is a helper text' },
76+
},
77+
};
78+
79+
export const OnlyItems: Story = {
80+
name: 'Only Items',
81+
args: {},
82+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
3+
import BaseFormControl from '@ids-internal/partials/BaseFormControl';
4+
import { createCssClassNames } from '@ibexa/ids-core/helpers/cssClassNames';
5+
6+
import { BaseInputsListProps, DIRECTION } from './BaseInputsList.types';
7+
8+
const BaseInputsList = <T,>({
9+
items,
10+
renderItem,
11+
className = '',
12+
direction = DIRECTION.VERTICAL,
13+
helperTextProps,
14+
labelProps,
15+
}: BaseInputsListProps<T>) => {
16+
const listClassName = createCssClassNames({
17+
'ids-choice-inputs-list': true,
18+
[`ids-choice-inputs-list--${direction}`]: true,
19+
[className]: true,
20+
});
21+
return (
22+
<BaseFormControl className={listClassName} helperText={helperTextProps} label={labelProps} type="list">
23+
<div className="ids-choice-inputs-list__items">{items.map((item) => renderItem(item))}</div>
24+
</BaseFormControl>
25+
);
26+
};
27+
28+
export default BaseInputsList;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { BaseComponentAriaAttributes } from '@ids-types/general';
2+
import { HelperTextProps } from '../../../HelperText/HelperText.types';
3+
import { LabelProps } from '../../../Label/Label.types';
4+
5+
export enum DIRECTION {
6+
HORIZONTAL = 'horizontal',
7+
VERTICAL = 'vertical',
8+
}
9+
10+
export interface BaseInputsListProps<T> extends BaseComponentAriaAttributes {
11+
items: T[];
12+
renderItem: (item: T) => React.ReactNode;
13+
direction?: DIRECTION;
14+
helperTextProps?: HelperTextProps;
15+
labelProps?: LabelProps;
16+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { BaseInputsListProps, DIRECTION } from './BaseInputsList.types';
2+
import BaseInputsList from './BaseInputsList';
3+
4+
export default BaseInputsList;
5+
export type { BaseInputsListProps, DIRECTION };

0 commit comments

Comments
 (0)