@bodynarf/react.components 1.1.1 → 1.1.4
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/{src/components → components}/anchor/anchor.scss +0 -0
- package/components/anchor/components/anchorWithIcon/index.d.ts +5 -0
- package/components/anchor/components/anchorWithIcon/index.d.ts.map +1 -0
- package/components/anchor/components/anchorWithIcon/index.js +16 -0
- package/components/anchor/components/simpleAnchor/index.d.ts +5 -0
- package/components/anchor/components/simpleAnchor/index.d.ts.map +1 -0
- package/components/anchor/components/simpleAnchor/index.js +5 -0
- package/components/anchor/index.d.ts +24 -0
- package/components/anchor/index.d.ts.map +1 -0
- package/components/anchor/index.js +18 -0
- package/{src/components/anchor/types.ts → components/anchor/types.d.ts} +3 -9
- package/components/anchor/types.d.ts.map +1 -0
- package/components/anchor/types.js +1 -0
- package/{src/components → components}/button/button.scss +0 -0
- package/components/button/components/buttonWithIcon/index.d.ts +5 -0
- package/components/button/components/buttonWithIcon/index.d.ts.map +1 -0
- package/components/button/components/buttonWithIcon/index.js +19 -0
- package/components/button/components/simpleButton/index.d.ts +5 -0
- package/components/button/components/simpleButton/index.d.ts.map +1 -0
- package/components/button/components/simpleButton/index.js +5 -0
- package/components/button/index.d.ts +34 -0
- package/components/button/index.d.ts.map +1 -0
- package/components/button/index.js +27 -0
- package/components/button/types.d.ts +20 -0
- package/components/button/types.d.ts.map +1 -0
- package/components/button/types.js +1 -0
- package/components/dropdown/components/dropdownItem/index.d.ts +15 -0
- package/components/dropdown/components/dropdownItem/index.d.ts.map +1 -0
- package/components/dropdown/components/dropdownItem/index.js +6 -0
- package/components/dropdown/components/dropdownLabel/index.d.ts +16 -0
- package/components/dropdown/components/dropdownLabel/index.d.ts.map +1 -0
- package/components/dropdown/components/dropdownLabel/index.js +21 -0
- package/{src/components → components}/dropdown/dropdown.scss +0 -0
- package/components/dropdown/index.d.ts +31 -0
- package/components/dropdown/index.d.ts.map +1 -0
- package/components/dropdown/index.js +57 -0
- package/{src/components/dropdown/types.ts → components/dropdown/types.d.ts} +3 -4
- package/components/dropdown/types.d.ts.map +1 -0
- package/components/dropdown/types.js +1 -0
- package/{src/components → components}/icon/icon.scss +0 -0
- package/components/icon/index.d.ts +18 -0
- package/components/icon/index.d.ts.map +1 -0
- package/components/icon/index.js +15 -0
- package/components/primitives/date/index.d.ts +11 -0
- package/components/primitives/date/index.d.ts.map +1 -0
- package/components/primitives/date/index.js +31 -0
- package/components/primitives/index.d.ts +5 -0
- package/components/primitives/index.d.ts.map +1 -0
- package/components/primitives/index.js +4 -0
- package/components/primitives/multiline/components/multilineWithLabel/index.d.ts +6 -0
- package/components/primitives/multiline/components/multilineWithLabel/index.d.ts.map +1 -0
- package/components/primitives/multiline/components/multilineWithLabel/index.js +29 -0
- package/components/primitives/multiline/components/multilineWithoutLabel/index.d.ts +6 -0
- package/components/primitives/multiline/components/multilineWithoutLabel/index.d.ts.map +1 -0
- package/components/primitives/multiline/components/multilineWithoutLabel/index.js +25 -0
- package/components/primitives/multiline/index.d.ts +13 -0
- package/components/primitives/multiline/index.d.ts.map +1 -0
- package/components/primitives/multiline/index.js +14 -0
- package/components/primitives/text/components/textWithLabel/index.d.ts +6 -0
- package/components/primitives/text/components/textWithLabel/index.d.ts.map +1 -0
- package/components/primitives/text/components/textWithLabel/index.js +28 -0
- package/components/primitives/text/components/textWithoutLabel/index.d.ts +6 -0
- package/components/primitives/text/components/textWithoutLabel/index.d.ts.map +1 -0
- package/components/primitives/text/components/textWithoutLabel/index.js +24 -0
- package/components/primitives/text/index.d.ts +8 -0
- package/components/primitives/text/index.d.ts.map +1 -0
- package/components/primitives/text/index.js +14 -0
- package/{src/components/primitives/types.ts → components/primitives/types.d.ts} +5 -32
- package/components/primitives/types.d.ts.map +1 -0
- package/components/primitives/types.js +1 -0
- package/components/search/index.d.ts +31 -0
- package/components/search/index.d.ts.map +1 -0
- package/components/search/index.js +39 -0
- package/{src/components → components}/search/search.scss +0 -0
- package/{src/components/types.ts → components/types.d.ts} +5 -16
- package/components/types.d.ts.map +1 -0
- package/components/types.js +1 -0
- package/hooks/index.d.ts +2 -0
- package/hooks/index.d.ts.map +1 -0
- package/hooks/index.js +1 -0
- package/hooks/useComponentOutsideClick.d.ts +11 -0
- package/hooks/useComponentOutsideClick.d.ts.map +1 -0
- package/hooks/useComponentOutsideClick.js +32 -0
- package/index.d.ts +10 -0
- package/index.d.ts.map +1 -0
- package/index.js +9 -0
- package/package.json +10 -21
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
- package/anchor.ts +0 -10
- package/button.ts +0 -11
- package/date.ts +0 -7
- package/dropdown.ts +0 -9
- package/hooks.ts +0 -5
- package/icon.ts +0 -7
- package/index.html +0 -13
- package/index.ts +0 -14
- package/multiline.ts +0 -7
- package/search.ts +0 -7
- package/src/components/anchor/components/anchorWithIcon/anchorWithIcon.tsx +0 -45
- package/src/components/anchor/components/simpleAnchor/simpleAnchor.tsx +0 -16
- package/src/components/anchor/index.tsx +0 -64
- package/src/components/button/components/buttonWithIcon/buttonWithIcon.tsx +0 -47
- package/src/components/button/components/simpleButton/simpleButton.tsx +0 -16
- package/src/components/button/index.tsx +0 -83
- package/src/components/button/types.ts +0 -40
- package/src/components/dropdown/components/dropdownItem/dropdownItem.tsx +0 -30
- package/src/components/dropdown/components/dropdownLabel/dropdownLabel.tsx +0 -60
- package/src/components/dropdown/index.tsx +0 -141
- package/src/components/icon/index.tsx +0 -34
- package/src/components/primitives/date/index.tsx +0 -103
- package/src/components/primitives/multiline/components/multilineWithLabel/index.tsx +0 -93
- package/src/components/primitives/multiline/components/multilineWithoutLabel/index.tsx +0 -51
- package/src/components/primitives/multiline/index.tsx +0 -28
- package/src/components/primitives/text/components/textWithLabel/index.tsx +0 -92
- package/src/components/primitives/text/components/textWithoutLabel/index.tsx +0 -49
- package/src/components/primitives/text/index.tsx +0 -21
- package/src/components/search/index.tsx +0 -127
- package/src/hooks/useComponentOutsideClick.ts +0 -48
- package/src/main.tsx +0 -9
- package/text.ts +0 -7
- package/tsconfig.json +0 -39
- package/tsconfig.node.json +0 -8
- package/vite.config.ts +0 -14
package/icon.ts
DELETED
package/index.html
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<base href="/"/>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
7
|
-
<title>bodynarf/react-components</title>
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="root"></div>
|
|
11
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
package/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseInputElementProps, InputColor, InputLabel, InputSize } from "src/components/primitives/types";
|
|
2
|
-
import { BaseElementProps, ElementIcon, IconPosition, IconSize } from "src/components/types";
|
|
3
|
-
|
|
4
|
-
export {
|
|
5
|
-
BaseInputElementProps,
|
|
6
|
-
InputColor,
|
|
7
|
-
InputLabel,
|
|
8
|
-
InputSize,
|
|
9
|
-
|
|
10
|
-
BaseElementProps,
|
|
11
|
-
ElementIcon,
|
|
12
|
-
IconPosition,
|
|
13
|
-
IconSize,
|
|
14
|
-
};
|
package/multiline.ts
DELETED
package/search.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { isNullOrEmpty } from '@bodynarf/utils/common';
|
|
2
|
-
|
|
3
|
-
import Icon from 'src/components/icon';
|
|
4
|
-
|
|
5
|
-
import { AnchorWithIconProps } from "../../types";
|
|
6
|
-
|
|
7
|
-
/** Anchor with icon component */
|
|
8
|
-
export const AnchorWithIcon = ({ href, className, onClick, caption, title, target, icon }: AnchorWithIconProps): JSX.Element => {
|
|
9
|
-
const iconPosition = icon.position || 'left';
|
|
10
|
-
|
|
11
|
-
const iconClassName: string = isNullOrEmpty(caption)
|
|
12
|
-
? icon.className
|
|
13
|
-
: iconPosition === 'left'
|
|
14
|
-
? `${icon.className} app-icon--left`
|
|
15
|
-
: `${icon.className} app-icon--right`;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (iconPosition === 'left') {
|
|
19
|
-
return (
|
|
20
|
-
<a
|
|
21
|
-
href={href}
|
|
22
|
-
className={className}
|
|
23
|
-
title={title}
|
|
24
|
-
target={target}
|
|
25
|
-
onClick={onClick}
|
|
26
|
-
>
|
|
27
|
-
<Icon {...icon} className={iconClassName} />
|
|
28
|
-
{caption}
|
|
29
|
-
</a>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return (
|
|
34
|
-
<a
|
|
35
|
-
href={href}
|
|
36
|
-
className={className}
|
|
37
|
-
title={title}
|
|
38
|
-
target={target}
|
|
39
|
-
onClick={onClick}
|
|
40
|
-
>
|
|
41
|
-
{caption}
|
|
42
|
-
<Icon {...icon} className={iconClassName} />
|
|
43
|
-
</a>
|
|
44
|
-
);
|
|
45
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { SimpleAnchorProps } from "../../types";
|
|
2
|
-
|
|
3
|
-
/** Simple anchor component, without icon */
|
|
4
|
-
export const SimpleAnchor = ({ href, className, onClick, caption, title, target }: SimpleAnchorProps): JSX.Element => {
|
|
5
|
-
return (
|
|
6
|
-
<a
|
|
7
|
-
className={className}
|
|
8
|
-
href={href}
|
|
9
|
-
title={title}
|
|
10
|
-
target={target}
|
|
11
|
-
onClick={onClick}
|
|
12
|
-
>
|
|
13
|
-
{caption}
|
|
14
|
-
</a>
|
|
15
|
-
);
|
|
16
|
-
};
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { isNullOrEmpty, isNullOrUndefined } from '@bodynarf/utils/common';
|
|
2
|
-
|
|
3
|
-
import './anchor.scss';
|
|
4
|
-
|
|
5
|
-
import { ElementIcon } from '../types';
|
|
6
|
-
|
|
7
|
-
import { SimpleAnchor } from './components/simpleAnchor/simpleAnchor';
|
|
8
|
-
import { AnchorWithIcon } from './components/anchorWithIcon/anchorWithIcon';
|
|
9
|
-
|
|
10
|
-
export type AnchorProps = {
|
|
11
|
-
/** Link destination */
|
|
12
|
-
href?: string;
|
|
13
|
-
|
|
14
|
-
/** Link caption */
|
|
15
|
-
caption?: string;
|
|
16
|
-
|
|
17
|
-
/** Click handler */
|
|
18
|
-
onClick?: () => void;
|
|
19
|
-
|
|
20
|
-
/** Configuration od inner icon */
|
|
21
|
-
icon?: ElementIcon;
|
|
22
|
-
|
|
23
|
-
/** Title of anchor */
|
|
24
|
-
title?: string;
|
|
25
|
-
|
|
26
|
-
/** Where to open the linked document */
|
|
27
|
-
target?: '_blank' | '_top';
|
|
28
|
-
|
|
29
|
-
/** Additional class names */
|
|
30
|
-
className?: string;
|
|
31
|
-
|
|
32
|
-
/** Should css hovering effects be disabled */
|
|
33
|
-
disableHovering?: boolean;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/** Anchor component */
|
|
37
|
-
export default function Anchor(props: AnchorProps): JSX.Element {
|
|
38
|
-
if (isNullOrUndefined(props.caption) && isNullOrUndefined(props.icon)) {
|
|
39
|
-
throw new Error("No anchor content provided");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const className: string = 'app-anchor'
|
|
43
|
-
+ (!isNullOrEmpty(props.className) ? ` ${props.className}` : '')
|
|
44
|
-
+ (props.disableHovering === true ? ' app-anchor--unhoverable' : '');
|
|
45
|
-
|
|
46
|
-
if (isNullOrUndefined(props.icon)) {
|
|
47
|
-
return (
|
|
48
|
-
<SimpleAnchor
|
|
49
|
-
{...props}
|
|
50
|
-
className={className}
|
|
51
|
-
onClick={props.onClick}
|
|
52
|
-
/>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return (
|
|
57
|
-
<AnchorWithIcon
|
|
58
|
-
{...props}
|
|
59
|
-
className={className}
|
|
60
|
-
onClick={props.onClick}
|
|
61
|
-
icon={props.icon as ElementIcon}
|
|
62
|
-
/>
|
|
63
|
-
);
|
|
64
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { isNullOrEmpty } from '@bodynarf/utils/common';
|
|
3
|
-
|
|
4
|
-
import Icon from 'src/components/icon';
|
|
5
|
-
|
|
6
|
-
import { ButtonWithIconProps } from '../../types';
|
|
7
|
-
|
|
8
|
-
/** Button with icon component */
|
|
9
|
-
export const ButtonWithIcon = ({ className, disabled, onClick, caption, title, icon }: ButtonWithIconProps): JSX.Element => {
|
|
10
|
-
const iconPosition = icon.position || 'left';
|
|
11
|
-
|
|
12
|
-
const iconClassName: string = isNullOrEmpty(caption)
|
|
13
|
-
? icon.className
|
|
14
|
-
: iconPosition === 'left'
|
|
15
|
-
? `${icon.className} app-icon--left`
|
|
16
|
-
: `${icon.className} app-icon--right`;
|
|
17
|
-
|
|
18
|
-
className = isNullOrEmpty(caption)
|
|
19
|
-
? `${className} button--icon-only`
|
|
20
|
-
: className;
|
|
21
|
-
|
|
22
|
-
if (iconPosition === 'left') {
|
|
23
|
-
return (
|
|
24
|
-
<button
|
|
25
|
-
className={className}
|
|
26
|
-
disabled={disabled}
|
|
27
|
-
onClick={onClick}
|
|
28
|
-
title={title}
|
|
29
|
-
>
|
|
30
|
-
<Icon {...icon} className={iconClassName} />
|
|
31
|
-
{caption}
|
|
32
|
-
</button>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<button
|
|
38
|
-
className={className}
|
|
39
|
-
disabled={disabled}
|
|
40
|
-
onClick={onClick}
|
|
41
|
-
title={title}
|
|
42
|
-
>
|
|
43
|
-
{caption}
|
|
44
|
-
<Icon {...icon} className={iconClassName} />
|
|
45
|
-
</button>
|
|
46
|
-
);
|
|
47
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { SimpleButtonProps } from '../../types';
|
|
3
|
-
|
|
4
|
-
/** Simple button component, without icon */
|
|
5
|
-
export const SimpleButton = ({ className, disabled, onClick, caption, title }: SimpleButtonProps): JSX.Element => {
|
|
6
|
-
return (
|
|
7
|
-
<button
|
|
8
|
-
className={className}
|
|
9
|
-
disabled={disabled}
|
|
10
|
-
onClick={onClick}
|
|
11
|
-
title={title}
|
|
12
|
-
>
|
|
13
|
-
{caption}
|
|
14
|
-
</button>
|
|
15
|
-
);
|
|
16
|
-
};
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { isNullOrEmpty, isNullOrUndefined, isStringEmpty } from '@bodynarf/utils/common';
|
|
2
|
-
|
|
3
|
-
import './button.scss';
|
|
4
|
-
|
|
5
|
-
import { ElementIcon, IconSize } from '../types';
|
|
6
|
-
|
|
7
|
-
import { ButtonType } from './types';
|
|
8
|
-
import { ButtonWithIcon } from './components/buttonWithIcon/buttonWithIcon';
|
|
9
|
-
import { SimpleButton } from './components/simpleButton/simpleButton';
|
|
10
|
-
|
|
11
|
-
export type ButtonProps = {
|
|
12
|
-
/** Button displaying text */
|
|
13
|
-
caption?: string;
|
|
14
|
-
|
|
15
|
-
/** Type of button (color) */
|
|
16
|
-
type: ButtonType;
|
|
17
|
-
|
|
18
|
-
/** Configuration of inner icon */
|
|
19
|
-
icon?: ElementIcon;
|
|
20
|
-
|
|
21
|
-
/** Button size */
|
|
22
|
-
size?: IconSize; // TODO: fix this type using
|
|
23
|
-
|
|
24
|
-
/** Title on hover */
|
|
25
|
-
title?: string;
|
|
26
|
-
|
|
27
|
-
/** Is button uses light version of color */
|
|
28
|
-
light?: boolean;
|
|
29
|
-
|
|
30
|
-
/** Is button outlined */
|
|
31
|
-
outlined?: boolean;
|
|
32
|
-
|
|
33
|
-
/** Should button corners be rounded */
|
|
34
|
-
rounded?: boolean;
|
|
35
|
-
|
|
36
|
-
/** Display loading icon */
|
|
37
|
-
isLoading?: boolean;
|
|
38
|
-
|
|
39
|
-
/** Is button disabled */
|
|
40
|
-
disabled?: boolean;
|
|
41
|
-
|
|
42
|
-
/** Click action handler */
|
|
43
|
-
onClick?: () => void;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Button component
|
|
48
|
-
* @throws Caption is not defined and icon configuration is not defined at the same time
|
|
49
|
-
*/
|
|
50
|
-
export default function Button(props: ButtonProps): JSX.Element {
|
|
51
|
-
if ((isNullOrEmpty(props.caption))
|
|
52
|
-
&& (isNullOrUndefined(props.icon) || isStringEmpty(props.icon?.className as string))
|
|
53
|
-
) {
|
|
54
|
-
throw new Error("No button content provided.");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const className: string =
|
|
58
|
-
`button is-${props.type}`
|
|
59
|
-
+ (props.light === true ? ' is-light' : '')
|
|
60
|
-
+ (!isNullOrUndefined(props.size) ? ` is-${props.size}` : '')
|
|
61
|
-
+ (props.outlined === true ? ' is-outlined' : '')
|
|
62
|
-
+ (props.rounded === true ? ' is-rounded' : '')
|
|
63
|
-
+ (props.isLoading === true ? ' is-loading' : '');
|
|
64
|
-
|
|
65
|
-
if (!isNullOrUndefined(props.icon)) {
|
|
66
|
-
return (
|
|
67
|
-
<ButtonWithIcon
|
|
68
|
-
{...props}
|
|
69
|
-
className={className}
|
|
70
|
-
onClick={props.onClick}
|
|
71
|
-
icon={props.icon as ElementIcon}
|
|
72
|
-
/>
|
|
73
|
-
);
|
|
74
|
-
} else {
|
|
75
|
-
return (
|
|
76
|
-
<SimpleButton
|
|
77
|
-
{...props}
|
|
78
|
-
className={className}
|
|
79
|
-
onClick={props.onClick}
|
|
80
|
-
/>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { ElementIcon } from "../types";
|
|
2
|
-
|
|
3
|
-
/** Button types according to Bulma framework */
|
|
4
|
-
export type ButtonType =
|
|
5
|
-
'default' /** color: transparent */
|
|
6
|
-
| 'primary' /** color: seawave green */
|
|
7
|
-
| 'link' /** color: blue-violet */
|
|
8
|
-
| 'info' /** color: sky-blue */
|
|
9
|
-
| 'success' /** color: green */
|
|
10
|
-
| 'warning' /** color: yellow */
|
|
11
|
-
| 'danger' /** color: red */
|
|
12
|
-
| 'white' /** color: white */
|
|
13
|
-
| 'light' /** color: light-gray */
|
|
14
|
-
| 'dark' /** color: dark-gray */
|
|
15
|
-
| 'black' /** color: black */
|
|
16
|
-
| 'text' /** Underline text with color: gray */
|
|
17
|
-
| 'ghost' /** Blue underline text with color: transparent */
|
|
18
|
-
;
|
|
19
|
-
|
|
20
|
-
export type SimpleButtonProps = {
|
|
21
|
-
/** Button class name*/
|
|
22
|
-
className: string;
|
|
23
|
-
|
|
24
|
-
/** Button click handler */
|
|
25
|
-
onClick?: () => void;
|
|
26
|
-
|
|
27
|
-
/** Button caption */
|
|
28
|
-
caption?: string;
|
|
29
|
-
|
|
30
|
-
/** Disabled attribute value*/
|
|
31
|
-
disabled?: boolean;
|
|
32
|
-
|
|
33
|
-
/** Title on hover */
|
|
34
|
-
title?: string;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export type ButtonWithIconProps = SimpleButtonProps & {
|
|
38
|
-
/** Icon configuration */
|
|
39
|
-
icon: ElementIcon;
|
|
40
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { SelectableItem } from "../../types";
|
|
2
|
-
|
|
3
|
-
/** Dropdown item props */
|
|
4
|
-
interface DropdownItemProps {
|
|
5
|
-
/** Item to present in dropdown */
|
|
6
|
-
item: SelectableItem;
|
|
7
|
-
|
|
8
|
-
/** Is item selected*/
|
|
9
|
-
selected: boolean;
|
|
10
|
-
|
|
11
|
-
/** Item click handler */
|
|
12
|
-
onClick: (event: React.MouseEvent<HTMLLIElement>) => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** Single item in dropdown component */
|
|
16
|
-
const DropdownItem = ({ item, selected, onClick }: DropdownItemProps): JSX.Element => {
|
|
17
|
-
return (
|
|
18
|
-
<li
|
|
19
|
-
key={item.id}
|
|
20
|
-
className={`app-dropdown-item dropdown-item${selected ? " is-active" : ""}`}
|
|
21
|
-
onClick={onClick}
|
|
22
|
-
data-dropdown-item-value={item.value}
|
|
23
|
-
title={item.displayValue}
|
|
24
|
-
>
|
|
25
|
-
{item.displayValue}
|
|
26
|
-
</li>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export default DropdownItem;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { MouseEvent } from 'react';
|
|
2
|
-
|
|
3
|
-
import { isNullOrEmpty, isNullOrUndefined } from "@bodynarf/utils/common";
|
|
4
|
-
|
|
5
|
-
import Icon from 'src/components/icon';
|
|
6
|
-
|
|
7
|
-
import { SelectableItem } from "../../types";
|
|
8
|
-
|
|
9
|
-
interface DropdownLabelProps {
|
|
10
|
-
/** Caption when no items selected */
|
|
11
|
-
caption: string;
|
|
12
|
-
|
|
13
|
-
/** Can user deselect */
|
|
14
|
-
deselectable: boolean;
|
|
15
|
-
|
|
16
|
-
/** Selected item */
|
|
17
|
-
selectedItem?: SelectableItem;
|
|
18
|
-
|
|
19
|
-
/** Click handler*/
|
|
20
|
-
onClick: (event: MouseEvent<HTMLLabelElement>) => void;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Label component */
|
|
24
|
-
const DropdownLabel = ({ caption, selectedItem, onClick, deselectable }: DropdownLabelProps): JSX.Element => {
|
|
25
|
-
const itemSelected = !isNullOrUndefined(selectedItem);
|
|
26
|
-
|
|
27
|
-
const text = itemSelected
|
|
28
|
-
? selectedItem?.displayValue
|
|
29
|
-
: caption;
|
|
30
|
-
|
|
31
|
-
const deselectVisible = deselectable && itemSelected;
|
|
32
|
-
|
|
33
|
-
const className = [
|
|
34
|
-
"dropdown-trigger",
|
|
35
|
-
"app-dropdown__label",
|
|
36
|
-
itemSelected ? "" : "app-dropdown__label--default",
|
|
37
|
-
"button"
|
|
38
|
-
].filter(x => !isNullOrEmpty(x))
|
|
39
|
-
.join(" ");
|
|
40
|
-
|
|
41
|
-
return (
|
|
42
|
-
<label
|
|
43
|
-
className={className}
|
|
44
|
-
onClick={onClick}
|
|
45
|
-
>
|
|
46
|
-
{deselectVisible &&
|
|
47
|
-
<Icon className="plus-lg" />
|
|
48
|
-
}
|
|
49
|
-
<span
|
|
50
|
-
className={deselectVisible ? "mx-2" : "mr-2"}
|
|
51
|
-
title={itemSelected ? text : undefined}
|
|
52
|
-
>
|
|
53
|
-
{text}
|
|
54
|
-
</span>
|
|
55
|
-
<Icon className="arrow-up" />
|
|
56
|
-
</label>
|
|
57
|
-
);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export default DropdownLabel;
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { MouseEvent, useCallback, useId, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import './dropdown.scss';
|
|
4
|
-
|
|
5
|
-
import { isNullOrEmpty, isNullOrUndefined } from '@bodynarf/utils/common';
|
|
6
|
-
|
|
7
|
-
import { useComponentOutsideClick } from 'src/hooks/useComponentOutsideClick';
|
|
8
|
-
|
|
9
|
-
import { SelectableItem } from './types';
|
|
10
|
-
import { BaseElementProps } from '../types';
|
|
11
|
-
|
|
12
|
-
import DropdownItem from './components/dropdownItem/dropdownItem';
|
|
13
|
-
import DropdownLabel from './components/dropdownLabel/dropdownLabel';
|
|
14
|
-
|
|
15
|
-
export type DropdownProps = BaseElementProps & {
|
|
16
|
-
/** Items which can be selected */
|
|
17
|
-
items: Array<SelectableItem>;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Selected value.
|
|
21
|
-
* Must be stored outside
|
|
22
|
-
*/
|
|
23
|
-
value?: SelectableItem;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Action to update selected value,
|
|
27
|
-
* which stored outside
|
|
28
|
-
*/
|
|
29
|
-
onSelect: (item?: SelectableItem) => void;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Caption.
|
|
33
|
-
* Appears only no element selected
|
|
34
|
-
*/
|
|
35
|
-
caption: string;
|
|
36
|
-
|
|
37
|
-
/** Hide dropdown list when its opened and user click outside */
|
|
38
|
-
hideOnOuterClick: boolean;
|
|
39
|
-
|
|
40
|
-
/** Can user deselect */
|
|
41
|
-
deselectable?: boolean;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Dropdown component */
|
|
45
|
-
const Dropdown = ({ value, items, onSelect, caption, deselectable, className, hideOnOuterClick }: DropdownProps): JSX.Element => {
|
|
46
|
-
const id = useId();
|
|
47
|
-
|
|
48
|
-
const [isListVisible, setListVisible] = useState<boolean>(false);
|
|
49
|
-
|
|
50
|
-
const onItemClick = useCallback(
|
|
51
|
-
(event: React.MouseEvent<HTMLLIElement>) => {
|
|
52
|
-
const target = event.target as HTMLLIElement;
|
|
53
|
-
|
|
54
|
-
if (isNullOrUndefined(target)) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const dataValue = target.dataset['dropdownItemValue'];
|
|
59
|
-
|
|
60
|
-
if (isNullOrEmpty(dataValue)) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const item = items.find(x => x.value === dataValue);
|
|
65
|
-
|
|
66
|
-
if (isNullOrUndefined(item)) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (value === item) {
|
|
71
|
-
setListVisible(false);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
onSelect(item);
|
|
76
|
-
setListVisible(false);
|
|
77
|
-
}, [setListVisible, value, items, onSelect]);
|
|
78
|
-
|
|
79
|
-
const onLabelClick = useCallback(
|
|
80
|
-
(event: MouseEvent<HTMLLabelElement>): void => {
|
|
81
|
-
const target = event.target as HTMLElement;
|
|
82
|
-
|
|
83
|
-
if (isNullOrUndefined(target)) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (target.classList.contains("bi-plus-lg")) {
|
|
88
|
-
onSelect(undefined);
|
|
89
|
-
} else {
|
|
90
|
-
setListVisible(state => !state);
|
|
91
|
-
}
|
|
92
|
-
}, [onSelect, setListVisible]);
|
|
93
|
-
|
|
94
|
-
useComponentOutsideClick(
|
|
95
|
-
`[data-dropdown-id="${id}"]`, isListVisible,
|
|
96
|
-
() => setListVisible(false),
|
|
97
|
-
hideOnOuterClick,
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
const classNames: string = [
|
|
101
|
-
"app-dropdown",
|
|
102
|
-
isListVisible ? "is-active" : "",
|
|
103
|
-
className,
|
|
104
|
-
"dropdown"
|
|
105
|
-
]
|
|
106
|
-
.filter(x => !isNullOrEmpty(x))
|
|
107
|
-
.join(" ");
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<div
|
|
111
|
-
key={id}
|
|
112
|
-
className={classNames}
|
|
113
|
-
data-dropdown-id={id}
|
|
114
|
-
>
|
|
115
|
-
<DropdownLabel
|
|
116
|
-
caption={caption}
|
|
117
|
-
deselectable={deselectable === true}
|
|
118
|
-
selectedItem={value}
|
|
119
|
-
onClick={onLabelClick}
|
|
120
|
-
/>
|
|
121
|
-
<div className="dropdown-menu">
|
|
122
|
-
{items.length > 0
|
|
123
|
-
? <ul className="dropdown-content">
|
|
124
|
-
{items.map(item =>
|
|
125
|
-
<DropdownItem
|
|
126
|
-
key={item.id}
|
|
127
|
-
item={item}
|
|
128
|
-
selected={value?.value === item.value}
|
|
129
|
-
onClick={onItemClick}
|
|
130
|
-
/>
|
|
131
|
-
)}
|
|
132
|
-
</ul>
|
|
133
|
-
: <span className="dropdown-content dropdown-item">No items found</span>
|
|
134
|
-
}
|
|
135
|
-
</div>
|
|
136
|
-
</div>
|
|
137
|
-
);
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
export default Dropdown;
|
|
141
|
-
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import './icon.scss';
|
|
2
|
-
|
|
3
|
-
import { IconSize } from '../types';
|
|
4
|
-
|
|
5
|
-
/** Icon component props */
|
|
6
|
-
export type IconProps = {
|
|
7
|
-
/**
|
|
8
|
-
* Class name for icon.
|
|
9
|
-
* Used to display icon from bootstrap-icons
|
|
10
|
-
*/
|
|
11
|
-
className: string;
|
|
12
|
-
|
|
13
|
-
/** Icon size */
|
|
14
|
-
size?: IconSize;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const sizeToClassMap: Map<IconSize, string> = new Map([
|
|
18
|
-
['small', ' app-icon--smal'],
|
|
19
|
-
['medium', ''],
|
|
20
|
-
['large', ' app-icon--large']
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Icon component. Based on bootstrap icons
|
|
25
|
-
*/
|
|
26
|
-
export default function Icon(props: IconProps): JSX.Element {
|
|
27
|
-
const size: IconSize = props.size || 'medium';
|
|
28
|
-
|
|
29
|
-
const className = `app-icon bi bi-${props.className}${sizeToClassMap.get(size)}`;
|
|
30
|
-
|
|
31
|
-
return (
|
|
32
|
-
<i className={className}></i>
|
|
33
|
-
);
|
|
34
|
-
}
|