@transferwise/components 0.0.0-experimental-b2eafa7 → 0.0.0-experimental-b7402e7
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/index.esm.js +50 -178
- package/build/index.esm.js.map +1 -1
- package/build/index.js +50 -179
- package/build/index.js.map +1 -1
- package/build/main.css +0 -101
- package/build/styles/main.css +0 -101
- package/build/types/checkboxOption/CheckboxOption.d.ts +2 -2
- package/build/types/checkboxOption/CheckboxOption.d.ts.map +1 -1
- package/build/types/index.d.ts +2 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/snackbar/Snackbar.d.ts +30 -22
- package/build/types/snackbar/Snackbar.d.ts.map +1 -1
- package/build/types/snackbar/SnackbarContext.d.ts +7 -2
- package/build/types/snackbar/SnackbarContext.d.ts.map +1 -1
- package/build/types/snackbar/SnackbarProvider.d.ts +7 -12
- package/build/types/snackbar/SnackbarProvider.d.ts.map +1 -1
- package/build/types/snackbar/index.d.ts +2 -0
- package/build/types/snackbar/index.d.ts.map +1 -0
- package/build/types/snackbar/useSnackbar.d.ts +1 -1
- package/build/types/snackbar/useSnackbar.d.ts.map +1 -1
- package/build/types/withNextPortal/withNextPortal.d.ts +1 -1
- package/build/types/withNextPortal/withNextPortal.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/checkboxOption/CheckboxOption.tsx +2 -2
- package/src/index.ts +2 -2
- package/src/main.css +0 -101
- package/src/main.less +0 -1
- package/src/snackbar/{Snackbar.story.js → Snackbar.story.tsx} +2 -1
- package/src/snackbar/{Snackbar.js → Snackbar.tsx} +31 -32
- package/src/snackbar/SnackbarContext.ts +11 -0
- package/src/snackbar/SnackbarProvider.tsx +39 -0
- package/src/ssr.spec.js +0 -17
- package/src/withNextPortal/withNextPortal.tsx +1 -1
- package/build/styles/segmentedControl/SegmentedControl.css +0 -101
- package/build/types/segmentedControl/SegmentedControl.d.ts +0 -31
- package/build/types/segmentedControl/SegmentedControl.d.ts.map +0 -1
- package/build/types/segmentedControl/index.d.ts +0 -3
- package/build/types/segmentedControl/index.d.ts.map +0 -1
- package/src/segmentedControl/SegmentedControl.css +0 -101
- package/src/segmentedControl/SegmentedControl.less +0 -101
- package/src/segmentedControl/SegmentedControl.spec.tsx +0 -106
- package/src/segmentedControl/SegmentedControl.story.tsx +0 -55
- package/src/segmentedControl/SegmentedControl.tsx +0 -175
- package/src/segmentedControl/index.ts +0 -2
- package/src/snackbar/SnackbarContext.js +0 -4
- package/src/snackbar/SnackbarProvider.js +0 -51
- /package/src/snackbar/{index.js → index.ts} +0 -0
- /package/src/snackbar/{useSnackbar.js → useSnackbar.ts} +0 -0
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { StoryFn } from '@storybook/react';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
|
|
4
|
-
import SegmentedControl, { Segments } from './SegmentedControl';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
component: SegmentedControl,
|
|
8
|
-
title: 'Forms/SegmentedControl',
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const segments: Segments = [
|
|
12
|
-
{ id: 'CUPCAKE', label: 'Cupcakes', value: 'cupcakes' },
|
|
13
|
-
{ id: 'SPONGECAKE', label: 'Sponge cake', value: 'spongecake' },
|
|
14
|
-
{ id: 'CARROT_CAKE', label: 'Carrot cake', value: 'carrotcake' },
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
const segmentsWithControls: Segments = [
|
|
18
|
-
{ id: 'CUPCAKE', label: 'Cupcakes', value: 'cupcakes', controls: 'aControlId' },
|
|
19
|
-
{ id: 'SPONGECAKE', label: 'Sponge cake', value: 'spongecake', controls: 'aControlId' },
|
|
20
|
-
{ id: 'CARROT_CAKE', label: 'Carrot cake', value: 'carrotcake', controls: 'aControlId' },
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const Template: StoryFn = (args) => {
|
|
24
|
-
const [selectedValue, setSelectedValue] = React.useState(segments[0].value);
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div className="p-a-2">
|
|
28
|
-
<SegmentedControl
|
|
29
|
-
name="aSegmentedControl"
|
|
30
|
-
defaultValue={selectedValue}
|
|
31
|
-
onChange={setSelectedValue}
|
|
32
|
-
{...(args.mode === 'view'
|
|
33
|
-
? { segments: segmentsWithControls, mode: 'view', controls: 'aControlId' }
|
|
34
|
-
: { segments, mode: 'input' })}
|
|
35
|
-
/>
|
|
36
|
-
<div className="m-a-2" id="aControlId">
|
|
37
|
-
<p>Selected value: {selectedValue}</p>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const SegmentedControlDefault = {
|
|
44
|
-
render: Template,
|
|
45
|
-
args: {
|
|
46
|
-
mode: 'input',
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const SegmentedControlView = {
|
|
51
|
-
render: Template,
|
|
52
|
-
args: {
|
|
53
|
-
mode: 'view',
|
|
54
|
-
},
|
|
55
|
-
};
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import classNames from 'classnames';
|
|
2
|
-
import { createRef, useEffect, useRef, useState } from 'react';
|
|
3
|
-
|
|
4
|
-
import Body from '../body';
|
|
5
|
-
import { Typography } from '../common';
|
|
6
|
-
|
|
7
|
-
type SegmentBase = { id: string; label: string; value: string };
|
|
8
|
-
|
|
9
|
-
type Segment = SegmentBase & { controls?: never };
|
|
10
|
-
type SegmentWithControls = SegmentBase & { controls: string };
|
|
11
|
-
|
|
12
|
-
export type Segments = Segment[] | SegmentWithControls[];
|
|
13
|
-
|
|
14
|
-
type SegmentedControlPropsBase = {
|
|
15
|
-
name: string;
|
|
16
|
-
defaultValue: string;
|
|
17
|
-
mode: 'input' | 'view';
|
|
18
|
-
onChange: (value: string) => void;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type SegmentedControlViewProps = {
|
|
22
|
-
mode: 'view';
|
|
23
|
-
segments: SegmentWithControls[];
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
type SegmentedControlInputProps = {
|
|
27
|
-
mode: 'input';
|
|
28
|
-
segments: Segment[];
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type SegmentedControlProps = SegmentedControlPropsBase &
|
|
32
|
-
(SegmentedControlViewProps | SegmentedControlInputProps);
|
|
33
|
-
|
|
34
|
-
const SegmentedControl = ({
|
|
35
|
-
name,
|
|
36
|
-
defaultValue,
|
|
37
|
-
mode = 'input',
|
|
38
|
-
segments,
|
|
39
|
-
onChange,
|
|
40
|
-
}: SegmentedControlProps) => {
|
|
41
|
-
const [selectedValue, setSelectedValue] = useState(defaultValue || segments[0].value);
|
|
42
|
-
const [animate, setAnimate] = useState(false);
|
|
43
|
-
|
|
44
|
-
const segmentsRef = useRef<HTMLDivElement>(null);
|
|
45
|
-
|
|
46
|
-
if (segments.length > 3) {
|
|
47
|
-
throw new Error(
|
|
48
|
-
'SegmentedControl only supports up to 3 segments. Please refer to: https://wise.design/components/segmented-control',
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const segmentsWithRefs = segments.map((segment) => ({
|
|
53
|
-
...segment,
|
|
54
|
-
ref: createRef<HTMLLabelElement | HTMLButtonElement>(),
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
const updateSegmentPosition = () => {
|
|
58
|
-
const selectedSegmentRef = segmentsWithRefs.find(
|
|
59
|
-
(segment) => segment.value === selectedValue,
|
|
60
|
-
)?.ref;
|
|
61
|
-
|
|
62
|
-
// We grab the active segments style object from the ref
|
|
63
|
-
// and set the css variables to the selected segments width and x position.
|
|
64
|
-
// This is so we can animate the highlight to the selected segment
|
|
65
|
-
if (selectedSegmentRef?.current && segmentsRef.current) {
|
|
66
|
-
const { style } = segmentsRef.current;
|
|
67
|
-
style.setProperty('--segment-highlight-width', `${selectedSegmentRef.current.offsetWidth}px`);
|
|
68
|
-
style.setProperty('--segment-highlight-x', `${selectedSegmentRef.current.offsetLeft}px`);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
updateSegmentPosition();
|
|
74
|
-
|
|
75
|
-
const handleWindowSizeChange = () => {
|
|
76
|
-
setAnimate(false);
|
|
77
|
-
updateSegmentPosition();
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
window.addEventListener('resize', handleWindowSizeChange);
|
|
81
|
-
return () => {
|
|
82
|
-
window.removeEventListener('resize', handleWindowSizeChange);
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
86
|
-
}, [segmentsWithRefs, selectedValue]);
|
|
87
|
-
|
|
88
|
-
useEffect(() => {
|
|
89
|
-
onChange(selectedValue);
|
|
90
|
-
}, [onChange, selectedValue]);
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<div
|
|
94
|
-
ref={segmentsRef}
|
|
95
|
-
data-testid="segmented-control"
|
|
96
|
-
className={classNames('segmented-control', {
|
|
97
|
-
'segmented-control--input': mode === 'input',
|
|
98
|
-
})}
|
|
99
|
-
>
|
|
100
|
-
<div
|
|
101
|
-
className={classNames('segmented-control__segments', {
|
|
102
|
-
'segmented-control__segments--no-animate': !animate,
|
|
103
|
-
})}
|
|
104
|
-
>
|
|
105
|
-
{segmentsWithRefs.map((segment) =>
|
|
106
|
-
mode === 'input' ? (
|
|
107
|
-
<label
|
|
108
|
-
ref={segment.ref as React.RefObject<HTMLLabelElement>}
|
|
109
|
-
key={segment.id}
|
|
110
|
-
htmlFor={segment.id}
|
|
111
|
-
className={classNames('segmented-control__segment', {
|
|
112
|
-
'segmented-control__selected-segment': selectedValue === segment.value,
|
|
113
|
-
})}
|
|
114
|
-
>
|
|
115
|
-
<input
|
|
116
|
-
type="radio"
|
|
117
|
-
className="segmented-control__radio-input"
|
|
118
|
-
id={segment.id}
|
|
119
|
-
name={name}
|
|
120
|
-
value={segment.value}
|
|
121
|
-
checked={selectedValue === segment.value}
|
|
122
|
-
onChange={() => {
|
|
123
|
-
setAnimate(true);
|
|
124
|
-
setSelectedValue(segment.value);
|
|
125
|
-
}}
|
|
126
|
-
/>
|
|
127
|
-
<Body
|
|
128
|
-
className="segmented-control__text"
|
|
129
|
-
as="span"
|
|
130
|
-
type={
|
|
131
|
-
selectedValue === segment.value
|
|
132
|
-
? Typography.BODY_DEFAULT_BOLD
|
|
133
|
-
: Typography.BODY_DEFAULT
|
|
134
|
-
}
|
|
135
|
-
>
|
|
136
|
-
{segment.label}
|
|
137
|
-
</Body>
|
|
138
|
-
</label>
|
|
139
|
-
) : (
|
|
140
|
-
<button
|
|
141
|
-
ref={segment.ref as React.RefObject<HTMLButtonElement>}
|
|
142
|
-
key={segment.id}
|
|
143
|
-
type="button"
|
|
144
|
-
role="tab"
|
|
145
|
-
id={segment.id}
|
|
146
|
-
aria-controls={segment.controls}
|
|
147
|
-
aria-selected={selectedValue === segment.value}
|
|
148
|
-
className={classNames('segmented-control__segment', 'segmented-control__button', {
|
|
149
|
-
'segmented-control__selected-segment': selectedValue === segment.value,
|
|
150
|
-
})}
|
|
151
|
-
onClick={() => {
|
|
152
|
-
setAnimate(true);
|
|
153
|
-
setSelectedValue(segment.value);
|
|
154
|
-
}}
|
|
155
|
-
>
|
|
156
|
-
<Body
|
|
157
|
-
as="span"
|
|
158
|
-
className="segmented-control__text"
|
|
159
|
-
type={
|
|
160
|
-
selectedValue === segment.value
|
|
161
|
-
? Typography.BODY_DEFAULT_BOLD
|
|
162
|
-
: Typography.BODY_DEFAULT
|
|
163
|
-
}
|
|
164
|
-
>
|
|
165
|
-
{segment.label}
|
|
166
|
-
</Body>
|
|
167
|
-
</button>
|
|
168
|
-
),
|
|
169
|
-
)}
|
|
170
|
-
</div>
|
|
171
|
-
</div>
|
|
172
|
-
);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
export default SegmentedControl;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import PropTypes from 'prop-types';
|
|
2
|
-
import { Component } from 'react';
|
|
3
|
-
|
|
4
|
-
import SnackbarPortal from './Snackbar';
|
|
5
|
-
import { SnackbarContext } from './SnackbarContext';
|
|
6
|
-
|
|
7
|
-
class SnackbarProvider extends Component {
|
|
8
|
-
constructor() {
|
|
9
|
-
super();
|
|
10
|
-
this.state = {
|
|
11
|
-
text: '',
|
|
12
|
-
timestamp: 0,
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
create = ({ action, text, theme }) => {
|
|
17
|
-
this.setState({ action, text, theme, timestamp: Date.now() });
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
render() {
|
|
21
|
-
const { action, text, theme, timestamp } = this.state;
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<SnackbarContext.Provider
|
|
25
|
-
value={{
|
|
26
|
-
createSnackbar: this.create,
|
|
27
|
-
}}
|
|
28
|
-
>
|
|
29
|
-
<SnackbarPortal
|
|
30
|
-
action={action}
|
|
31
|
-
text={text}
|
|
32
|
-
timestamp={timestamp}
|
|
33
|
-
timeout={this.props.timeout}
|
|
34
|
-
theme={theme}
|
|
35
|
-
/>
|
|
36
|
-
{this.props.children}
|
|
37
|
-
</SnackbarContext.Provider>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
SnackbarProvider.propTypes = {
|
|
43
|
-
children: PropTypes.node.isRequired,
|
|
44
|
-
timeout: PropTypes.number,
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
SnackbarProvider.defaultProps = {
|
|
48
|
-
timeout: 4500,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export default SnackbarProvider;
|
|
File without changes
|
|
File without changes
|