paris 0.8.21 → 0.9.0
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/CHANGELOG.md +36 -0
- package/package.json +2 -2
- package/src/helpers/useIsMounted.ts +17 -0
- package/src/helpers/useResizeObserver.ts +97 -0
- package/src/stories/accordion/Accordion.module.scss +4 -4
- package/src/stories/avatar/Avatar.module.scss +1 -1
- package/src/stories/avatar/Avatar.tsx +1 -1
- package/src/stories/button/Button.module.scss +46 -24
- package/src/stories/button/Button.stories.ts +24 -0
- package/src/stories/button/Button.tsx +95 -70
- package/src/stories/callout/Callout.module.scss +7 -7
- package/src/stories/callout/Callout.stories.ts +8 -0
- package/src/stories/callout/Callout.tsx +4 -3
- package/src/stories/card/Card.module.scss +3 -3
- package/src/stories/card/Card.stories.ts +0 -5
- package/src/stories/checkbox/Checkbox.module.scss +19 -6
- package/src/stories/checkbox/Checkbox.tsx +2 -1
- package/src/stories/combobox/Combobox.stories.ts +8 -8
- package/src/stories/combobox/Combobox.tsx +11 -4
- package/src/stories/dialog/Dialog.module.scss +43 -19
- package/src/stories/dialog/Dialog.stories.tsx +40 -0
- package/src/stories/dialog/Dialog.tsx +28 -17
- package/src/stories/drawer/Drawer.module.scss +141 -46
- package/src/stories/drawer/Drawer.stories.tsx +151 -0
- package/src/stories/drawer/Drawer.tsx +100 -103
- package/src/stories/field/Field.stories.ts +1 -1
- package/src/stories/field/Field.tsx +0 -1
- package/src/stories/icon/ArrowRight.tsx +11 -0
- package/src/stories/icon/Check.tsx +11 -0
- package/src/stories/icon/Icon.stories.ts +5 -1
- package/src/stories/icon/index.ts +3 -0
- package/src/stories/input/Input.module.scss +43 -31
- package/src/stories/input/Input.stories.ts +7 -7
- package/src/stories/input/Input.tsx +14 -5
- package/src/stories/menu/Menu.module.scss +6 -6
- package/src/stories/menu/Menu.stories.tsx +24 -28
- package/src/stories/popover/Popover.module.scss +3 -3
- package/src/stories/select/Select.module.scss +38 -16
- package/src/stories/select/Select.stories.ts +24 -12
- package/src/stories/select/Select.tsx +17 -3
- package/src/stories/styledlink/StyledLink.module.scss +2 -2
- package/src/stories/table/Table.module.scss +6 -5
- package/src/stories/table/Table.stories.ts +9 -9
- package/src/stories/table/Table.tsx +7 -1
- package/src/stories/tabs/Tabs.module.scss +168 -27
- package/src/stories/tabs/Tabs.stories.tsx +125 -0
- package/src/stories/tabs/Tabs.tsx +69 -37
- package/src/stories/tag/Tag.module.scss +160 -21
- package/src/stories/tag/Tag.stories.ts +22 -1
- package/src/stories/tag/Tag.tsx +63 -16
- package/src/stories/textarea/TextArea.stories.ts +2 -2
- package/src/stories/textarea/TextArea.tsx +12 -5
- package/src/stories/theme/themes.ts +907 -13
- package/src/stories/theme/tokens.ts +77 -0
- package/src/stories/theme/tw-preflight.css +3 -3
- package/src/stories/tilt/Tilt.stories.tsx +4 -4
- package/src/stories/toast/Toast.module.scss +4 -4
- package/src/stories/tabs/Tabs.stories.ts +0 -39
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# paris
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a8941e5: Tabs: color and styling updates, kind `full`, `barStyle` thick or thin, `backgroundStyle` with glass option
|
|
8
|
+
- ecd7deb: Theme: Revamped tokens and variables with updated structures, plus new materials and blurs
|
|
9
|
+
- a8941e5: Theme: updated “materials” variables, added accent glows to “lighting”
|
|
10
|
+
- a8941e5: Drawer: color and styling updates, new sizes `fullWithMargin` and `fullOnMobile` with tweaked `full` behavior, `bottomPanel` with glass material and removed padding, `additionalActions` available on paginated drawers, `overlayStyle` "greyed" renamed to "grey"
|
|
11
|
+
- a8941e5: Dialog: color and styling updates, `overlayStyle` with default `blur` and option `grey`
|
|
12
|
+
- a8941e5: Callout: color updates, default ArrowRight icon
|
|
13
|
+
- a8941e5: Tag: color and styling updates, `shape` prop for `square` variant with `icon`, `corners` prop for border and radius, planned`and`void`kinds,`colorLevel` to adjust color background
|
|
14
|
+
- a8941e5: Button: color updates, added `medium` size, `corners` prop for border-radius, removed `rounded` shape
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- a8941e5: Accordion: color updates
|
|
19
|
+
- a8941e5: Styled Link: color updates
|
|
20
|
+
- a8941e5: Table: color and styling updates
|
|
21
|
+
- a8941e5: Toast: color updates
|
|
22
|
+
- a8941e5: Popover: color updates
|
|
23
|
+
- a8941e5: Checkbox: color updates
|
|
24
|
+
- a8941e5: Select: color and styling updates, fixed disabled states
|
|
25
|
+
- a8941e5: Menu: color updates
|
|
26
|
+
- a8941e5: TextArea: color updates, enhancer updates to match Input
|
|
27
|
+
- a8941e5: Card: color updates
|
|
28
|
+
- a8941e5: Avatar: color updates
|
|
29
|
+
- a8941e5: Combobox: color and styling updates
|
|
30
|
+
- a8941e5: Icon: `Check` and `ArrowRight`
|
|
31
|
+
- a8941e5: Input: color and styling updates, enhancer color states
|
|
32
|
+
|
|
33
|
+
## 0.8.22
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- 0243ccb: fix(Field): Remove stopPropagation on Field component
|
|
38
|
+
|
|
3
39
|
## 0.8.21
|
|
4
40
|
|
|
5
41
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "paris",
|
|
3
3
|
"author": "Sanil Chawla <sanil@slingshot.fm> (https://sanil.co)",
|
|
4
4
|
"description": "Paris is Slingshot's React design system. It's a collection of reusable components, design tokens, and guidelines that help us build consistent, accessible, and performant user interfaces.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.9.0",
|
|
6
6
|
"homepage": "https://paris.slingshot.fm",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"clsx": "^1.2.1",
|
|
68
68
|
"font-color-contrast": "^11.1.0",
|
|
69
69
|
"framer-motion": "^10.16.4",
|
|
70
|
-
"pte": "^0.
|
|
70
|
+
"pte": "^0.5.0",
|
|
71
71
|
"react-hot-toast": "^2.4.1",
|
|
72
72
|
"react-parallax-tilt": "^1.7.144",
|
|
73
73
|
"react-tiny-popover": "^8.0.4",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copied from https://usehooks-ts.com/react-hook/use-is-mounted
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
4
|
+
|
|
5
|
+
export function useIsMounted(): () => boolean {
|
|
6
|
+
const isMounted = useRef(false);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
isMounted.current = true;
|
|
10
|
+
|
|
11
|
+
return () => {
|
|
12
|
+
isMounted.current = false;
|
|
13
|
+
};
|
|
14
|
+
}, []);
|
|
15
|
+
|
|
16
|
+
return useCallback(() => isMounted.current, []);
|
|
17
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Copied from https://usehooks-ts.com/react-hook/use-resize-observer
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import type { RefObject } from 'react';
|
|
6
|
+
|
|
7
|
+
import { useIsMounted } from './useIsMounted';
|
|
8
|
+
|
|
9
|
+
type Size = {
|
|
10
|
+
width: number | undefined
|
|
11
|
+
height: number | undefined
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type UseResizeObserverOptions<T extends HTMLElement = HTMLElement> = {
|
|
15
|
+
ref: RefObject<T>
|
|
16
|
+
onResize?: (size: Size) => void
|
|
17
|
+
box?: 'border-box' | 'content-box' | 'device-pixel-content-box'
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const initialSize: Size = {
|
|
21
|
+
width: undefined,
|
|
22
|
+
height: undefined,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function useResizeObserver<T extends HTMLElement = HTMLElement>(
|
|
26
|
+
options: UseResizeObserverOptions<T>,
|
|
27
|
+
): Size {
|
|
28
|
+
const { ref, box = 'content-box' } = options;
|
|
29
|
+
const [{ width, height }, setSize] = useState<Size>(initialSize);
|
|
30
|
+
const isMounted = useIsMounted();
|
|
31
|
+
const previousSize = useRef<Size>({ ...initialSize });
|
|
32
|
+
const onResize = useRef<((size: Size) => void) | undefined>(undefined);
|
|
33
|
+
onResize.current = options.onResize;
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (!ref.current) return;
|
|
37
|
+
|
|
38
|
+
if (typeof window === 'undefined' || !('ResizeObserver' in window)) return;
|
|
39
|
+
|
|
40
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
41
|
+
const boxProp = box === 'border-box'
|
|
42
|
+
? 'borderBoxSize'
|
|
43
|
+
: box === 'device-pixel-content-box'
|
|
44
|
+
? 'devicePixelContentBoxSize'
|
|
45
|
+
: 'contentBoxSize';
|
|
46
|
+
|
|
47
|
+
const newWidth = extractSize(entry, boxProp, 'inlineSize');
|
|
48
|
+
const newHeight = extractSize(entry, boxProp, 'blockSize');
|
|
49
|
+
|
|
50
|
+
const hasChanged = previousSize.current.width !== newWidth
|
|
51
|
+
|| previousSize.current.height !== newHeight;
|
|
52
|
+
|
|
53
|
+
if (hasChanged) {
|
|
54
|
+
const newSize: Size = { width: newWidth, height: newHeight };
|
|
55
|
+
previousSize.current.width = newWidth;
|
|
56
|
+
previousSize.current.height = newHeight;
|
|
57
|
+
|
|
58
|
+
if (onResize.current) {
|
|
59
|
+
onResize.current(newSize);
|
|
60
|
+
} else if (isMounted()) {
|
|
61
|
+
setSize(newSize);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
observer.observe(ref.current, { box });
|
|
67
|
+
|
|
68
|
+
return () => {
|
|
69
|
+
observer.disconnect();
|
|
70
|
+
};
|
|
71
|
+
}, [box, ref, isMounted]);
|
|
72
|
+
|
|
73
|
+
return { width, height };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type BoxSizesKey = keyof Pick<
|
|
77
|
+
ResizeObserverEntry,
|
|
78
|
+
'borderBoxSize' | 'contentBoxSize' | 'devicePixelContentBoxSize'
|
|
79
|
+
>;
|
|
80
|
+
|
|
81
|
+
function extractSize(
|
|
82
|
+
entry: ResizeObserverEntry,
|
|
83
|
+
box: BoxSizesKey,
|
|
84
|
+
sizeType: keyof ResizeObserverSize,
|
|
85
|
+
): number | undefined {
|
|
86
|
+
if (!entry[box]) {
|
|
87
|
+
if (box === 'contentBoxSize') {
|
|
88
|
+
return entry.contentRect[sizeType === 'inlineSize' ? 'width' : 'height'];
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return Array.isArray(entry[box])
|
|
94
|
+
? entry[box][0][sizeType]
|
|
95
|
+
: // @ts-ignore Support Firefox's non-standard behavior
|
|
96
|
+
(entry[box][sizeType] as number);
|
|
97
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
.container {
|
|
2
|
-
color: var(--pte-colors-contentPrimary);
|
|
3
|
-
border-bottom: 1px solid var(--pte-colors-
|
|
2
|
+
color: var(--pte-new-colors-contentPrimary);
|
|
3
|
+
border-bottom: 1px solid var(--pte-new-colors-borderSubtle);
|
|
4
4
|
cursor: pointer;
|
|
5
5
|
transition: all var(--pte-animations-duration-relaxed) var(--pte-animations-timing-easeInOutExpo);
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
border-bottom: 1px solid transparent;
|
|
20
20
|
transition: border-bottom-color var(--pte-animations-duration-gradual) var(--pte-animations-timing-easeInOutExpo);
|
|
21
21
|
&.open {
|
|
22
|
-
border-bottom-color: var(--pte-colors-
|
|
22
|
+
border-bottom-color: var(--pte-new-colors-borderSubtle);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -48,6 +48,6 @@
|
|
|
48
48
|
display: flex;
|
|
49
49
|
flex-direction: column;
|
|
50
50
|
gap: 12px;
|
|
51
|
-
background-color: var(--pte-colors-
|
|
51
|
+
background-color: var(--pte-new-colors-overlaySubtle);
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
&:hover {
|
|
23
23
|
cursor: default;
|
|
24
|
-
background-color: var(--pte-colors-
|
|
24
|
+
background-color: var(--pte-new-colors-buttonFillHover);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
&[aria-disabled=false]:active {
|
|
@@ -40,45 +40,47 @@
|
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
.primary {
|
|
43
|
-
color: var(--pte-colors-contentInversePrimary);
|
|
44
|
-
background-color: var(--pte-colors-
|
|
45
|
-
border-color: var(--pte-colors-
|
|
43
|
+
color: var(--pte-new-colors-contentInversePrimary);
|
|
44
|
+
background-color: var(--pte-new-colors-buttonFill);
|
|
45
|
+
border-color: var(--pte-new-colors-buttonFill);
|
|
46
46
|
|
|
47
47
|
&:hover {
|
|
48
|
-
border-color: var(
|
|
48
|
+
border-color: var(-pte-new-colors-buttonFillHover);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
&[aria-disabled=true] {
|
|
52
|
-
color: var(--pte-colors-contentDisabled);
|
|
53
|
-
background-color: var(--pte-colors-
|
|
54
|
-
border-color: var(--pte-colors-
|
|
52
|
+
color: var(--pte-new-colors-contentDisabled);
|
|
53
|
+
background-color: var(--pte-new-colors-buttonFillDisabled);
|
|
54
|
+
border-color: var(--pte-new-colors-buttonFillDisabled);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
.secondary {
|
|
59
|
-
color: var(--pte-colors-contentPrimary);
|
|
59
|
+
color: var(--pte-new-colors-contentPrimary);
|
|
60
60
|
background-color: transparent;
|
|
61
|
-
border-color: var(--pte-colors-
|
|
61
|
+
border-color: var(--pte-new-colors-buttonBorder);
|
|
62
|
+
|
|
63
|
+
&:hover {
|
|
64
|
+
background-color: var(--pte-new-colors-overlayMedium);
|
|
65
|
+
}
|
|
62
66
|
|
|
63
67
|
&[aria-disabled=true] {
|
|
64
|
-
color: var(--pte-colors-contentDisabled);
|
|
65
|
-
border-color: var(--pte-colors-
|
|
68
|
+
color: var(--pte-new-colors-contentDisabled);
|
|
69
|
+
border-color: var(--pte-new-colors-buttonBorderDisabled);
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
.tertiary {
|
|
70
|
-
color: var(--pte-colors-contentPrimary);
|
|
74
|
+
color: var(--pte-new-colors-contentPrimary);
|
|
71
75
|
background-color: transparent;
|
|
72
76
|
border-color: transparent;
|
|
73
|
-
}
|
|
74
77
|
|
|
75
|
-
.secondary, .tertiary {
|
|
76
78
|
&:hover {
|
|
77
|
-
background-color: var(--pte-colors-
|
|
79
|
+
background-color: var(--pte-new-colors-overlayMedium);
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
&[aria-disabled=true] {
|
|
81
|
-
color: var(--pte-colors-contentDisabled);
|
|
83
|
+
color: var(--pte-new-colors-contentDisabled);
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -92,6 +94,11 @@
|
|
|
92
94
|
padding: 8px 15px;
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
.medium {
|
|
98
|
+
height: 28px;
|
|
99
|
+
padding: 6px 14px;
|
|
100
|
+
}
|
|
101
|
+
|
|
95
102
|
.small {
|
|
96
103
|
height: 20px;
|
|
97
104
|
padding: 4px 15px;
|
|
@@ -115,16 +122,26 @@
|
|
|
115
122
|
border-radius: var(--pte-borders-radius-circle);
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
.
|
|
119
|
-
|
|
125
|
+
.square, .rectangle {
|
|
126
|
+
&.sharp {
|
|
127
|
+
border-radius: var(--pte-borders-radius-rectangle);
|
|
128
|
+
}
|
|
120
129
|
|
|
121
|
-
&.
|
|
122
|
-
border-radius: var(--pte-borders-radius-
|
|
130
|
+
&.rounded {
|
|
131
|
+
border-radius: var(--pte-borders-radius-rounded);
|
|
132
|
+
|
|
133
|
+
&.small {
|
|
134
|
+
border-radius: var(--pte-borders-radius-roundedSmall);
|
|
135
|
+
}
|
|
123
136
|
}
|
|
124
|
-
}
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
|
|
138
|
+
&.roundedXL {
|
|
139
|
+
border-radius: var(--pte-borders-radius-roundedLarge);
|
|
140
|
+
|
|
141
|
+
&.small {
|
|
142
|
+
border-radius: var(--pte-borders-radius-rounded);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
128
145
|
}
|
|
129
146
|
|
|
130
147
|
.circle, .square {
|
|
@@ -133,6 +150,11 @@
|
|
|
133
150
|
padding: 8px;
|
|
134
151
|
}
|
|
135
152
|
|
|
153
|
+
&.medium {
|
|
154
|
+
width: 28px;
|
|
155
|
+
padding: 4px;
|
|
156
|
+
}
|
|
157
|
+
|
|
136
158
|
&.small {
|
|
137
159
|
width: 20px;
|
|
138
160
|
padding: 4px;
|
|
@@ -57,3 +57,27 @@ export const WithEnhancer: Story = {
|
|
|
57
57
|
}),
|
|
58
58
|
},
|
|
59
59
|
};
|
|
60
|
+
|
|
61
|
+
export const Circle: Story = {
|
|
62
|
+
args: {
|
|
63
|
+
children: 'Button',
|
|
64
|
+
shape: 'circle',
|
|
65
|
+
kind: 'tertiary',
|
|
66
|
+
startEnhancer: ({ size }) => createElement(FontAwesomeIcon, {
|
|
67
|
+
icon: faPlus,
|
|
68
|
+
width: `${size}px`,
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const Rounded: Story = {
|
|
74
|
+
args: {
|
|
75
|
+
children: 'Button',
|
|
76
|
+
shape: 'rectangle',
|
|
77
|
+
corners: 'rounded',
|
|
78
|
+
startEnhancer: ({ size }) => createElement(FontAwesomeIcon, {
|
|
79
|
+
icon: faPlus,
|
|
80
|
+
width: `${size}px`,
|
|
81
|
+
}),
|
|
82
|
+
},
|
|
83
|
+
};
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
import type {
|
|
4
4
|
CSSProperties, FC, HTMLAttributeAnchorTarget, MouseEventHandler, ReactNode,
|
|
5
5
|
} from 'react';
|
|
6
|
+
import { useMemo } from 'react';
|
|
6
7
|
import type { ButtonProps as AriaButtonProps } from '@ariakit/react';
|
|
7
8
|
import { Button as AriaButton } from '@ariakit/react';
|
|
8
9
|
import clsx from 'clsx';
|
|
9
10
|
import fontColorContrast from 'font-color-contrast';
|
|
11
|
+
import type { CSSLength } from '@ssh/csstypes';
|
|
10
12
|
import styles from './Button.module.scss';
|
|
11
13
|
import { Text } from '../text';
|
|
12
14
|
import type { Enhancer } from '../../types/Enhancer';
|
|
@@ -17,22 +19,31 @@ import { NotificationDot } from '../icon/NotificationDot';
|
|
|
17
19
|
|
|
18
20
|
const EnhancerSizes = {
|
|
19
21
|
large: 13,
|
|
22
|
+
medium: 12,
|
|
20
23
|
small: 11,
|
|
21
24
|
xs: 9,
|
|
22
25
|
};
|
|
23
26
|
|
|
27
|
+
export const CornerPresets = ['sharp', 'rounded', 'roundedXL'] as const;
|
|
28
|
+
|
|
24
29
|
export const ButtonThemes = {
|
|
25
30
|
negative: {
|
|
26
|
-
primary: pvar('colors.
|
|
27
|
-
secondary: pvar('colors.
|
|
31
|
+
primary: pvar('new.colors.buttonBorderNegative'),
|
|
32
|
+
secondary: pvar('new.colors.buttonFillHoverNegative'),
|
|
33
|
+
primaryAlt: pvar('new.colors.contentNegative'),
|
|
34
|
+
secondaryAlt: pvar('new.colors.backgroundNegativeStrong'),
|
|
28
35
|
},
|
|
29
36
|
positive: {
|
|
30
|
-
primary: pvar('colors.contentPositive'),
|
|
31
|
-
secondary: pvar('colors.backgroundPositive'),
|
|
37
|
+
primary: pvar('new.colors.contentPositive'),
|
|
38
|
+
secondary: pvar('new.colors.backgroundPositive'),
|
|
39
|
+
primaryAlt: pvar('new.colors.contentPositive'),
|
|
40
|
+
secondaryAlt: pvar('new.colors.backgroundPositiveStrong'),
|
|
32
41
|
},
|
|
33
42
|
warning: {
|
|
34
|
-
primary: pvar('colors.contentWarning'),
|
|
35
|
-
secondary: pvar('colors.backgroundWarning'),
|
|
43
|
+
primary: pvar('new.colors.contentWarning'),
|
|
44
|
+
secondary: pvar('new.colors.backgroundWarning'),
|
|
45
|
+
primaryAlt: pvar('new.colors.contentWarning'),
|
|
46
|
+
secondaryAlt: pvar('new.colors.backgroundWarningStrong'),
|
|
36
47
|
},
|
|
37
48
|
} as const;
|
|
38
49
|
|
|
@@ -46,12 +57,19 @@ export type ButtonProps = {
|
|
|
46
57
|
* The size of the Button.
|
|
47
58
|
* @default large
|
|
48
59
|
*/
|
|
49
|
-
size?: 'large' | 'small' | 'xs';
|
|
60
|
+
size?: 'large' | 'medium' | 'small' | 'xs';
|
|
50
61
|
/**
|
|
51
62
|
* The shape of the Button.
|
|
52
63
|
* @default pill
|
|
53
64
|
*/
|
|
54
|
-
shape?: 'pill' | 'circle' | 'rectangle' | 'square'
|
|
65
|
+
shape?: 'pill' | 'circle' | 'rectangle' | 'square';
|
|
66
|
+
/**
|
|
67
|
+
* The radius of the corners for the `rectangle` and `square` Button shapes. Either a preset or a valid {@link CSSLength} string.
|
|
68
|
+
* `sharp` will have no rounding, `rounded` will have a slight rounding, and `roundedXL` will have a large rounding.
|
|
69
|
+
* @see CornerPresets
|
|
70
|
+
* @default rounded
|
|
71
|
+
*/
|
|
72
|
+
corners?: typeof CornerPresets[number] | CSSLength;
|
|
55
73
|
/**
|
|
56
74
|
* A color to apply for the Button. Provide an object with `primary` and `secondary` properties to set the primary and hover colors.
|
|
57
75
|
*/
|
|
@@ -126,6 +144,7 @@ export const Button: FC<ButtonProps> = ({
|
|
|
126
144
|
kind = 'primary',
|
|
127
145
|
size = 'large',
|
|
128
146
|
shape = 'pill',
|
|
147
|
+
corners = 'rounded',
|
|
129
148
|
colors,
|
|
130
149
|
theme,
|
|
131
150
|
type = 'button',
|
|
@@ -139,66 +158,72 @@ export const Button: FC<ButtonProps> = ({
|
|
|
139
158
|
displayNotificationDot = false,
|
|
140
159
|
style,
|
|
141
160
|
...props
|
|
142
|
-
}) =>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
161
|
+
}) => {
|
|
162
|
+
const cornersIsPreset = useMemo(() => (CornerPresets as readonly string[]).includes(corners), [corners]);
|
|
163
|
+
return (
|
|
164
|
+
<AriaButton
|
|
165
|
+
{...props}
|
|
166
|
+
style={(theme || colors) ? {
|
|
167
|
+
'--pte-new-colors-contentInversePrimary': fontColorContrast(theme ? ButtonThemes[theme].primary : colors?.primary || pvar('new.colors.contentPrimary')), // text for primary
|
|
168
|
+
'--pte-new-colors-buttonFill': theme ? ButtonThemes[theme].primaryAlt : colors?.primary, // background for primary
|
|
169
|
+
'--pte-new-colors-buttonFillHover': theme ? ButtonThemes[theme].secondaryAlt : colors?.secondary, // hover background for primary
|
|
170
|
+
'--pte-new-colors-contentPrimary': theme ? ButtonThemes[theme].primary : colors?.primary, // text for secondary/tertiary
|
|
171
|
+
'--pte-new-colors-buttonBorder': theme ? ButtonThemes[theme].primary : colors?.primary, // border for secondary/tertiary
|
|
172
|
+
'--pte-new-colors-overlayMedium': theme ? ButtonThemes[theme].secondary : colors?.secondary, // hover background for secondary/tertiary
|
|
173
|
+
borderRadius: !cornersIsPreset ? corners : '',
|
|
174
|
+
...style,
|
|
175
|
+
} as CSSProperties : ({ borderRadius: !cornersIsPreset ? corners : '', ...style })}
|
|
176
|
+
className={clsx(
|
|
177
|
+
styles.button,
|
|
178
|
+
styles[kind],
|
|
179
|
+
styles[shape],
|
|
180
|
+
styles[size],
|
|
181
|
+
cornersIsPreset && styles[corners],
|
|
182
|
+
props?.className,
|
|
183
|
+
)}
|
|
184
|
+
aria-disabled={disabled ?? false}
|
|
185
|
+
type={type}
|
|
186
|
+
aria-details={typeof children === 'string' ? children : undefined}
|
|
187
|
+
onClick={!disabled && !href && !loading ? onClick : () => {}}
|
|
188
|
+
disabled={false}
|
|
189
|
+
{...href ? {
|
|
190
|
+
render: (properties) => (
|
|
191
|
+
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
|
192
|
+
<a
|
|
193
|
+
{...properties}
|
|
194
|
+
href={href}
|
|
195
|
+
target={props.hreftarget ?? '_self'}
|
|
196
|
+
rel={props.hreftarget === '_self' ? undefined : 'noreferrer'}
|
|
197
|
+
/>
|
|
198
|
+
),
|
|
199
|
+
} : {}}
|
|
200
|
+
>
|
|
201
|
+
{!!startEnhancer && (
|
|
202
|
+
<MemoizedEnhancer
|
|
203
|
+
enhancer={startEnhancer}
|
|
204
|
+
size={EnhancerSizes[size]}
|
|
173
205
|
/>
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
{!!displayNotificationDot && (
|
|
199
|
-
<div className="absolute top-0 right-0">
|
|
200
|
-
<NotificationDot size={8} />
|
|
201
|
-
</div>
|
|
202
|
-
)}
|
|
203
|
-
</AriaButton>
|
|
204
|
-
);
|
|
206
|
+
)}
|
|
207
|
+
{!['circle', 'square'].includes(shape) && (
|
|
208
|
+
<Text kind="labelXSmall">
|
|
209
|
+
{!loading ? (
|
|
210
|
+
children || 'Button'
|
|
211
|
+
) : (
|
|
212
|
+
<Spinner size={EnhancerSizes[size]} />
|
|
213
|
+
)}
|
|
214
|
+
</Text>
|
|
215
|
+
)}
|
|
216
|
+
{!!endEnhancer && (
|
|
217
|
+
<MemoizedEnhancer
|
|
218
|
+
enhancer={endEnhancer}
|
|
219
|
+
size={EnhancerSizes[size]}
|
|
220
|
+
/>
|
|
221
|
+
)}
|
|
222
|
+
{!!displayNotificationDot && (
|
|
223
|
+
<div className="absolute top-0 right-0">
|
|
224
|
+
<NotificationDot size={8} />
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
227
|
+
</AriaButton>
|
|
228
|
+
);
|
|
229
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
.content {
|
|
2
|
-
background-color: var(--pte-colors-
|
|
2
|
+
background-color: var(--pte-new-colors-overlayMedium);
|
|
3
3
|
border-radius: 6px;
|
|
4
4
|
width: 100%;
|
|
5
5
|
padding: 8px 10px;
|
|
6
|
-
color: var(--pte-colors-
|
|
6
|
+
color: var(--pte-new-colors-contentSecondary);
|
|
7
7
|
|
|
8
8
|
display: flex;
|
|
9
9
|
flex-direction: row;
|
|
@@ -26,18 +26,18 @@
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
&.warning {
|
|
29
|
-
background-color: var(--pte-colors-backgroundWarning);
|
|
30
|
-
color: var(--pte-colors-contentWarning);
|
|
29
|
+
background-color: var(--pte-new-colors-backgroundWarning);
|
|
30
|
+
color: var(--pte-new-colors-contentWarning);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
&.negative {
|
|
34
|
-
background-color: var(--pte-colors-
|
|
35
|
-
color: var(--pte-colors-contentNegative);
|
|
34
|
+
background-color: var(--pte-new-colors-overlayRed);
|
|
35
|
+
color: var(--pte-new-colors-contentNegative);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
&.positive {
|
|
39
39
|
.icon {
|
|
40
|
-
color: var(--pte-colors-contentPositive);
|
|
40
|
+
color: var(--pte-new-colors-contentPositive);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -4,12 +4,13 @@ import type {
|
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import styles from './Callout.module.scss';
|
|
6
6
|
import { RemoveFromDOM, TextWhenString } from '../utility';
|
|
7
|
+
import { Icon, ArrowRight } from '../icon';
|
|
7
8
|
|
|
8
9
|
export type CalloutProps = {
|
|
9
10
|
/** The variant of the Callout. */
|
|
10
11
|
variant?: 'default' | 'warning' | 'positive' | 'negative';
|
|
11
|
-
/** An icon to display in the Callout. For best results, use an SVG icon with fill set to `currentColor`. */
|
|
12
|
-
icon?: ReactElement;
|
|
12
|
+
/** An icon to display in the Callout. To hide icon, set `icon={null}`. For best results, use an SVG icon with fill set to `currentColor`. */
|
|
13
|
+
icon?: ReactElement | null;
|
|
13
14
|
/** The contents of the Callout. */
|
|
14
15
|
children?: ReactNode;
|
|
15
16
|
} & Omit<ComponentPropsWithoutRef<'div'>, 'children'>;
|
|
@@ -28,7 +29,7 @@ export type CalloutProps = {
|
|
|
28
29
|
*/
|
|
29
30
|
export const Callout: FC<CalloutProps> = ({
|
|
30
31
|
variant = 'default',
|
|
31
|
-
icon
|
|
32
|
+
icon = <Icon icon={ArrowRight} size={16} className={styles.icon} />,
|
|
32
33
|
children,
|
|
33
34
|
className,
|
|
34
35
|
...props
|