@dtdot/lego 2.0.0-2 → 2.0.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/build/components/ActionMenu/ActionMenu.component.d.ts +4 -1
- package/build/components/ActionMenu/ActionMenu.component.js +2 -16
- package/build/components/Button/Button.component.d.ts +5 -1
- package/build/components/Button/Button.component.js +63 -10
- package/build/theme/dark.theme.js +16 -6
- package/build/theme/default.theme.js +6 -0
- package/build/theme/helpers/getThemeVariantColours.d.ts +1 -5
- package/build/theme/helpers/getThemeVariantColours.js +3 -15
- package/build/theme/theme.types.d.ts +2 -0
- package/package.json +3 -1
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { IconProp } from '@fortawesome/fontawesome-svg-core';
|
|
3
3
|
import { ColourVariant } from '../../theme/theme.types';
|
|
4
|
+
import { ButtonSize } from '../Button/Button.component';
|
|
4
5
|
export interface ActionMenuProps {
|
|
5
6
|
'children': React.ReactNode;
|
|
6
7
|
'variant'?: ColourVariant;
|
|
8
|
+
'size'?: ButtonSize;
|
|
7
9
|
'icon'?: IconProp;
|
|
10
|
+
'text'?: string;
|
|
8
11
|
'data-cy'?: string;
|
|
9
12
|
}
|
|
10
13
|
declare const ActionMenu: {
|
|
11
|
-
({ children, variant, icon, "data-cy": dataCy }: ActionMenuProps): JSX.Element;
|
|
14
|
+
({ children, variant, size, icon, text, "data-cy": dataCy }: ActionMenuProps): JSX.Element;
|
|
12
15
|
Item: ({ children, onClick, "data-cy": dataCy }: import("./_ActionMenuItem.component").ActionMenuItemProps) => JSX.Element;
|
|
13
16
|
Checkbox: ({ children, checked, onClick, "data-cy": dataCy }: import("./_ActionMenuCheckbox.component").ActionMenuCheckboxProps) => JSX.Element;
|
|
14
17
|
};
|
|
@@ -1,26 +1,14 @@
|
|
|
1
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
2
1
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
3
2
|
import ReactDOM from 'react-dom';
|
|
4
3
|
import { usePopper } from 'react-popper';
|
|
5
4
|
import { faEllipsisV } from '@fortawesome/free-solid-svg-icons';
|
|
6
|
-
import styled from 'styled-components';
|
|
7
5
|
import Button from '../Button/Button.component';
|
|
8
6
|
import ActionMenuContext from './ActionMenu.context';
|
|
9
7
|
import ActionMenuCheckbox from './_ActionMenuCheckbox.component';
|
|
10
8
|
import ActionMenuItem from './_ActionMenuItem.component';
|
|
11
9
|
import ActionMenuPanel from './_ActionMenuPanel.component';
|
|
12
|
-
const IconWrapper = styled.div `
|
|
13
|
-
width: 0;
|
|
14
|
-
height: 100%;
|
|
15
|
-
display: flex;
|
|
16
|
-
align-items: center;
|
|
17
|
-
justify-content: center;
|
|
18
|
-
`;
|
|
19
|
-
const StyledIcon = styled(FontAwesomeIcon) `
|
|
20
|
-
font-size: 18px;
|
|
21
|
-
`;
|
|
22
10
|
const offsetFn = () => [70, 4];
|
|
23
|
-
const ActionMenu = ({ children, variant, icon, 'data-cy': dataCy }) => {
|
|
11
|
+
const ActionMenu = ({ children, variant, size, icon, text, 'data-cy': dataCy }) => {
|
|
24
12
|
const [shown, setShown] = useState(false);
|
|
25
13
|
const [referenceElement, setReferenceElement] = useState();
|
|
26
14
|
const [popperElement, setPopperElement] = useState();
|
|
@@ -46,9 +34,7 @@ const ActionMenu = ({ children, variant, icon, 'data-cy': dataCy }) => {
|
|
|
46
34
|
};
|
|
47
35
|
}, [handleGlobalClick, popperElement]);
|
|
48
36
|
return (React.createElement(React.Fragment, null,
|
|
49
|
-
React.createElement(Button, { variant: variant, "data-cy": dataCy || 'action-menu-button', ref: setReferenceElement, onClick: () => setShown(true) },
|
|
50
|
-
React.createElement(IconWrapper, null,
|
|
51
|
-
React.createElement(StyledIcon, { icon: icon || faEllipsisV }))),
|
|
37
|
+
React.createElement(Button, { variant: variant, size: size, icon: icon || faEllipsisV, "data-cy": dataCy || 'action-menu-button', ref: setReferenceElement, onClick: () => setShown(true) }, text),
|
|
52
38
|
shown &&
|
|
53
39
|
ReactDOM.createPortal(React.createElement("div", { ref: setPopperElement, style: styles.popper, ...attributes.popper },
|
|
54
40
|
React.createElement(ActionMenuContext.Provider, { value: { closeActionMenu: () => setShown(false) } },
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { IconProp } from '@fortawesome/fontawesome-svg-core';
|
|
2
3
|
import { ColourVariant } from '../../theme/theme.types';
|
|
4
|
+
export type ButtonSize = 'sm' | 'md';
|
|
3
5
|
export interface ButtonProps {
|
|
4
|
-
'children'
|
|
6
|
+
'children'?: React.ReactNode;
|
|
5
7
|
'loading'?: boolean;
|
|
6
8
|
'variant'?: ColourVariant;
|
|
9
|
+
'size'?: ButtonSize;
|
|
7
10
|
'type'?: 'submit' | 'button';
|
|
11
|
+
'icon'?: IconProp;
|
|
8
12
|
'onClick'?: () => void;
|
|
9
13
|
'data-cy'?: string;
|
|
10
14
|
}
|
|
@@ -1,15 +1,50 @@
|
|
|
1
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
1
2
|
import React, { useContext } from 'react';
|
|
2
3
|
import styled, { keyframes } from 'styled-components';
|
|
3
4
|
import getThemeVariantColours from '../../theme/helpers/getThemeVariantColours';
|
|
4
5
|
import ButtonContext from './Button.context';
|
|
6
|
+
const getButtonHeightPx = (size) => {
|
|
7
|
+
switch (size) {
|
|
8
|
+
case 'sm':
|
|
9
|
+
return '32px';
|
|
10
|
+
case 'md':
|
|
11
|
+
return '48px';
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const getButtonPaddingPx = (size) => {
|
|
15
|
+
switch (size) {
|
|
16
|
+
case 'sm':
|
|
17
|
+
return '0 12px';
|
|
18
|
+
case 'md':
|
|
19
|
+
return '0 24px';
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const getIconContainerSizePx = (size) => {
|
|
23
|
+
switch (size) {
|
|
24
|
+
case 'sm':
|
|
25
|
+
return { width: '32px', height: '32px' };
|
|
26
|
+
case 'md':
|
|
27
|
+
return { width: '48px', height: '48px' };
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const IconOuter = styled.span `
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
justify-content: center;
|
|
34
|
+
|
|
35
|
+
color: ${(props) => getThemeVariantColours(props.variant, props.theme).contrastText};
|
|
36
|
+
background-color: ${(props) => getThemeVariantColours(props.variant, props.theme).darker};
|
|
37
|
+
|
|
38
|
+
height: ${(props) => getIconContainerSizePx(props.size).height};
|
|
39
|
+
width: ${(props) => getIconContainerSizePx(props.size).width};
|
|
40
|
+
`;
|
|
5
41
|
const StyledButton = styled.button `
|
|
6
42
|
outline: none;
|
|
7
43
|
box-shadow: none;
|
|
8
44
|
border: none;
|
|
9
45
|
|
|
10
46
|
cursor: pointer;
|
|
11
|
-
|
|
12
|
-
padding: 0 24px;
|
|
47
|
+
padding: 0;
|
|
13
48
|
|
|
14
49
|
font-size: ${(props) => props.theme.fonts.default.size};
|
|
15
50
|
font-family: ${(props) => props.theme.fonts.default.family};
|
|
@@ -20,30 +55,44 @@ const StyledButton = styled.button `
|
|
|
20
55
|
border-radius: 2px;
|
|
21
56
|
|
|
22
57
|
// Props defined by the context
|
|
23
|
-
height: ${(props) => props.height ||
|
|
58
|
+
height: ${(props) => props.height || getButtonHeightPx(props.size)};
|
|
24
59
|
width: ${(props) => props.width};
|
|
25
60
|
align-self: ${(props) => props.alignSelf};
|
|
26
61
|
margin-top: ${(props) => props.marginTop};
|
|
27
62
|
|
|
28
63
|
&:hover {
|
|
29
64
|
background-color: ${(props) => getThemeVariantColours(props.variant, props.theme).hover};
|
|
65
|
+
|
|
66
|
+
${IconOuter} {
|
|
67
|
+
background-color: ${(props) => getThemeVariantColours(props.variant, props.theme).darkerHover};
|
|
68
|
+
}
|
|
30
69
|
}
|
|
31
70
|
`;
|
|
71
|
+
const ButtonInner = styled.div `
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
`;
|
|
75
|
+
const ButtonTextContainer = styled.span `
|
|
76
|
+
padding: ${(props) => getButtonPaddingPx(props.size)};
|
|
77
|
+
`;
|
|
32
78
|
const spinAnimation = keyframes `
|
|
33
79
|
0% { transform: rotate(0deg); }
|
|
34
80
|
100% { transform: rotate(360deg); }
|
|
35
81
|
`;
|
|
82
|
+
const SpinnerContainer = styled.span `
|
|
83
|
+
padding: 0 24px;
|
|
84
|
+
`;
|
|
36
85
|
const ButtonSpinner = styled.div `
|
|
37
86
|
display: inline-block;
|
|
38
|
-
width:
|
|
39
|
-
height:
|
|
87
|
+
width: ${(props) => getButtonHeightPx(props.size)};
|
|
88
|
+
height: ${(props) => getButtonHeightPx(props.size)};
|
|
40
89
|
|
|
41
90
|
&:after {
|
|
42
91
|
content: ' ';
|
|
43
92
|
display: block;
|
|
44
|
-
width: 24px;
|
|
45
|
-
height: 24px;
|
|
46
|
-
margin: 10px;
|
|
93
|
+
width: ${(props) => (props.size === 'md' ? '24px' : '16px')};
|
|
94
|
+
height: ${(props) => (props.size === 'md' ? '24px' : '16px')};
|
|
95
|
+
margin: ${(props) => (props.size === 'md' ? '10px' : '6px')};
|
|
47
96
|
border-radius: 50%;
|
|
48
97
|
border: 2px solid ${(props) => getThemeVariantColours(props.variant, props.theme).contrastText};
|
|
49
98
|
border-color: ${(props) => getThemeVariantColours(props.variant, props.theme).contrastText} transparent
|
|
@@ -54,8 +103,12 @@ const ButtonSpinner = styled.div `
|
|
|
54
103
|
}
|
|
55
104
|
`;
|
|
56
105
|
const Button = React.forwardRef(function Button(props, ref) {
|
|
57
|
-
const { children, loading, variant = 'primary', type = 'button', onClick, 'data-cy': dataCy } = props;
|
|
106
|
+
const { children, loading, variant = 'primary', size = 'md', type = 'button', icon, onClick, 'data-cy': dataCy, } = props;
|
|
58
107
|
const { width, height, alignSelf, marginTop } = useContext(ButtonContext);
|
|
59
|
-
return (React.createElement(StyledButton, { ref: ref, width: width, height: height, alignSelf: alignSelf, marginTop: marginTop, variant: variant, type: type, onClick: onClick, "data-cy": dataCy || 'button' }, loading ? React.createElement(
|
|
108
|
+
return (React.createElement(StyledButton, { ref: ref, width: width, height: height, alignSelf: alignSelf, marginTop: marginTop, variant: variant, size: size, type: type, onClick: onClick, "data-cy": dataCy || 'button' }, loading ? (React.createElement(SpinnerContainer, null,
|
|
109
|
+
React.createElement(ButtonSpinner, { "data-cy": 'button-loading-spinner', variant: variant, size: size }))) : (React.createElement(ButtonInner, null,
|
|
110
|
+
children && React.createElement(ButtonTextContainer, { size: size }, children),
|
|
111
|
+
icon && (React.createElement(IconOuter, { variant: variant, size: size },
|
|
112
|
+
React.createElement(FontAwesomeIcon, { icon: icon })))))));
|
|
60
113
|
});
|
|
61
114
|
export default Button;
|
|
@@ -1,21 +1,31 @@
|
|
|
1
|
+
import tinycolour from 'tinycolor2';
|
|
2
|
+
const primaryBase = '#94b8e3';
|
|
3
|
+
const secondaryBase = '#424448';
|
|
4
|
+
const tertiaryBase = '#5c5f67';
|
|
1
5
|
const darkTheme = {
|
|
2
6
|
name: 'dark',
|
|
3
7
|
colours: {
|
|
4
8
|
background: '#424448',
|
|
5
9
|
overlayBackground: '#a4caf9',
|
|
6
10
|
primary: {
|
|
7
|
-
main:
|
|
8
|
-
hover:
|
|
11
|
+
main: primaryBase,
|
|
12
|
+
hover: tinycolour(primaryBase).lighten(2).toString(),
|
|
13
|
+
darker: tinycolour(primaryBase).darken(10).toString(),
|
|
14
|
+
darkerHover: tinycolour(primaryBase).darken(10).lighten(2).toString(),
|
|
9
15
|
contrastText: '#191919',
|
|
10
16
|
},
|
|
11
17
|
secondary: {
|
|
12
|
-
main:
|
|
13
|
-
hover:
|
|
18
|
+
main: secondaryBase,
|
|
19
|
+
hover: tinycolour(secondaryBase).lighten(5).toString(),
|
|
20
|
+
darker: secondaryBase,
|
|
21
|
+
darkerHover: tinycolour(secondaryBase).lighten(5).toString(),
|
|
14
22
|
contrastText: '#e2e2e2',
|
|
15
23
|
},
|
|
16
24
|
tertiary: {
|
|
17
|
-
main:
|
|
18
|
-
hover:
|
|
25
|
+
main: tertiaryBase,
|
|
26
|
+
hover: tinycolour(tertiaryBase).lighten(5).toString(),
|
|
27
|
+
darker: tinycolour(tertiaryBase).darken(5).toString(),
|
|
28
|
+
darkerHover: tinycolour(tertiaryBase).darken(5).lighten(5).toString(),
|
|
19
29
|
contrastText: '#e2e2e2',
|
|
20
30
|
},
|
|
21
31
|
defaultFont: '#e2e2e2',
|
|
@@ -7,16 +7,22 @@ const defaultTheme = {
|
|
|
7
7
|
primary: {
|
|
8
8
|
main: colours.grey70,
|
|
9
9
|
hover: 'red',
|
|
10
|
+
darker: colours.grey70,
|
|
11
|
+
darkerHover: colours.grey70,
|
|
10
12
|
contrastText: colours.grey10,
|
|
11
13
|
},
|
|
12
14
|
secondary: {
|
|
13
15
|
main: colours.yellow,
|
|
14
16
|
hover: 'red',
|
|
17
|
+
darker: colours.yellow,
|
|
18
|
+
darkerHover: colours.yellow,
|
|
15
19
|
contrastText: colours.grey90,
|
|
16
20
|
},
|
|
17
21
|
tertiary: {
|
|
18
22
|
main: colours.yellow,
|
|
19
23
|
hover: 'red',
|
|
24
|
+
darker: colours.yellow,
|
|
25
|
+
darkerHover: colours.yellow,
|
|
20
26
|
contrastText: colours.grey90,
|
|
21
27
|
},
|
|
22
28
|
defaultFont: colours.grey90,
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { DefaultTheme } from 'styled-components';
|
|
2
2
|
import { ColourVariant } from '../theme.types';
|
|
3
|
-
declare const _default: (variant: ColourVariant, theme: DefaultTheme) =>
|
|
4
|
-
main: string;
|
|
5
|
-
hover: string;
|
|
6
|
-
contrastText: string;
|
|
7
|
-
};
|
|
3
|
+
declare const _default: (variant: ColourVariant, theme: DefaultTheme) => import("../theme.types").IPalette;
|
|
8
4
|
export default _default;
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
export default (variant, theme) => {
|
|
2
2
|
switch (variant) {
|
|
3
3
|
case 'tertiary':
|
|
4
|
-
return
|
|
5
|
-
main: theme.colours.tertiary.main,
|
|
6
|
-
hover: theme.colours.tertiary.hover,
|
|
7
|
-
contrastText: theme.colours.tertiary.contrastText,
|
|
8
|
-
};
|
|
4
|
+
return theme.colours.tertiary;
|
|
9
5
|
case 'secondary':
|
|
10
|
-
return
|
|
11
|
-
main: theme.colours.secondary.main,
|
|
12
|
-
hover: theme.colours.secondary.hover,
|
|
13
|
-
contrastText: theme.colours.secondary.contrastText,
|
|
14
|
-
};
|
|
6
|
+
return theme.colours.secondary;
|
|
15
7
|
case 'primary':
|
|
16
8
|
default:
|
|
17
|
-
return
|
|
18
|
-
main: theme.colours.primary.main,
|
|
19
|
-
hover: theme.colours.primary.hover,
|
|
20
|
-
contrastText: theme.colours.primary.contrastText,
|
|
21
|
-
};
|
|
9
|
+
return theme.colours.primary;
|
|
22
10
|
}
|
|
23
11
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dtdot/lego",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-3",
|
|
4
4
|
"description": "Some reusable components for building my applications",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"@types/react-dom": "^18.0.9",
|
|
39
39
|
"@types/spark-md5": "^3.0.2",
|
|
40
40
|
"@types/styled-components": "^5.1.26",
|
|
41
|
+
"@types/tinycolor2": "^1.4.3",
|
|
41
42
|
"@types/uuid": "^9.0.0",
|
|
42
43
|
"@typescript-eslint/eslint-plugin": "^5.47.0",
|
|
43
44
|
"@typescript-eslint/parser": "^5.47.0",
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
"react-popper": "^2.3.0",
|
|
70
71
|
"react-use-measure": "^2.1.1",
|
|
71
72
|
"spark-md5": "^3.0.2",
|
|
73
|
+
"tinycolor2": "^1.6.0",
|
|
72
74
|
"uuid": "^9.0.0"
|
|
73
75
|
}
|
|
74
76
|
}
|