components-test-pb 0.0.3 → 0.0.5
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/dist/Components/Button/Button.d.ts +3 -0
- package/dist/Components/Button/Button.js +8 -0
- package/dist/Components/Button/Button.types.d.ts +14 -0
- package/dist/Components/Button/Button.types.js +1 -0
- package/dist/Components/Button/index.d.ts +5 -0
- package/dist/Components/Button/index.js +4 -0
- package/dist/Components/Button/renderButton.d.ts +3 -0
- package/dist/Components/Button/renderButton.js +6 -0
- package/dist/Components/Button/useButton.d.ts +2 -0
- package/dist/Components/Button/useButton.js +11 -0
- package/dist/Components/Button/useButtonStyles.styles.d.ts +4 -0
- package/dist/Components/Button/useButtonStyles.styles.js +108 -0
- package/dist/Components/Text/useTextStyles.styles.js +43 -15
- package/dist/Theme/tokens.d.ts +81 -0
- package/dist/Theme/tokens.js +80 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/src/Components/Button/Button.tsx +13 -0
- package/src/Components/Button/Button.types.ts +25 -0
- package/src/Components/Button/index.ts +11 -0
- package/src/Components/Button/renderButton.tsx +9 -0
- package/src/Components/Button/useButton.ts +16 -0
- package/src/Components/Button/useButtonStyles.styles.ts +151 -0
- package/src/Components/Text/useText.ts +0 -1
- package/src/Components/Text/useTextStyles.styles.ts +25 -15
- package/src/Theme/tokens.ts +98 -0
- package/src/index.ts +13 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useButton } from './useButton.js';
|
|
2
|
+
import { renderButton } from './renderButton.js';
|
|
3
|
+
import { useButtonStyles } from './useButtonStyles.styles.js';
|
|
4
|
+
export const Button = (props) => {
|
|
5
|
+
const state = useButton(props);
|
|
6
|
+
useButtonStyles(state);
|
|
7
|
+
return renderButton(state);
|
|
8
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ComponentProps, ComponentState, Slot } from '../../Types/compose/types.js';
|
|
2
|
+
import { DistributiveOmit } from '../../Types/utils/types.js';
|
|
3
|
+
export type ButtonSlots = {
|
|
4
|
+
root: NonNullable<Slot<'a'>>;
|
|
5
|
+
};
|
|
6
|
+
export type ButtonSize = 'small' | 'medium' | 'large';
|
|
7
|
+
export type ButtonProps = ComponentProps<ButtonSlots> & {
|
|
8
|
+
appearance?: 'secondary' | 'primary' | 'tertiary';
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
shape?: 'rounded' | 'circular' | 'square';
|
|
11
|
+
size?: ButtonSize;
|
|
12
|
+
};
|
|
13
|
+
export type ButtonBaseProps = DistributiveOmit<ButtonProps, 'appearance' | 'size' | 'shape'>;
|
|
14
|
+
export type ButtonState = ComponentState<ButtonSlots> & Required<Pick<ButtonProps, 'appearance' | 'disabled' | 'shape' | 'size'>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { ButtonSlots, ButtonProps, ButtonBaseProps, ButtonState } from './Button.types.js';
|
|
2
|
+
export { Button } from './Button.js';
|
|
3
|
+
export { useButton } from './useButton.js';
|
|
4
|
+
export { renderButton } from './renderButton.js';
|
|
5
|
+
export { useButtonStyles } from './useButtonStyles.styles.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const useButton = (props) => {
|
|
2
|
+
const { appearance, shape, size, disabled, ...buttonProps } = props;
|
|
3
|
+
return {
|
|
4
|
+
appearance: appearance ?? 'secondary',
|
|
5
|
+
shape: shape ?? 'rounded',
|
|
6
|
+
size: size ?? 'medium',
|
|
7
|
+
disabled: disabled ?? false,
|
|
8
|
+
components: { root: buttonProps.as ?? 'button' },
|
|
9
|
+
root: { as: buttonProps.as ?? 'button', ...buttonProps },
|
|
10
|
+
};
|
|
11
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { makeStyles, makeResetStyles, mergeClasses, shorthands } from 'css-engine-test-pb';
|
|
2
|
+
import { Tokens } from '../../Theme/tokens.js';
|
|
3
|
+
export const buttonClassNames = {
|
|
4
|
+
root: 'Button'
|
|
5
|
+
};
|
|
6
|
+
const useRootBaseClassName = makeResetStyles({
|
|
7
|
+
alignItems: 'center',
|
|
8
|
+
boxSizing: 'border-box',
|
|
9
|
+
display: 'inline-flex',
|
|
10
|
+
justifyContent: 'center',
|
|
11
|
+
textDecorationLine: 'none',
|
|
12
|
+
verticalAlign: 'center',
|
|
13
|
+
margin: 0,
|
|
14
|
+
overflow: 'hidden',
|
|
15
|
+
backgroundColor: Tokens.colorNeutralBackground1,
|
|
16
|
+
color: Tokens.colorNeutralForeground1,
|
|
17
|
+
border: `${Tokens.strokeWidthThin} solid ${Tokens.colorNeutralStroke1}`,
|
|
18
|
+
fontFamily: Tokens.fontFamilyBase,
|
|
19
|
+
outlineStyle: 'none',
|
|
20
|
+
':hover': {
|
|
21
|
+
backgroundColor: Tokens.colorNeutralBackground1Hover,
|
|
22
|
+
borderColor: Tokens.colorNeutralStroke1Hover,
|
|
23
|
+
color: Tokens.colorNeutralForeground1,
|
|
24
|
+
cursor: 'pointer'
|
|
25
|
+
},
|
|
26
|
+
':hover:active,:active:focus-visible': {
|
|
27
|
+
backgroundColor: Tokens.colorNeutralBackground1Pressed,
|
|
28
|
+
borderColor: Tokens.colorNeutralStroke1Pressed,
|
|
29
|
+
color: Tokens.colorNeutralForeground1,
|
|
30
|
+
outlineStyle: 'none'
|
|
31
|
+
},
|
|
32
|
+
padding: '5px 12px',
|
|
33
|
+
minWidth: '96px',
|
|
34
|
+
borderRadius: Tokens.borderRadiusMedium,
|
|
35
|
+
fontSize: Tokens.fontSize300,
|
|
36
|
+
fontWeight: Tokens.fontWeightRegular,
|
|
37
|
+
lineHeight: Tokens.lineHeight300,
|
|
38
|
+
transitionDuration: Tokens.durationNormal,
|
|
39
|
+
transitionProperty: 'background, border, color',
|
|
40
|
+
transitionTimingFunction: Tokens.curveEasy
|
|
41
|
+
});
|
|
42
|
+
const useRootStyles = makeStyles({
|
|
43
|
+
primary: {
|
|
44
|
+
backgroundColor: Tokens.colorBrandBackground,
|
|
45
|
+
...shorthands.borderColor('transparent'),
|
|
46
|
+
color: Tokens.colorBrandForeground1,
|
|
47
|
+
':hover': {
|
|
48
|
+
backgroundColor: Tokens.colorBrandBackgroundHover,
|
|
49
|
+
...shorthands.borderColor('transparent'),
|
|
50
|
+
color: Tokens.colorBrandForeground1Hover
|
|
51
|
+
},
|
|
52
|
+
':hover:active,:active:focus-visible': {
|
|
53
|
+
backgroundColor: Tokens.colorBrandBackgroundPressed,
|
|
54
|
+
...shorthands.borderColor('transparent'),
|
|
55
|
+
color: Tokens.colorBrandForeground1Hover
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
secondary: {},
|
|
59
|
+
tertiary: {
|
|
60
|
+
backgroundColor: 'transparent',
|
|
61
|
+
...shorthands.borderColor('transparent'),
|
|
62
|
+
color: Tokens.colorNeutralForeground1,
|
|
63
|
+
':hover': {
|
|
64
|
+
backgroundColor: 'transparent',
|
|
65
|
+
...shorthands.borderColor('transparent'),
|
|
66
|
+
color: Tokens.colorBrandBackground
|
|
67
|
+
},
|
|
68
|
+
':hover:active,:active:focus-visible': {
|
|
69
|
+
backgroundColor: 'transparent',
|
|
70
|
+
...shorthands.borderColor('transparent'),
|
|
71
|
+
color: Tokens.colorBrandBackgroundPressed
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
circular: { borderRadius: Tokens.borderRadiusCircular },
|
|
75
|
+
rounded: {},
|
|
76
|
+
square: { borderRadius: Tokens.borderRadiusNone },
|
|
77
|
+
small: {
|
|
78
|
+
minWidth: '64px',
|
|
79
|
+
padding: '3px 8px',
|
|
80
|
+
borderRadius: Tokens.borderRadiusMedium,
|
|
81
|
+
fontSize: Tokens.fontSize200,
|
|
82
|
+
fontWeight: Tokens.fontWeightRegular,
|
|
83
|
+
lineHeight: Tokens.lineHeight200
|
|
84
|
+
},
|
|
85
|
+
medium: {},
|
|
86
|
+
large: {
|
|
87
|
+
minWidth: '96px',
|
|
88
|
+
padding: '8px 16px',
|
|
89
|
+
borderRadius: Tokens.borderRadiusMedium,
|
|
90
|
+
fontSize: Tokens.fontSize400,
|
|
91
|
+
fontWeight: Tokens.fontWeightMedium,
|
|
92
|
+
lineHeight: Tokens.lineHeight400
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const useRootDisabledstyles = makeStyles({
|
|
96
|
+
base: {},
|
|
97
|
+
primary: {},
|
|
98
|
+
secondary: {},
|
|
99
|
+
tertiary: {}
|
|
100
|
+
});
|
|
101
|
+
export const useButtonStyles = (state) => {
|
|
102
|
+
const rootBaseClassName = useRootBaseClassName();
|
|
103
|
+
const rootStyles = useRootStyles();
|
|
104
|
+
const rootDisabledStyles = useRootDisabledstyles();
|
|
105
|
+
const { appearance, disabled, shape, size } = state;
|
|
106
|
+
state.root.className = mergeClasses(buttonClassNames.root, rootBaseClassName, appearance && rootStyles[appearance], rootStyles[size], rootStyles[shape], disabled && rootDisabledStyles.base, appearance && disabled && rootDisabledStyles[appearance], state.root.className);
|
|
107
|
+
return state;
|
|
108
|
+
};
|
|
@@ -1,38 +1,66 @@
|
|
|
1
1
|
import { makeStyles, mergeClasses } from 'css-engine-test-pb';
|
|
2
|
+
import { Tokens } from '../../Theme/tokens.js';
|
|
2
3
|
export const textClassNames = {
|
|
3
4
|
root: 'Text'
|
|
4
5
|
};
|
|
5
6
|
const useStyles = makeStyles({
|
|
6
7
|
root: {
|
|
7
8
|
fontFamily: 'Neue Montreal',
|
|
8
|
-
fontSize:
|
|
9
|
-
lineHeight:
|
|
10
|
-
fontWeight:
|
|
9
|
+
fontSize: Tokens.fontSize300,
|
|
10
|
+
lineHeight: Tokens.lineHeight300,
|
|
11
|
+
fontWeight: Tokens.fontWeightRegular,
|
|
11
12
|
display: 'inline',
|
|
12
13
|
whiteSpace: 'normal',
|
|
13
14
|
overflow: 'visible',
|
|
14
15
|
textOverflow: 'clip'
|
|
15
16
|
},
|
|
16
|
-
size100: {
|
|
17
|
-
|
|
17
|
+
size100: {
|
|
18
|
+
fontSize: Tokens.fontSize100,
|
|
19
|
+
lineHeight: Tokens.lineHeight100
|
|
20
|
+
},
|
|
21
|
+
size200: {
|
|
22
|
+
fontSize: Tokens.fontSize200,
|
|
23
|
+
lineHeight: Tokens.lineHeight200
|
|
24
|
+
},
|
|
18
25
|
size300: {},
|
|
19
|
-
size400: {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
size400: {
|
|
27
|
+
fontSize: Tokens.fontSize400,
|
|
28
|
+
lineHeight: Tokens.lineHeight400
|
|
29
|
+
},
|
|
30
|
+
size500: {
|
|
31
|
+
fontSize: Tokens.fontSize500,
|
|
32
|
+
lineHeight: Tokens.lineHeight500
|
|
33
|
+
},
|
|
34
|
+
size600: {
|
|
35
|
+
fontSize: Tokens.fontSize600,
|
|
36
|
+
lineHeight: Tokens.lineHeight600
|
|
37
|
+
},
|
|
38
|
+
size700: {
|
|
39
|
+
fontSize: Tokens.fontSize700,
|
|
40
|
+
lineHeight: Tokens.lineHeight700
|
|
41
|
+
},
|
|
42
|
+
size800: {
|
|
43
|
+
fontSize: Tokens.fontSize800,
|
|
44
|
+
lineHeight: Tokens.lineHeight800
|
|
45
|
+
},
|
|
46
|
+
size900: {
|
|
47
|
+
fontSize: Tokens.fontSize900,
|
|
48
|
+
lineHeight: Tokens.lineHeight900
|
|
49
|
+
},
|
|
50
|
+
size1000: {
|
|
51
|
+
fontSize: Tokens.fontSize1000,
|
|
52
|
+
lineHeight: Tokens.lineHeight1000
|
|
53
|
+
},
|
|
26
54
|
monospace: {},
|
|
27
55
|
numeric: {},
|
|
28
56
|
weightMedium: {
|
|
29
|
-
fontWeight:
|
|
57
|
+
fontWeight: Tokens.fontWeightMedium
|
|
30
58
|
},
|
|
31
59
|
weightSemibold: {
|
|
32
|
-
fontWeight:
|
|
60
|
+
fontWeight: Tokens.fontWeightSemibold
|
|
33
61
|
},
|
|
34
62
|
weightBold: {
|
|
35
|
-
fontWeight:
|
|
63
|
+
fontWeight: Tokens.fontWeightBold
|
|
36
64
|
}
|
|
37
65
|
});
|
|
38
66
|
export const useTextStyles = (state) => {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export declare const Tokens: {
|
|
2
|
+
readonly fontFamilyBase: "Neue Montreal";
|
|
3
|
+
readonly fontFamilyMonospace: "'Courier New', Courier, monospace";
|
|
4
|
+
readonly fontFamilyNumeric: "Neue Montreal";
|
|
5
|
+
readonly fontSize100: "10px";
|
|
6
|
+
readonly fontSize200: "12px";
|
|
7
|
+
readonly fontSize300: "14px";
|
|
8
|
+
readonly fontSize400: "16px";
|
|
9
|
+
readonly fontSize500: "20px";
|
|
10
|
+
readonly fontSize600: "24px";
|
|
11
|
+
readonly fontSize700: "28px";
|
|
12
|
+
readonly fontSize800: "32px";
|
|
13
|
+
readonly fontSize900: "40px";
|
|
14
|
+
readonly fontSize1000: "68px";
|
|
15
|
+
readonly lineHeight100: "14px";
|
|
16
|
+
readonly lineHeight200: "16px";
|
|
17
|
+
readonly lineHeight300: "20px";
|
|
18
|
+
readonly lineHeight400: "22px";
|
|
19
|
+
readonly lineHeight500: "28px";
|
|
20
|
+
readonly lineHeight600: "32px";
|
|
21
|
+
readonly lineHeight700: "36px";
|
|
22
|
+
readonly lineHeight800: "40px";
|
|
23
|
+
readonly lineHeight900: "52px";
|
|
24
|
+
readonly lineHeight1000: "92px";
|
|
25
|
+
readonly fontWeightRegular: 450;
|
|
26
|
+
readonly fontWeightMedium: 530;
|
|
27
|
+
readonly fontWeightSemibold: 700;
|
|
28
|
+
readonly fontWeightBold: 800;
|
|
29
|
+
readonly borderRadiusNone: "0px";
|
|
30
|
+
readonly borderRadiusSmall: "2px";
|
|
31
|
+
readonly borderRadiusMedium: "4px";
|
|
32
|
+
readonly borderRadiusLarge: "6px";
|
|
33
|
+
readonly borderRadiusXLarge: "8px";
|
|
34
|
+
readonly borderRadiusCircular: "9999px";
|
|
35
|
+
readonly strokeWidthThin: "1px";
|
|
36
|
+
readonly strokeWidthThick: "2px";
|
|
37
|
+
readonly strokeWidthThicker: "4px";
|
|
38
|
+
readonly spacingXXS: "2px";
|
|
39
|
+
readonly spacingXS: "4px";
|
|
40
|
+
readonly spacingSNudge: "6px";
|
|
41
|
+
readonly spacingS: "8px";
|
|
42
|
+
readonly spacingMNudge: "10px";
|
|
43
|
+
readonly spacingM: "12px";
|
|
44
|
+
readonly spacingL: "16px";
|
|
45
|
+
readonly spacingXL: "20px";
|
|
46
|
+
readonly spacingXXL: "24px";
|
|
47
|
+
readonly spacingXXXL: "32px";
|
|
48
|
+
readonly colorNeutralForeground1: "#242424";
|
|
49
|
+
readonly colorNeutralForegroundDisabled: "#bdbdbd";
|
|
50
|
+
readonly colorNeutralForegroundOnBrand: "#ffffff";
|
|
51
|
+
readonly colorNeutralBackground1: "#ffffff";
|
|
52
|
+
readonly colorNeutralBackground1Hover: "#f5f5f5";
|
|
53
|
+
readonly colorNeutralBackground1Pressed: "#e0e0e0";
|
|
54
|
+
readonly colorNeutralBackground3: "#f5f5f5";
|
|
55
|
+
readonly colorNeutralBackgroundDisabled: "#f0f0f0";
|
|
56
|
+
readonly colorNeutralStroke1: "#cccccc";
|
|
57
|
+
readonly colorNeutralStroke1Hover: "#b3b3b3";
|
|
58
|
+
readonly colorNeutralStroke1Pressed: "#999999";
|
|
59
|
+
readonly colorNeutralStrokeDisabled: "#e0e0e0";
|
|
60
|
+
readonly colorBrandBackground: "#312dfb";
|
|
61
|
+
readonly colorBrandBackgroundHover: "#2b28e2";
|
|
62
|
+
readonly colorBrandBackgroundPressed: "#2522c9";
|
|
63
|
+
readonly colorBrandStroke1: "#312dfb";
|
|
64
|
+
readonly colorBrandStroke1Hover: "#2b28e2";
|
|
65
|
+
readonly colorBrandStroke1Pressed: "#2522c9";
|
|
66
|
+
readonly colorBrandForeground1: "#ffffff";
|
|
67
|
+
readonly colorBrandForeground1Hover: "#ffffff";
|
|
68
|
+
readonly colorBrandForeground1Pressed: "#ffffff";
|
|
69
|
+
readonly colorSubtleBackground: "transparent";
|
|
70
|
+
readonly colorSubtleBackgroundHover: "#f5f5f5";
|
|
71
|
+
readonly colorSubtleBackgroundPressed: "#e0e0e0";
|
|
72
|
+
readonly colorTransparentBackground: "transparent";
|
|
73
|
+
readonly colorTransparentStroke: "transparent";
|
|
74
|
+
readonly durationNormal: "150ms";
|
|
75
|
+
readonly durationFast: "100ms";
|
|
76
|
+
readonly durationSlow: "300ms";
|
|
77
|
+
readonly curveEasy: "cubic-bezier(0.33,0,0.67,1)";
|
|
78
|
+
readonly curveDecelerate: "cubic-bezier(0,0,0,1)";
|
|
79
|
+
readonly curveAccelerate: "cubic-bezier(1,0,1,1)";
|
|
80
|
+
};
|
|
81
|
+
export type Tokens = typeof Tokens;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export const Tokens = {
|
|
2
|
+
fontFamilyBase: 'Neue Montreal',
|
|
3
|
+
fontFamilyMonospace: "'Courier New', Courier, monospace",
|
|
4
|
+
fontFamilyNumeric: 'Neue Montreal',
|
|
5
|
+
fontSize100: '10px',
|
|
6
|
+
fontSize200: '12px',
|
|
7
|
+
fontSize300: '14px',
|
|
8
|
+
fontSize400: '16px',
|
|
9
|
+
fontSize500: '20px',
|
|
10
|
+
fontSize600: '24px',
|
|
11
|
+
fontSize700: '28px',
|
|
12
|
+
fontSize800: '32px',
|
|
13
|
+
fontSize900: '40px',
|
|
14
|
+
fontSize1000: '68px',
|
|
15
|
+
lineHeight100: '14px',
|
|
16
|
+
lineHeight200: '16px',
|
|
17
|
+
lineHeight300: '20px',
|
|
18
|
+
lineHeight400: '22px',
|
|
19
|
+
lineHeight500: '28px',
|
|
20
|
+
lineHeight600: '32px',
|
|
21
|
+
lineHeight700: '36px',
|
|
22
|
+
lineHeight800: '40px',
|
|
23
|
+
lineHeight900: '52px',
|
|
24
|
+
lineHeight1000: '92px',
|
|
25
|
+
fontWeightRegular: 450,
|
|
26
|
+
fontWeightMedium: 530,
|
|
27
|
+
fontWeightSemibold: 700,
|
|
28
|
+
fontWeightBold: 800,
|
|
29
|
+
borderRadiusNone: '0px',
|
|
30
|
+
borderRadiusSmall: '2px',
|
|
31
|
+
borderRadiusMedium: '4px',
|
|
32
|
+
borderRadiusLarge: '6px',
|
|
33
|
+
borderRadiusXLarge: '8px',
|
|
34
|
+
borderRadiusCircular: '9999px',
|
|
35
|
+
strokeWidthThin: '1px',
|
|
36
|
+
strokeWidthThick: '2px',
|
|
37
|
+
strokeWidthThicker: '4px',
|
|
38
|
+
spacingXXS: '2px',
|
|
39
|
+
spacingXS: '4px',
|
|
40
|
+
spacingSNudge: '6px',
|
|
41
|
+
spacingS: '8px',
|
|
42
|
+
spacingMNudge: '10px',
|
|
43
|
+
spacingM: '12px',
|
|
44
|
+
spacingL: '16px',
|
|
45
|
+
spacingXL: '20px',
|
|
46
|
+
spacingXXL: '24px',
|
|
47
|
+
spacingXXXL: '32px',
|
|
48
|
+
colorNeutralForeground1: '#242424',
|
|
49
|
+
colorNeutralForegroundDisabled: '#bdbdbd',
|
|
50
|
+
colorNeutralForegroundOnBrand: '#ffffff',
|
|
51
|
+
colorNeutralBackground1: '#ffffff',
|
|
52
|
+
colorNeutralBackground1Hover: '#f5f5f5',
|
|
53
|
+
colorNeutralBackground1Pressed: '#e0e0e0',
|
|
54
|
+
colorNeutralBackground3: '#f5f5f5',
|
|
55
|
+
colorNeutralBackgroundDisabled: '#f0f0f0',
|
|
56
|
+
colorNeutralStroke1: '#cccccc',
|
|
57
|
+
colorNeutralStroke1Hover: '#b3b3b3',
|
|
58
|
+
colorNeutralStroke1Pressed: '#999999',
|
|
59
|
+
colorNeutralStrokeDisabled: '#e0e0e0',
|
|
60
|
+
colorBrandBackground: '#312dfb',
|
|
61
|
+
colorBrandBackgroundHover: '#2b28e2',
|
|
62
|
+
colorBrandBackgroundPressed: '#2522c9',
|
|
63
|
+
colorBrandStroke1: '#312dfb',
|
|
64
|
+
colorBrandStroke1Hover: '#2b28e2',
|
|
65
|
+
colorBrandStroke1Pressed: '#2522c9',
|
|
66
|
+
colorBrandForeground1: '#ffffff',
|
|
67
|
+
colorBrandForeground1Hover: '#ffffff',
|
|
68
|
+
colorBrandForeground1Pressed: '#ffffff',
|
|
69
|
+
colorSubtleBackground: 'transparent',
|
|
70
|
+
colorSubtleBackgroundHover: '#f5f5f5',
|
|
71
|
+
colorSubtleBackgroundPressed: '#e0e0e0',
|
|
72
|
+
colorTransparentBackground: 'transparent',
|
|
73
|
+
colorTransparentStroke: 'transparent',
|
|
74
|
+
durationNormal: '150ms',
|
|
75
|
+
durationFast: '100ms',
|
|
76
|
+
durationSlow: '300ms',
|
|
77
|
+
curveEasy: 'cubic-bezier(0.33,0,0.67,1)',
|
|
78
|
+
curveDecelerate: 'cubic-bezier(0,0,0,1)',
|
|
79
|
+
curveAccelerate: 'cubic-bezier(1,0,1,1)',
|
|
80
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { Text, useText, renderText, useTextStyles } from './Components/Text/index.js';
|
|
2
2
|
export type { TextSlots, TextProps, TextPresetProps, TextState } from './Components/Text/index.js';
|
|
3
|
+
export { Button, useButton, renderButton, useButtonStyles } from './Components/Button/index.js';
|
|
4
|
+
export type { ButtonSlots, ButtonProps, ButtonBaseProps, ButtonState } from './Components/Button/index.js';
|
|
3
5
|
export * from './Types/compose/index.js';
|
|
4
6
|
export * from './Types/utils/index.js';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FC } from '../../Types/utils/types.js';
|
|
2
|
+
import type { ButtonProps } from './Button.types.js';
|
|
3
|
+
import { useButton } from './useButton.js';
|
|
4
|
+
import { renderButton } from './renderButton.js';
|
|
5
|
+
import { useButtonStyles } from './useButtonStyles.styles.js';
|
|
6
|
+
|
|
7
|
+
export const Button: FC<ButtonProps> = (props) => {
|
|
8
|
+
const state = useButton(props);
|
|
9
|
+
|
|
10
|
+
useButtonStyles(state);
|
|
11
|
+
|
|
12
|
+
return renderButton(state);
|
|
13
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ComponentProps, ComponentState, Slot } from '../../Types/compose/types.js';
|
|
2
|
+
import { DistributiveOmit } from '../../Types/utils/types.js';
|
|
3
|
+
|
|
4
|
+
export type ButtonSlots = {
|
|
5
|
+
root: NonNullable<Slot<'a'>>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type ButtonSize = 'small' | 'medium' | 'large';
|
|
9
|
+
|
|
10
|
+
export type ButtonProps = ComponentProps<ButtonSlots> & {
|
|
11
|
+
appearance?: 'secondary' | 'primary' | 'tertiary';
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
shape?: 'rounded' | 'circular' | 'square';
|
|
14
|
+
size?: ButtonSize;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type ButtonBaseProps = DistributiveOmit<ButtonProps, 'appearance' | 'size' | 'shape'>;
|
|
18
|
+
|
|
19
|
+
export type ButtonState = ComponentState<ButtonSlots> &
|
|
20
|
+
Required<
|
|
21
|
+
Pick<
|
|
22
|
+
ButtonProps,
|
|
23
|
+
'appearance' | 'disabled' | 'shape' | 'size'
|
|
24
|
+
>
|
|
25
|
+
>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
ButtonSlots,
|
|
3
|
+
ButtonProps,
|
|
4
|
+
ButtonBaseProps,
|
|
5
|
+
ButtonState
|
|
6
|
+
} from './Button.types.js';
|
|
7
|
+
|
|
8
|
+
export { Button } from './Button.js';
|
|
9
|
+
export { useButton } from './useButton.js';
|
|
10
|
+
export { renderButton } from './renderButton.js';
|
|
11
|
+
export { useButtonStyles } from './useButtonStyles.styles.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Element } from '../../Types/utils/types.js';
|
|
2
|
+
import type { ButtonState } from './Button.types.js';
|
|
3
|
+
|
|
4
|
+
export const renderButton = (state: ButtonState): Element => {
|
|
5
|
+
const Root = state.components.root;
|
|
6
|
+
const { as: _as, ...rootProps } = state.root;
|
|
7
|
+
|
|
8
|
+
return <Root {...rootProps} />;
|
|
9
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ButtonProps, ButtonState } from './Button.types.js';
|
|
2
|
+
|
|
3
|
+
export const useButton = (props: ButtonProps): ButtonState => {
|
|
4
|
+
const { appearance, shape, size, disabled, ...buttonProps } = props;
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
appearance: appearance ?? 'secondary',
|
|
8
|
+
shape: shape ?? 'rounded',
|
|
9
|
+
size: size ?? 'medium',
|
|
10
|
+
disabled: disabled ?? false,
|
|
11
|
+
|
|
12
|
+
components: { root: buttonProps.as ?? 'button' },
|
|
13
|
+
|
|
14
|
+
root: { as: buttonProps.as ?? 'button', ...buttonProps } as ButtonState['root'],
|
|
15
|
+
};
|
|
16
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { makeStyles, makeResetStyles, mergeClasses, shorthands } from 'css-engine-test-pb';
|
|
2
|
+
import { SlotClassNames } from '../../Types/compose/types.js';
|
|
3
|
+
import { ButtonSlots, ButtonState } from './Button.types.js';
|
|
4
|
+
import { Tokens } from '../../Theme/tokens.js';
|
|
5
|
+
|
|
6
|
+
export const buttonClassNames: SlotClassNames<ButtonSlots> = {
|
|
7
|
+
root: 'Button'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const useRootBaseClassName = makeResetStyles({
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
boxSizing: 'border-box',
|
|
13
|
+
display: 'inline-flex',
|
|
14
|
+
justifyContent: 'center',
|
|
15
|
+
textDecorationLine: 'none',
|
|
16
|
+
verticalAlign: 'center',
|
|
17
|
+
|
|
18
|
+
margin: 0,
|
|
19
|
+
overflow: 'hidden',
|
|
20
|
+
|
|
21
|
+
backgroundColor: Tokens.colorNeutralBackground1,
|
|
22
|
+
color: Tokens.colorNeutralForeground1,
|
|
23
|
+
border: `${Tokens.strokeWidthThin} solid ${Tokens.colorNeutralStroke1}`,
|
|
24
|
+
|
|
25
|
+
fontFamily: Tokens.fontFamilyBase,
|
|
26
|
+
outlineStyle: 'none',
|
|
27
|
+
|
|
28
|
+
':hover': {
|
|
29
|
+
backgroundColor: Tokens.colorNeutralBackground1Hover,
|
|
30
|
+
borderColor: Tokens.colorNeutralStroke1Hover,
|
|
31
|
+
color: Tokens.colorNeutralForeground1,
|
|
32
|
+
|
|
33
|
+
cursor: 'pointer'
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
':hover:active,:active:focus-visible': {
|
|
37
|
+
backgroundColor: Tokens.colorNeutralBackground1Pressed,
|
|
38
|
+
borderColor: Tokens.colorNeutralStroke1Pressed,
|
|
39
|
+
color: Tokens.colorNeutralForeground1,
|
|
40
|
+
|
|
41
|
+
outlineStyle: 'none'
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
padding: '5px 12px',
|
|
45
|
+
minWidth: '96px',
|
|
46
|
+
borderRadius: Tokens.borderRadiusMedium,
|
|
47
|
+
|
|
48
|
+
fontSize: Tokens.fontSize300,
|
|
49
|
+
fontWeight: Tokens.fontWeightRegular,
|
|
50
|
+
lineHeight: Tokens.lineHeight300,
|
|
51
|
+
|
|
52
|
+
transitionDuration: Tokens.durationNormal,
|
|
53
|
+
transitionProperty: 'background, border, color',
|
|
54
|
+
transitionTimingFunction: Tokens.curveEasy
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const useRootStyles = makeStyles({
|
|
58
|
+
primary: {
|
|
59
|
+
backgroundColor: Tokens.colorBrandBackground,
|
|
60
|
+
...shorthands.borderColor('transparent'),
|
|
61
|
+
color: Tokens.colorBrandForeground1,
|
|
62
|
+
|
|
63
|
+
':hover': {
|
|
64
|
+
backgroundColor: Tokens.colorBrandBackgroundHover,
|
|
65
|
+
...shorthands.borderColor('transparent'),
|
|
66
|
+
color: Tokens.colorBrandForeground1Hover
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
':hover:active,:active:focus-visible': {
|
|
70
|
+
backgroundColor: Tokens.colorBrandBackgroundPressed,
|
|
71
|
+
...shorthands.borderColor('transparent'),
|
|
72
|
+
color: Tokens.colorBrandForeground1Hover
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
secondary: {},
|
|
76
|
+
tertiary: {
|
|
77
|
+
backgroundColor: 'transparent',
|
|
78
|
+
...shorthands.borderColor('transparent'),
|
|
79
|
+
color: Tokens.colorNeutralForeground1,
|
|
80
|
+
|
|
81
|
+
':hover': {
|
|
82
|
+
backgroundColor: 'transparent',
|
|
83
|
+
...shorthands.borderColor('transparent'),
|
|
84
|
+
color: Tokens.colorBrandBackground
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
':hover:active,:active:focus-visible': {
|
|
88
|
+
backgroundColor: 'transparent',
|
|
89
|
+
...shorthands.borderColor('transparent'),
|
|
90
|
+
color: Tokens.colorBrandBackgroundPressed
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
circular: { borderRadius: Tokens.borderRadiusCircular },
|
|
95
|
+
rounded: {},
|
|
96
|
+
square: { borderRadius: Tokens.borderRadiusNone },
|
|
97
|
+
|
|
98
|
+
small: {
|
|
99
|
+
minWidth: '64px',
|
|
100
|
+
padding: '3px 8px',
|
|
101
|
+
borderRadius: Tokens.borderRadiusMedium,
|
|
102
|
+
|
|
103
|
+
fontSize: Tokens.fontSize200,
|
|
104
|
+
fontWeight: Tokens.fontWeightRegular,
|
|
105
|
+
lineHeight: Tokens.lineHeight200
|
|
106
|
+
},
|
|
107
|
+
medium: {},
|
|
108
|
+
large: {
|
|
109
|
+
minWidth: '96px',
|
|
110
|
+
padding: '8px 16px',
|
|
111
|
+
borderRadius: Tokens.borderRadiusMedium,
|
|
112
|
+
|
|
113
|
+
fontSize: Tokens.fontSize400,
|
|
114
|
+
fontWeight: Tokens.fontWeightMedium,
|
|
115
|
+
lineHeight: Tokens.lineHeight400
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const useRootDisabledstyles = makeStyles({
|
|
120
|
+
base: {},
|
|
121
|
+
primary: {},
|
|
122
|
+
secondary: {},
|
|
123
|
+
tertiary: {}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export const useButtonStyles = (state: ButtonState): ButtonState => {
|
|
127
|
+
|
|
128
|
+
const rootBaseClassName = useRootBaseClassName();
|
|
129
|
+
|
|
130
|
+
const rootStyles = useRootStyles();
|
|
131
|
+
const rootDisabledStyles = useRootDisabledstyles();
|
|
132
|
+
|
|
133
|
+
const { appearance, disabled, shape, size } = state;
|
|
134
|
+
|
|
135
|
+
state.root.className = mergeClasses(
|
|
136
|
+
buttonClassNames.root,
|
|
137
|
+
rootBaseClassName,
|
|
138
|
+
|
|
139
|
+
appearance && rootStyles[appearance],
|
|
140
|
+
|
|
141
|
+
rootStyles[size],
|
|
142
|
+
rootStyles[shape],
|
|
143
|
+
|
|
144
|
+
disabled && rootDisabledStyles.base,
|
|
145
|
+
appearance && disabled && rootDisabledStyles[appearance],
|
|
146
|
+
|
|
147
|
+
state.root.className,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
return state;
|
|
151
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { makeStyles, mergeClasses } from 'css-engine-test-pb';
|
|
2
2
|
import { SlotClassNames } from '../../Types/compose/types.js';
|
|
3
3
|
import { TextSlots, TextState } from './Text.types.js';
|
|
4
|
+
import { Tokens } from '../../Theme/tokens.js';
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export const textClassNames: SlotClassNames<TextSlots> = {
|
|
@@ -10,43 +11,52 @@ export const textClassNames: SlotClassNames<TextSlots> = {
|
|
|
10
11
|
const useStyles = makeStyles({
|
|
11
12
|
root: {
|
|
12
13
|
fontFamily: 'Neue Montreal',
|
|
13
|
-
fontSize:
|
|
14
|
-
lineHeight:
|
|
15
|
-
fontWeight:
|
|
14
|
+
fontSize: Tokens.fontSize300,
|
|
15
|
+
lineHeight: Tokens.lineHeight300,
|
|
16
|
+
fontWeight: Tokens.fontWeightRegular,
|
|
16
17
|
display: 'inline',
|
|
17
18
|
whiteSpace: 'normal',
|
|
18
19
|
overflow: 'visible',
|
|
19
20
|
textOverflow: 'clip'
|
|
20
21
|
},
|
|
21
22
|
size100: {
|
|
22
|
-
|
|
23
|
+
fontSize: Tokens.fontSize100,
|
|
24
|
+
lineHeight: Tokens.lineHeight100
|
|
23
25
|
},
|
|
24
26
|
size200: {
|
|
25
|
-
|
|
27
|
+
fontSize: Tokens.fontSize200,
|
|
28
|
+
lineHeight: Tokens.lineHeight200
|
|
26
29
|
},
|
|
27
30
|
size300: {
|
|
28
31
|
|
|
29
32
|
},
|
|
30
33
|
size400: {
|
|
31
|
-
|
|
34
|
+
fontSize: Tokens.fontSize400,
|
|
35
|
+
lineHeight: Tokens.lineHeight400
|
|
32
36
|
},
|
|
33
37
|
size500: {
|
|
34
|
-
|
|
38
|
+
fontSize: Tokens.fontSize500,
|
|
39
|
+
lineHeight: Tokens.lineHeight500
|
|
35
40
|
},
|
|
36
41
|
size600: {
|
|
37
|
-
|
|
42
|
+
fontSize: Tokens.fontSize600,
|
|
43
|
+
lineHeight: Tokens.lineHeight600
|
|
38
44
|
},
|
|
39
45
|
size700: {
|
|
40
|
-
|
|
46
|
+
fontSize: Tokens.fontSize700,
|
|
47
|
+
lineHeight: Tokens.lineHeight700
|
|
41
48
|
},
|
|
42
49
|
size800: {
|
|
43
|
-
|
|
50
|
+
fontSize: Tokens.fontSize800,
|
|
51
|
+
lineHeight: Tokens.lineHeight800
|
|
44
52
|
},
|
|
45
53
|
size900: {
|
|
46
|
-
|
|
54
|
+
fontSize: Tokens.fontSize900,
|
|
55
|
+
lineHeight: Tokens.lineHeight900
|
|
47
56
|
},
|
|
48
57
|
size1000: {
|
|
49
|
-
|
|
58
|
+
fontSize: Tokens.fontSize1000,
|
|
59
|
+
lineHeight: Tokens.lineHeight1000
|
|
50
60
|
},
|
|
51
61
|
monospace: {
|
|
52
62
|
|
|
@@ -55,13 +65,13 @@ const useStyles = makeStyles({
|
|
|
55
65
|
|
|
56
66
|
},
|
|
57
67
|
weightMedium: {
|
|
58
|
-
fontWeight:
|
|
68
|
+
fontWeight: Tokens.fontWeightMedium
|
|
59
69
|
},
|
|
60
70
|
weightSemibold: {
|
|
61
|
-
fontWeight:
|
|
71
|
+
fontWeight: Tokens.fontWeightSemibold
|
|
62
72
|
},
|
|
63
73
|
weightBold: {
|
|
64
|
-
fontWeight:
|
|
74
|
+
fontWeight: Tokens.fontWeightBold
|
|
65
75
|
}
|
|
66
76
|
});
|
|
67
77
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export const Tokens = {
|
|
2
|
+
fontFamilyBase: 'Neue Montreal',
|
|
3
|
+
fontFamilyMonospace: "'Courier New', Courier, monospace",
|
|
4
|
+
fontFamilyNumeric: 'Neue Montreal',
|
|
5
|
+
|
|
6
|
+
fontSize100: '10px',
|
|
7
|
+
fontSize200: '12px',
|
|
8
|
+
fontSize300: '14px',
|
|
9
|
+
fontSize400: '16px',
|
|
10
|
+
fontSize500: '20px',
|
|
11
|
+
fontSize600: '24px',
|
|
12
|
+
fontSize700: '28px',
|
|
13
|
+
fontSize800: '32px',
|
|
14
|
+
fontSize900: '40px',
|
|
15
|
+
fontSize1000: '68px',
|
|
16
|
+
|
|
17
|
+
lineHeight100: '14px',
|
|
18
|
+
lineHeight200: '16px',
|
|
19
|
+
lineHeight300: '20px',
|
|
20
|
+
lineHeight400: '22px',
|
|
21
|
+
lineHeight500: '28px',
|
|
22
|
+
lineHeight600: '32px',
|
|
23
|
+
lineHeight700: '36px',
|
|
24
|
+
lineHeight800: '40px',
|
|
25
|
+
lineHeight900: '52px',
|
|
26
|
+
lineHeight1000: '92px',
|
|
27
|
+
|
|
28
|
+
fontWeightRegular: 450,
|
|
29
|
+
fontWeightMedium: 530,
|
|
30
|
+
fontWeightSemibold: 700,
|
|
31
|
+
fontWeightBold: 800,
|
|
32
|
+
|
|
33
|
+
borderRadiusNone: '0px',
|
|
34
|
+
borderRadiusSmall: '2px',
|
|
35
|
+
borderRadiusMedium: '4px',
|
|
36
|
+
borderRadiusLarge: '6px',
|
|
37
|
+
borderRadiusXLarge: '8px',
|
|
38
|
+
borderRadiusCircular: '9999px',
|
|
39
|
+
|
|
40
|
+
strokeWidthThin: '1px',
|
|
41
|
+
strokeWidthThick: '2px',
|
|
42
|
+
strokeWidthThicker: '4px',
|
|
43
|
+
|
|
44
|
+
spacingXXS: '2px',
|
|
45
|
+
spacingXS: '4px',
|
|
46
|
+
spacingSNudge: '6px',
|
|
47
|
+
spacingS: '8px',
|
|
48
|
+
spacingMNudge: '10px',
|
|
49
|
+
spacingM: '12px',
|
|
50
|
+
spacingL: '16px',
|
|
51
|
+
spacingXL: '20px',
|
|
52
|
+
spacingXXL: '24px',
|
|
53
|
+
spacingXXXL: '32px',
|
|
54
|
+
|
|
55
|
+
colorNeutralForeground1: '#242424',
|
|
56
|
+
colorNeutralForegroundDisabled: '#bdbdbd',
|
|
57
|
+
colorNeutralForegroundOnBrand: '#ffffff',
|
|
58
|
+
|
|
59
|
+
colorNeutralBackground1: '#ffffff',
|
|
60
|
+
colorNeutralBackground1Hover: '#f5f5f5',
|
|
61
|
+
colorNeutralBackground1Pressed: '#e0e0e0',
|
|
62
|
+
colorNeutralBackground3: '#f5f5f5',
|
|
63
|
+
colorNeutralBackgroundDisabled: '#f0f0f0',
|
|
64
|
+
|
|
65
|
+
colorNeutralStroke1: '#cccccc',
|
|
66
|
+
colorNeutralStroke1Hover: '#b3b3b3',
|
|
67
|
+
colorNeutralStroke1Pressed: '#999999',
|
|
68
|
+
colorNeutralStrokeDisabled: '#e0e0e0',
|
|
69
|
+
|
|
70
|
+
colorBrandBackground: '#312dfb',
|
|
71
|
+
colorBrandBackgroundHover: '#2b28e2',
|
|
72
|
+
colorBrandBackgroundPressed: '#2522c9',
|
|
73
|
+
|
|
74
|
+
colorBrandStroke1: '#312dfb',
|
|
75
|
+
colorBrandStroke1Hover: '#2b28e2',
|
|
76
|
+
colorBrandStroke1Pressed: '#2522c9',
|
|
77
|
+
|
|
78
|
+
colorBrandForeground1: '#ffffff',
|
|
79
|
+
colorBrandForeground1Hover: '#ffffff',
|
|
80
|
+
colorBrandForeground1Pressed: '#ffffff',
|
|
81
|
+
|
|
82
|
+
colorSubtleBackground: 'transparent',
|
|
83
|
+
colorSubtleBackgroundHover: '#f5f5f5',
|
|
84
|
+
colorSubtleBackgroundPressed: '#e0e0e0',
|
|
85
|
+
|
|
86
|
+
colorTransparentBackground: 'transparent',
|
|
87
|
+
colorTransparentStroke: 'transparent',
|
|
88
|
+
|
|
89
|
+
durationNormal: '150ms',
|
|
90
|
+
durationFast: '100ms',
|
|
91
|
+
durationSlow: '300ms',
|
|
92
|
+
curveEasy: 'cubic-bezier(0.33,0,0.67,1)',
|
|
93
|
+
curveDecelerate: 'cubic-bezier(0,0,0,1)',
|
|
94
|
+
curveAccelerate: 'cubic-bezier(1,0,1,1)',
|
|
95
|
+
|
|
96
|
+
} as const;
|
|
97
|
+
|
|
98
|
+
export type Tokens = typeof Tokens;
|
package/src/index.ts
CHANGED
|
@@ -11,5 +11,18 @@ export type {
|
|
|
11
11
|
TextState
|
|
12
12
|
} from './Components/Text/index.js';
|
|
13
13
|
|
|
14
|
+
export {
|
|
15
|
+
Button,
|
|
16
|
+
useButton,
|
|
17
|
+
renderButton,
|
|
18
|
+
useButtonStyles
|
|
19
|
+
} from './Components/Button/index.js';
|
|
20
|
+
export type {
|
|
21
|
+
ButtonSlots,
|
|
22
|
+
ButtonProps,
|
|
23
|
+
ButtonBaseProps,
|
|
24
|
+
ButtonState
|
|
25
|
+
} from './Components/Button/index.js';
|
|
26
|
+
|
|
14
27
|
export * from './Types/compose/index.js';
|
|
15
28
|
export * from './Types/utils/index.js';
|