@ssa-ui-kit/core 1.0.1 → 1.0.3
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/.storybook/style.css +9 -0
- package/dist/components/Button/fixtures.d.ts +8 -0
- package/dist/components/Button/types.d.ts +2 -0
- package/dist/components/FormHelperText/FormHelperText.d.ts +1 -1
- package/dist/components/Input/types.d.ts +1 -0
- package/dist/components/Label/Label.d.ts +1 -1
- package/dist/components/Label/LabelBase.d.ts +2 -0
- package/dist/components/Label/types.d.ts +1 -0
- package/dist/components/Typeahead/Typeahead.context.d.ts +36 -0
- package/dist/components/Typeahead/Typeahead.d.ts +11 -0
- package/dist/components/Typeahead/components/MultipleTrigger.d.ts +1 -0
- package/dist/components/Typeahead/components/NoOptions.d.ts +1 -0
- package/dist/components/Typeahead/components/SingleTrigger.d.ts +1 -0
- package/dist/components/Typeahead/components/TypeaheadItem.d.ts +8 -0
- package/dist/components/Typeahead/components/TypeaheadOption.d.ts +2 -0
- package/dist/components/Typeahead/components/TypeaheadOptions.d.ts +2 -0
- package/dist/components/Typeahead/components/TypeaheadTrigger.d.ts +1 -0
- package/dist/components/Typeahead/components/index.d.ts +7 -0
- package/dist/components/Typeahead/index.d.ts +5 -0
- package/dist/components/Typeahead/styles.d.ts +47 -0
- package/dist/components/Typeahead/types.d.ts +46 -0
- package/dist/components/Typeahead/useTypeahead.d.ts +36 -0
- package/dist/components/Typeahead/utils.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/emotion.d.ts +4 -1
- package/package.json +1 -1
- package/src/components/Button/Button.tsx +10 -2
- package/src/components/Button/types.ts +2 -0
- package/src/components/CollapsibleNavBar/stories/CollapsibleNavBar.stories.tsx +47 -25
- package/src/components/CollapsibleNavBar/stories/Layout.tsx +1 -1
- package/src/components/Filters/Filters.tsx +1 -1
- package/src/components/FormHelperText/FormHelperText.tsx +2 -1
- package/src/components/Input/Input.spec.tsx +6 -8
- package/src/components/Input/Input.tsx +14 -8
- package/src/components/Input/types.ts +1 -0
- package/src/components/Label/Label.tsx +2 -0
- package/src/components/Label/LabelBase.tsx +3 -2
- package/src/components/Label/types.ts +1 -0
- package/src/components/MultipleDropdownOptions/MultipleDropdownOptions.tsx +1 -1
- package/src/components/ResponsiveImage/ResponsiveImage.stories.tsx +6 -4
- package/src/components/TableFilters/styles.ts +1 -0
- package/src/components/TextField/TextField.stories.tsx +8 -1
- package/src/components/Typeahead/Typeahead.context.ts +59 -0
- package/src/components/Typeahead/Typeahead.spec.tsx +506 -0
- package/src/components/Typeahead/Typeahead.stories.tsx +372 -0
- package/src/components/Typeahead/Typeahead.tsx +120 -0
- package/src/components/Typeahead/components/MultipleTrigger.tsx +116 -0
- package/src/components/Typeahead/components/NoOptions.tsx +7 -0
- package/src/components/Typeahead/components/SingleTrigger.tsx +71 -0
- package/src/components/Typeahead/components/TypeaheadItem.ts +14 -0
- package/src/components/Typeahead/components/TypeaheadOption.tsx +12 -0
- package/src/components/Typeahead/components/TypeaheadOptions.tsx +25 -0
- package/src/components/Typeahead/components/TypeaheadTrigger.tsx +26 -0
- package/src/components/Typeahead/components/index.ts +7 -0
- package/src/components/Typeahead/index.ts +5 -0
- package/src/components/Typeahead/styles.ts +193 -0
- package/src/components/Typeahead/types.ts +77 -0
- package/src/components/Typeahead/useTypeahead.tsx +321 -0
- package/src/components/Typeahead/utils.tsx +22 -0
- package/src/components/index.ts +1 -0
- package/src/themes/main.ts +3 -0
- package/src/types/emotion.ts +3 -0
- package/tsbuildcache +1 -1
package/dist/types/emotion.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ type Colors = MakeColors<[
|
|
|
12
12
|
'white30',
|
|
13
13
|
'dark',
|
|
14
14
|
'greyLighter',
|
|
15
|
+
'greyLighter40',
|
|
15
16
|
'greySelectedMenuItem',
|
|
16
17
|
'greyFocused',
|
|
17
18
|
'greyFocused40',
|
|
@@ -20,6 +21,7 @@ type Colors = MakeColors<[
|
|
|
20
21
|
'grey40',
|
|
21
22
|
'greyShadow24',
|
|
22
23
|
'greyDarker',
|
|
24
|
+
'greyDarker40',
|
|
23
25
|
'greyDarker60',
|
|
24
26
|
'greyDarker80',
|
|
25
27
|
'greyDarker14',
|
|
@@ -105,7 +107,8 @@ type Colors = MakeColors<[
|
|
|
105
107
|
'blueButtonHoverGradientFrom',
|
|
106
108
|
'blueButtonHoverGradientTo',
|
|
107
109
|
'blueButtonActive',
|
|
108
|
-
'blueRoyal'
|
|
110
|
+
'blueRoyal',
|
|
111
|
+
'blueRoyal12'
|
|
109
112
|
]>;
|
|
110
113
|
export type ColorsKeys = keyof Colors;
|
|
111
114
|
type MediaQueryString = `@media${string}`;
|
package/package.json
CHANGED
|
@@ -47,6 +47,8 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
47
47
|
text,
|
|
48
48
|
startIcon,
|
|
49
49
|
endIcon,
|
|
50
|
+
startIconClassName,
|
|
51
|
+
endIconClassName,
|
|
50
52
|
variant = 'primary',
|
|
51
53
|
type = 'button',
|
|
52
54
|
className,
|
|
@@ -89,7 +91,10 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
89
91
|
onClick={onClick}
|
|
90
92
|
{...ariaProps}>
|
|
91
93
|
{startIcon ? (
|
|
92
|
-
<span
|
|
94
|
+
<span
|
|
95
|
+
style={noMargin}
|
|
96
|
+
css={[iconWrapperRight]}
|
|
97
|
+
className={startIconClassName}>
|
|
93
98
|
{startIcon}
|
|
94
99
|
</span>
|
|
95
100
|
) : null}
|
|
@@ -107,7 +112,10 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
107
112
|
)
|
|
108
113
|
) : null}
|
|
109
114
|
{endIcon ? (
|
|
110
|
-
<span
|
|
115
|
+
<span
|
|
116
|
+
style={noMargin}
|
|
117
|
+
css={[iconWrapperLeft]}
|
|
118
|
+
className={endIconClassName}>
|
|
111
119
|
{endIcon}
|
|
112
120
|
</span>
|
|
113
121
|
) : null}
|
|
@@ -21,6 +21,8 @@ export interface ButtonProps extends ButtonAriaProps {
|
|
|
21
21
|
text?: string;
|
|
22
22
|
startIcon?: React.ReactNode;
|
|
23
23
|
endIcon?: React.ReactNode;
|
|
24
|
+
startIconClassName?: string;
|
|
25
|
+
endIconClassName?: string;
|
|
24
26
|
variant?: keyof ButtonVariants | 'custom';
|
|
25
27
|
type?: 'button' | 'reset' | 'submit';
|
|
26
28
|
isDisabled?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment } from 'react';
|
|
2
2
|
import { Routes, Route, MemoryRouter } from 'react-router-dom';
|
|
3
|
-
import { Meta } from '@storybook/react';
|
|
4
|
-
import { Title, Description,
|
|
3
|
+
import { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
import { Title, Description, Subtitle, Stories } from '@storybook/addon-docs';
|
|
5
5
|
|
|
6
6
|
import { DecoratorFunction } from '@storybook/types';
|
|
7
7
|
import { CollapsibleNavBar } from '../CollapsibleNavBar';
|
|
@@ -35,11 +35,17 @@ export default {
|
|
|
35
35
|
parameters: {
|
|
36
36
|
layout: 'fullscreen',
|
|
37
37
|
docs: {
|
|
38
|
+
source: {
|
|
39
|
+
type: 'code',
|
|
40
|
+
},
|
|
38
41
|
page: () => (
|
|
39
42
|
<Fragment>
|
|
40
43
|
<Title />
|
|
44
|
+
<Subtitle />
|
|
41
45
|
<Description />
|
|
42
|
-
<
|
|
46
|
+
<div css={{ height: 300 }}>
|
|
47
|
+
<Stories />
|
|
48
|
+
</div>
|
|
43
49
|
</Fragment>
|
|
44
50
|
),
|
|
45
51
|
},
|
|
@@ -54,26 +60,42 @@ export default {
|
|
|
54
60
|
},
|
|
55
61
|
} as Meta<typeof CollapsibleNavBar>;
|
|
56
62
|
|
|
57
|
-
export const Default = {
|
|
63
|
+
export const Default: StoryObj<typeof CollapsibleNavBar> = () => {
|
|
64
|
+
return (
|
|
65
|
+
<CollapsibleNavBar
|
|
66
|
+
items={ITEMS}
|
|
67
|
+
renderLogo={<Logo />}
|
|
68
|
+
onChange={(isChecked) => {
|
|
69
|
+
console.log('>>>onChange', isChecked);
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
58
74
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
Default.args = {};
|
|
76
|
+
|
|
77
|
+
export const WithCustomIcon: Meta<typeof CollapsibleNavBar> = () => {
|
|
78
|
+
return (
|
|
79
|
+
<CollapsibleNavBar
|
|
80
|
+
items={[
|
|
81
|
+
...ITEMS,
|
|
82
|
+
{
|
|
83
|
+
path: 'custom',
|
|
84
|
+
CustomIcon,
|
|
85
|
+
title: 'Item with custom icon',
|
|
86
|
+
iconSize: 22,
|
|
87
|
+
iconName: 'archive',
|
|
88
|
+
},
|
|
89
|
+
]}
|
|
90
|
+
renderLogo={<Logo />}
|
|
91
|
+
onChange={(isChecked) => {
|
|
92
|
+
console.log('>>>onChange', isChecked);
|
|
93
|
+
}}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
WithCustomIcon.title = 'With Custom Icon';
|
|
99
|
+
WithCustomIcon.parameters = {
|
|
100
|
+
layout: 'fullscreen',
|
|
101
|
+
};
|
|
@@ -36,7 +36,7 @@ export const Layout = ({ children }: { children: React.ReactNode }) => {
|
|
|
36
36
|
}}>
|
|
37
37
|
{children}
|
|
38
38
|
<Main>
|
|
39
|
-
{new Array(
|
|
39
|
+
{new Array(30).fill(1).map((_, index) => (
|
|
40
40
|
<NotificationCard
|
|
41
41
|
key={index}
|
|
42
42
|
title="CyberVeinToken is Now Available"
|
|
@@ -6,10 +6,11 @@ const FormHelperText = ({
|
|
|
6
6
|
status,
|
|
7
7
|
disabled,
|
|
8
8
|
children,
|
|
9
|
+
...rest
|
|
9
10
|
}: FormHelperTextProps) => {
|
|
10
11
|
status = disabled ? 'basic' : status;
|
|
11
12
|
return (
|
|
12
|
-
<FormHelperTextBase role={role} status={status}>
|
|
13
|
+
<FormHelperTextBase role={role} status={status} {...rest}>
|
|
13
14
|
{children}
|
|
14
15
|
</FormHelperTextBase>
|
|
15
16
|
);
|
|
@@ -15,14 +15,12 @@ describe('Inputs', () => {
|
|
|
15
15
|
expect(input).toBeInTheDocument();
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
-
it('
|
|
19
|
-
jest.spyOn(console, '
|
|
20
|
-
|
|
21
|
-
expect((
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
render(<Input placeholder="Field" name="field" disabled={true} />),
|
|
25
|
-
).toThrow('Input component must be used within a Form component');
|
|
18
|
+
it('Throw warning when without register', () => {
|
|
19
|
+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation();
|
|
20
|
+
render(<Input placeholder="Field" name="field" disabled={true} />);
|
|
21
|
+
expect(warnSpy).toBeCalledWith(
|
|
22
|
+
'Input component must be used within a Form component',
|
|
23
|
+
);
|
|
26
24
|
});
|
|
27
25
|
|
|
28
26
|
it('Render input disabled', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { forwardRef } from 'react';
|
|
1
|
+
import { forwardRef, useEffect } from 'react';
|
|
2
2
|
import { useMergeRefs } from '@floating-ui/react';
|
|
3
3
|
import { InputBase } from './InputBase';
|
|
4
4
|
import { InputGroup } from './InputGroup';
|
|
@@ -25,21 +25,27 @@ const InputInner = (
|
|
|
25
25
|
startElement,
|
|
26
26
|
endElement,
|
|
27
27
|
className,
|
|
28
|
+
wrapperClassName,
|
|
28
29
|
inputProps = {},
|
|
29
30
|
register,
|
|
30
31
|
onKeyUp,
|
|
31
32
|
}: InputProps,
|
|
32
33
|
inputRef?: React.ForwardedRef<HTMLInputElement | null>,
|
|
33
34
|
) => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!register) {
|
|
37
|
+
console.warn('Input component must be used within a Form component');
|
|
38
|
+
}
|
|
39
|
+
}, []);
|
|
37
40
|
|
|
38
41
|
const showStatusIcon = () => !disabled && !endElement;
|
|
39
42
|
|
|
40
|
-
const registerResult = register(name, validationSchema);
|
|
43
|
+
const registerResult = register?.(name, validationSchema);
|
|
41
44
|
return (
|
|
42
|
-
<InputGroup
|
|
45
|
+
<InputGroup
|
|
46
|
+
css={[mapColors[status]]}
|
|
47
|
+
className={wrapperClassName}
|
|
48
|
+
disabled={disabled}>
|
|
43
49
|
{startElement ? <div css={S.startElement}>{startElement}</div> : null}
|
|
44
50
|
<InputBase
|
|
45
51
|
type={type}
|
|
@@ -53,8 +59,8 @@ const InputInner = (
|
|
|
53
59
|
className={className}
|
|
54
60
|
onKeyUp={onKeyUp}
|
|
55
61
|
{...inputProps}
|
|
56
|
-
{...register(name, validationSchema)}
|
|
57
|
-
ref={useMergeRefs([registerResult
|
|
62
|
+
{...register?.(name, validationSchema)}
|
|
63
|
+
ref={useMergeRefs([registerResult?.ref, inputRef])}
|
|
58
64
|
/>
|
|
59
65
|
|
|
60
66
|
{status === 'error' && showStatusIcon() ? <InputStatusError /> : null}
|
|
@@ -5,11 +5,13 @@ const Label = ({
|
|
|
5
5
|
children,
|
|
6
6
|
htmlFor,
|
|
7
7
|
className,
|
|
8
|
+
isDisabled,
|
|
8
9
|
onMouseEnter,
|
|
9
10
|
onMouseLeave,
|
|
10
11
|
}: LabelProps) => (
|
|
11
12
|
<LabelBase
|
|
12
13
|
htmlFor={htmlFor}
|
|
14
|
+
isDisabled={isDisabled}
|
|
13
15
|
className={className}
|
|
14
16
|
onMouseEnter={onMouseEnter}
|
|
15
17
|
onMouseLeave={onMouseLeave}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styled from '@emotion/styled';
|
|
2
2
|
|
|
3
|
-
export const LabelBase = styled.label
|
|
3
|
+
export const LabelBase = styled.label<{ isDisabled?: boolean }>`
|
|
4
4
|
display: inline-block;
|
|
5
5
|
|
|
6
6
|
flex: 1;
|
|
@@ -8,7 +8,8 @@ export const LabelBase = styled.label`
|
|
|
8
8
|
font-size: 1rem;
|
|
9
9
|
line-height: 22px;
|
|
10
10
|
|
|
11
|
-
color: ${({ theme }) =>
|
|
11
|
+
color: ${({ theme, isDisabled }) =>
|
|
12
|
+
isDisabled ? theme.colors.grey : theme.colors.greyDarker};
|
|
12
13
|
|
|
13
14
|
margin: 0 0 6px 4px;
|
|
14
15
|
`;
|
|
@@ -4,6 +4,7 @@ import { CommonProps } from '@global-types/emotion';
|
|
|
4
4
|
export interface LabelProps extends CommonProps {
|
|
5
5
|
htmlFor?: string;
|
|
6
6
|
children: React.ReactNode;
|
|
7
|
+
isDisabled?: boolean;
|
|
7
8
|
onMouseEnter?: MouseEventHandler<HTMLLabelElement>;
|
|
8
9
|
onMouseLeave?: MouseEventHandler<HTMLLabelElement>;
|
|
9
10
|
}
|
|
@@ -21,10 +21,12 @@ export const Default: StoryObj<typeof ResponsiveImage> = () => {
|
|
|
21
21
|
tag
|
|
22
22
|
</Typography>
|
|
23
23
|
<ResponsiveImage
|
|
24
|
-
srcSet=
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
srcSet={`
|
|
25
|
+
https://firebasestorage.googleapis.com/v0/b/admin-themes.appspot.com/o/logo%2FUI_KIT_Medium_90_51.png?alt=media&token=6761e4f3-b985-4322-8824-0c9668a2e2d9 90w,
|
|
26
|
+
https://firebasestorage.googleapis.com/v0/b/admin-themes.appspot.com/o/logo%2FUI_KIT_Small_80_49.png?alt=media&token=910e7a01-8127-4e2e-88e6-1b85805d7beb 80w`}
|
|
27
|
+
sizes="(max-width: 900px) 80px, (min-width: 900px) 90px"
|
|
28
|
+
src="https://firebasestorage.googleapis.com/v0/b/admin-themes.appspot.com/o/logo%2FUI_KIT_Small_80_49.png?alt=media&token=910e7a01-8127-4e2e-88e6-1b85805d7beb"
|
|
29
|
+
alt="SSA UI Kit"
|
|
28
30
|
/>
|
|
29
31
|
</div>
|
|
30
32
|
);
|
|
@@ -148,7 +148,14 @@ export const WithAction: StoryObj<typeof TextField> = () => {
|
|
|
148
148
|
register={register}
|
|
149
149
|
helperText="some nice text"
|
|
150
150
|
endElement={
|
|
151
|
-
<button
|
|
151
|
+
<button
|
|
152
|
+
onClick={(event) => {
|
|
153
|
+
event.stopPropagation();
|
|
154
|
+
event.preventDefault();
|
|
155
|
+
console.log('calling action...');
|
|
156
|
+
}}>
|
|
157
|
+
Action
|
|
158
|
+
</button>
|
|
152
159
|
}
|
|
153
160
|
/>
|
|
154
161
|
);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { UseTypeaheadResult } from './useTypeahead';
|
|
3
|
+
|
|
4
|
+
export const TypeaheadContext = React.createContext<UseTypeaheadResult>({
|
|
5
|
+
optionsWithKey: {},
|
|
6
|
+
isMultiple: false,
|
|
7
|
+
selectedItems: [],
|
|
8
|
+
typeaheadId: '',
|
|
9
|
+
firstSuggestion: '',
|
|
10
|
+
inputRef: { current: null },
|
|
11
|
+
triggerRef: { current: null },
|
|
12
|
+
isOpen: false,
|
|
13
|
+
className: undefined,
|
|
14
|
+
startIcon: null,
|
|
15
|
+
endIcon: null,
|
|
16
|
+
startIconClassName: undefined,
|
|
17
|
+
endIconClassName: undefined,
|
|
18
|
+
name: '',
|
|
19
|
+
inputName: '',
|
|
20
|
+
inputValue: '',
|
|
21
|
+
validationSchema: {},
|
|
22
|
+
status: 'basic',
|
|
23
|
+
isDisabled: false,
|
|
24
|
+
options: [],
|
|
25
|
+
placeholder: '',
|
|
26
|
+
setValue: () => {
|
|
27
|
+
/* no-op */
|
|
28
|
+
},
|
|
29
|
+
register: () => {
|
|
30
|
+
return {} as any;
|
|
31
|
+
},
|
|
32
|
+
handleChange: () => {
|
|
33
|
+
/* no-op */
|
|
34
|
+
},
|
|
35
|
+
handleClearAll: () => {
|
|
36
|
+
/* no-op */
|
|
37
|
+
},
|
|
38
|
+
handleInputClick: () => {
|
|
39
|
+
/* no-op */
|
|
40
|
+
},
|
|
41
|
+
handleInputKeyDown: () => {
|
|
42
|
+
/* no-op */
|
|
43
|
+
},
|
|
44
|
+
handleInputChange: () => {
|
|
45
|
+
/* no-op */
|
|
46
|
+
},
|
|
47
|
+
handleOpenChange: () => {
|
|
48
|
+
/* no-op */
|
|
49
|
+
},
|
|
50
|
+
handleRemoveSelectedClick: () => () => {
|
|
51
|
+
/* no-op */
|
|
52
|
+
},
|
|
53
|
+
handleSelectedClick: () => {
|
|
54
|
+
/* no-op */
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const useTypeaheadContext = (): UseTypeaheadResult =>
|
|
59
|
+
React.useContext(TypeaheadContext);
|