widenarrow-ui 1.0.20 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/SelectInput/SelectInput.d.ts +4 -0
- package/lib/components/SelectInput/SelectInput.stories.d.ts +6 -0
- package/lib/components/SelectInput/SelectInput.types.d.ts +24 -0
- package/lib/components/SelectInput/index.d.ts +1 -0
- package/lib/components/index.d.ts +1 -0
- package/lib/index.css +1 -1
- package/lib/index.d.ts +27 -1
- package/lib/index.esm.css +1 -1
- package/lib/index.esm.js +160 -128
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +160 -127
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ListItem/ListItem.module.scss +6 -5
- package/src/components/ListItem/ListItem.stories.tsx +10 -2
- package/src/components/ListItem/ListItem.tsx +2 -3
- package/src/components/SelectInput/SelectInput.module.scss +74 -0
- package/src/components/SelectInput/SelectInput.stories.tsx +22 -0
- package/src/components/SelectInput/SelectInput.tsx +119 -0
- package/src/components/SelectInput/SelectInput.types.ts +26 -0
- package/src/components/SelectInput/index.ts +1 -0
- package/src/components/index.ts +1 -0
package/package.json
CHANGED
|
@@ -89,7 +89,6 @@
|
|
|
89
89
|
font-weight: 600;
|
|
90
90
|
font-size: $font-size-l;
|
|
91
91
|
color: $grey-5;
|
|
92
|
-
margin-bottom: 0;
|
|
93
92
|
margin-top: 0;
|
|
94
93
|
transition: color 50ms ease-in-out;
|
|
95
94
|
}
|
|
@@ -113,19 +112,17 @@
|
|
|
113
112
|
|
|
114
113
|
.innerContainer {
|
|
115
114
|
display: flex;
|
|
115
|
+
min-width: 0;
|
|
116
116
|
align-items: center;
|
|
117
117
|
justify-content: space-between;
|
|
118
118
|
flex-grow: 1;
|
|
119
|
-
|
|
120
|
-
&_withEllipsis {
|
|
121
|
-
overflow: hidden;
|
|
122
|
-
}
|
|
123
119
|
}
|
|
124
120
|
|
|
125
121
|
.contentContainer {
|
|
126
122
|
display: flex;
|
|
127
123
|
flex-direction: column;
|
|
128
124
|
margin-right: 12px;
|
|
125
|
+
flex-grow: 1;
|
|
129
126
|
|
|
130
127
|
&_withEllipsis {
|
|
131
128
|
overflow: hidden;
|
|
@@ -142,6 +139,10 @@
|
|
|
142
139
|
}
|
|
143
140
|
}
|
|
144
141
|
|
|
142
|
+
.buttonsContainer {
|
|
143
|
+
height: auto;
|
|
144
|
+
}
|
|
145
|
+
|
|
145
146
|
@include margin(8);
|
|
146
147
|
@include padding(8);
|
|
147
148
|
@include backgroundColor('backgroundColor');
|
|
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
|
|
|
3
3
|
import { ListItem } from 'src/components/ListItem';
|
|
4
4
|
import { Box } from 'src/components/Box';
|
|
5
5
|
import { SwitchButton } from 'src/components/SwitchButton';
|
|
6
|
+
import { ColorTypes } from 'src/constants';
|
|
6
7
|
|
|
7
8
|
const meta: Meta<typeof ListItem> = {
|
|
8
9
|
title: 'Components/ListItem',
|
|
@@ -24,12 +25,19 @@ export const Default: Story = {
|
|
|
24
25
|
<div style={{ width: '880px', display: 'flex', justifyContent: 'center' }}>
|
|
25
26
|
<ListItem
|
|
26
27
|
{...props}
|
|
28
|
+
borderColor={ColorTypes.BLACK}
|
|
29
|
+
border={'1'}
|
|
27
30
|
onClickCallback={() => {
|
|
28
31
|
console.log('Hej!');
|
|
29
32
|
}}
|
|
30
33
|
buttonsComponent={
|
|
31
|
-
<Box
|
|
32
|
-
<
|
|
34
|
+
<Box alignItems={'center'}>
|
|
35
|
+
{/* <div style={{ height: '300px', backgroundColor: 'red', width: '100px', marginRight: '8px' }}></div>
|
|
36
|
+
<div style={{ height: '300px', backgroundColor: 'green', width: '100px', marginRight: '8px' }}></div>
|
|
37
|
+
<div style={{ height: '300px', backgroundColor: 'blue', width: '100px' }}></div> */}
|
|
38
|
+
<Box>
|
|
39
|
+
<SwitchButton label={'Click me'} checked name={'switch example'} onClickCallback={() => undefined} />
|
|
40
|
+
</Box>
|
|
33
41
|
</Box>
|
|
34
42
|
}
|
|
35
43
|
/>
|
|
@@ -86,7 +86,6 @@ const ListItem: FC<ListItemProps> = ({
|
|
|
86
86
|
) : null}
|
|
87
87
|
<div
|
|
88
88
|
className={s('innerContainer', {
|
|
89
|
-
innerContainer_withEllipsis: withEllipsis,
|
|
90
89
|
[`padding_${padding}`]: is(String, padding),
|
|
91
90
|
[`paddingX_${paddingX}`]: is(String, paddingX),
|
|
92
91
|
[`paddingY_${paddingY}`]: is(String, paddingY),
|
|
@@ -106,12 +105,12 @@ const ListItem: FC<ListItemProps> = ({
|
|
|
106
105
|
>
|
|
107
106
|
{contentComponent && contentComponent}
|
|
108
107
|
{title ? (
|
|
109
|
-
<Heading className={s('heading')} type={'h4'} withEllipsis={withEllipsis}>
|
|
108
|
+
<Heading className={s('heading')} marginBottom={description ? '05' : '0'} type={'h4'} withEllipsis={withEllipsis}>
|
|
110
109
|
{title}
|
|
111
110
|
</Heading>
|
|
112
111
|
) : null}
|
|
113
112
|
{description ? (
|
|
114
|
-
<Paragraph marginBottom={'0'} fontSize=
|
|
113
|
+
<Paragraph marginBottom={'0'} fontSize={'s'} marginTop={'0'}>
|
|
115
114
|
{description}
|
|
116
115
|
</Paragraph>
|
|
117
116
|
) : null}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
@import 'src/styles/mixins.scss';
|
|
2
|
+
|
|
3
|
+
.container {
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
6
|
+
&_marginBottom {
|
|
7
|
+
margin-bottom: $two-base-size;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&_disabled {
|
|
11
|
+
pointer-events: none;
|
|
12
|
+
opacity: $disabled-opacity;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.inputContainer {
|
|
17
|
+
position: relative;
|
|
18
|
+
line-height: 1.2; // don't cut letters that go underneath the baseline ('g', 'q', etc)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.input {
|
|
22
|
+
@include input-field;
|
|
23
|
+
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
display: block;
|
|
26
|
+
height: $form-component-height;
|
|
27
|
+
width: 100%;
|
|
28
|
+
font-size: $font-size-m;
|
|
29
|
+
|
|
30
|
+
// Reset native select appearance (also removing icon) and add custom background arrow
|
|
31
|
+
-webkit-appearance: none;
|
|
32
|
+
-moz-appearance: none;
|
|
33
|
+
appearance: none;
|
|
34
|
+
background-color: $white;
|
|
35
|
+
|
|
36
|
+
&_active {
|
|
37
|
+
background-image: url('data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2212%22%20height%3D%2212%22%20viewBox%3D%220%200%2012%2012%22%3E%3Ctitle%3Edown-arrow%3C%2Ftitle%3E%3Cg%20fill%3D%22%23707070%22%3E%3Cpath%20d%3D%22M10.293%2C3.293%2C6%2C7.586%2C1.707%2C3.293A1%2C1%2C0%2C0%2C0%2C.293%2C4.707l5%2C5a1%2C1%2C0%2C0%2C0%2C1.414%2C0l5-5a1%2C1%2C0%2C1%2C0-1.414-1.414Z%22%20fill%3D%22%23707070%22%3E%3C%2Fpath%3E%3C%2Fg%3E%3C%2Fsvg%3E');
|
|
38
|
+
background-size: 12px;
|
|
39
|
+
background-position: calc(100% - 16px) center;
|
|
40
|
+
background-repeat: no-repeat;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@include breakpoint($lg) {
|
|
44
|
+
min-width: 240px;
|
|
45
|
+
|
|
46
|
+
&:hover {
|
|
47
|
+
border-color: $blue;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.button {
|
|
53
|
+
width: 100%;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.dropDown {
|
|
57
|
+
width: 100%;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.spinner {
|
|
61
|
+
position: absolute;
|
|
62
|
+
top: 8px;
|
|
63
|
+
right: 10px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.error {
|
|
67
|
+
display: block;
|
|
68
|
+
color: $red;
|
|
69
|
+
margin: $base-size 0 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.helperText {
|
|
73
|
+
@include form-helperText;
|
|
74
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { SelectInput } from 'src/components/SelectInput';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof SelectInput> = {
|
|
6
|
+
title: 'Components/SelectInput',
|
|
7
|
+
component: SelectInput
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
|
|
12
|
+
type Story = StoryObj<typeof SelectInput>;
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {
|
|
15
|
+
args: {
|
|
16
|
+
options: [
|
|
17
|
+
{ text: 'First item', value: 0 },
|
|
18
|
+
{ text: 'Second item', value: 1 },
|
|
19
|
+
{ text: 'Third item', value: 2 }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { FC, Fragment } from 'react';
|
|
2
|
+
import classNames from 'classnames/bind';
|
|
3
|
+
|
|
4
|
+
import { HierarchyTypes, IconTypes } from 'src/constants';
|
|
5
|
+
|
|
6
|
+
import { Label } from 'src/components/Typography/Typography';
|
|
7
|
+
import { SolidSpinner } from 'src/components/SolidSpinner';
|
|
8
|
+
import { Button } from 'src/components/Button';
|
|
9
|
+
import { DropDown } from 'src/components/DropDown';
|
|
10
|
+
import { DropDownItem } from 'src/components/DropDownItem';
|
|
11
|
+
import { SelectInputProps, OptionItem } from './SelectInput.types';
|
|
12
|
+
|
|
13
|
+
import styles from './SelectInput.module.scss';
|
|
14
|
+
|
|
15
|
+
const s = classNames.bind(styles);
|
|
16
|
+
|
|
17
|
+
const SelectInput: FC<SelectInputProps> = ({
|
|
18
|
+
name,
|
|
19
|
+
label,
|
|
20
|
+
nativeHtmlComponent = true,
|
|
21
|
+
size,
|
|
22
|
+
onChange,
|
|
23
|
+
defaultOption,
|
|
24
|
+
value,
|
|
25
|
+
error,
|
|
26
|
+
helperText,
|
|
27
|
+
options,
|
|
28
|
+
disabled,
|
|
29
|
+
loading,
|
|
30
|
+
className,
|
|
31
|
+
inputClassName,
|
|
32
|
+
marginBottom
|
|
33
|
+
}) => (
|
|
34
|
+
<div
|
|
35
|
+
className={s('container', {
|
|
36
|
+
container_marginBottom: marginBottom,
|
|
37
|
+
container_disabled: disabled,
|
|
38
|
+
[className as string]: className
|
|
39
|
+
})}
|
|
40
|
+
>
|
|
41
|
+
{label && <Label htmlFor={name}>{label}</Label>}
|
|
42
|
+
<div className={s('inputContainer')}>
|
|
43
|
+
{nativeHtmlComponent ? (
|
|
44
|
+
<Fragment>
|
|
45
|
+
<select
|
|
46
|
+
disabled={disabled || loading}
|
|
47
|
+
name={name}
|
|
48
|
+
value={value}
|
|
49
|
+
onChange={(e) => {
|
|
50
|
+
onChange(e.target.value); // Only send value, expensive to pass the whole event as argument through multiple components
|
|
51
|
+
}}
|
|
52
|
+
className={s('input', {
|
|
53
|
+
input_active: disabled !== true && loading !== true,
|
|
54
|
+
[inputClassName as string]: inputClassName
|
|
55
|
+
})}
|
|
56
|
+
aria-label={label || name}
|
|
57
|
+
>
|
|
58
|
+
{defaultOption && <option value="">{defaultOption}</option>}
|
|
59
|
+
{options &&
|
|
60
|
+
options.map((option) => (
|
|
61
|
+
<option key={option.value} value={option.value} disabled={option.disabled}>
|
|
62
|
+
{option.text}
|
|
63
|
+
</option>
|
|
64
|
+
))}
|
|
65
|
+
</select>
|
|
66
|
+
{loading && <SolidSpinner className={s('spinner')} size={size} />}
|
|
67
|
+
</Fragment>
|
|
68
|
+
) : (
|
|
69
|
+
<Fragment>
|
|
70
|
+
<DropDown
|
|
71
|
+
offset={{ vertical: 0, horizontal: 0 }}
|
|
72
|
+
placement={'bottom'}
|
|
73
|
+
buttonComponent={
|
|
74
|
+
<Button
|
|
75
|
+
loading={loading}
|
|
76
|
+
className={s('button')}
|
|
77
|
+
text={(() => {
|
|
78
|
+
let i = 0;
|
|
79
|
+
while (i < options.length) {
|
|
80
|
+
if (options[i].value === value) {
|
|
81
|
+
return options[i].text;
|
|
82
|
+
}
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
return 'Select an option';
|
|
86
|
+
})()}
|
|
87
|
+
size={size}
|
|
88
|
+
type={HierarchyTypes.SECONDARY}
|
|
89
|
+
icon={IconTypes.CHEVRON_DOWN}
|
|
90
|
+
/>
|
|
91
|
+
}
|
|
92
|
+
className={s('dropDown')}
|
|
93
|
+
withArrow={false}
|
|
94
|
+
>
|
|
95
|
+
{options
|
|
96
|
+
? options.map((opt: OptionItem) => (
|
|
97
|
+
<DropDownItem
|
|
98
|
+
key={opt.text}
|
|
99
|
+
text={opt.text}
|
|
100
|
+
type={HierarchyTypes.PRIMARY}
|
|
101
|
+
size={size}
|
|
102
|
+
active={opt.value === value}
|
|
103
|
+
onClickCallback={() => {
|
|
104
|
+
onChange(opt.value);
|
|
105
|
+
}}
|
|
106
|
+
/>
|
|
107
|
+
))
|
|
108
|
+
: null}
|
|
109
|
+
</DropDown>
|
|
110
|
+
</Fragment>
|
|
111
|
+
)}
|
|
112
|
+
{/* Note, value is set here rather than on the option - docs: https://facebook.github.io/react/docs/forms.html */}
|
|
113
|
+
</div>
|
|
114
|
+
{helperText && <p className={s('helperText')}>{helperText}</p>}
|
|
115
|
+
{error && <span className={s('error')}>{error}</span>}
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
export { SelectInput };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SizeTypes } from '../../constants';
|
|
2
|
+
|
|
3
|
+
export interface OptionItem {
|
|
4
|
+
text: string;
|
|
5
|
+
value: string | number;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface SelectInputProps {
|
|
10
|
+
className?: string;
|
|
11
|
+
inputClassName?: string;
|
|
12
|
+
defaultOption?: string;
|
|
13
|
+
size: SizeTypes.SMALL | SizeTypes.MEDIUM | SizeTypes.LARGE;
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
error?: string;
|
|
16
|
+
helperText?: string;
|
|
17
|
+
text?: string;
|
|
18
|
+
marginBottom?: boolean;
|
|
19
|
+
loading?: boolean;
|
|
20
|
+
label?: string;
|
|
21
|
+
name: string;
|
|
22
|
+
onChange: (value: string | number) => void;
|
|
23
|
+
options: Array<OptionItem>;
|
|
24
|
+
value: string | number;
|
|
25
|
+
nativeHtmlComponent?: boolean;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SelectInput';
|
package/src/components/index.ts
CHANGED