@transferwise/components 46.7.0 → 46.8.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/build/index.js CHANGED
@@ -7544,7 +7544,7 @@ class WithDisplayFormat extends React.Component {
7544
7544
  const cursorPosition = getCursorPositionAfterKeystroke(action, selectionStart, selectionEnd, displayPattern, pastedLength);
7545
7545
  setTimeout(() => {
7546
7546
  if (triggerEvent) {
7547
- triggerEvent.currentTarget.setSelectionRange(cursorPosition, cursorPosition);
7547
+ triggerEvent.target.setSelectionRange(cursorPosition, cursorPosition);
7548
7548
  }
7549
7549
  this.setState({
7550
7550
  selectionStart: cursorPosition,
@@ -9913,7 +9913,6 @@ const PromoCard = /*#__PURE__*/React.forwardRef(({
9913
9913
  setChecked(!checked); // Update local state for checkbox
9914
9914
  }
9915
9915
  };
9916
-
9917
9916
  const componentId = `${id || generateRandomId()}`;
9918
9917
  // Set the icon to `'arrow'` if `href` is truthy and `type` is falsy, or
9919
9918
  // `'download'` if `download` is truthy. If neither condition is true, set
@@ -11077,6 +11076,109 @@ Select.defaultProps = {
11077
11076
  dropdownProps: {}
11078
11077
  };
11079
11078
 
11079
+ const SegmentedControl = ({
11080
+ name,
11081
+ defaultValue,
11082
+ mode = 'input',
11083
+ segments,
11084
+ onChange
11085
+ }) => {
11086
+ const [selectedValue, setSelectedValue] = React.useState(defaultValue || segments[0].value);
11087
+ const [animate, setAnimate] = React.useState(false);
11088
+ const segmentsRef = React.useRef(null);
11089
+ if (segments.length > 3) {
11090
+ throw new Error('SegmentedControl only supports up to 3 segments. Please refer to: https://wise.design/components/segmented-control');
11091
+ }
11092
+ const segmentsWithRefs = segments.map(segment => ({
11093
+ ...segment,
11094
+ ref: /*#__PURE__*/React.createRef()
11095
+ }));
11096
+ const updateSegmentPosition = () => {
11097
+ const selectedSegmentRef = segmentsWithRefs.find(segment => segment.value === selectedValue)?.ref;
11098
+ // We grab the active segments style object from the ref
11099
+ // and set the css variables to the selected segments width and x position.
11100
+ // This is so we can animate the highlight to the selected segment
11101
+ if (selectedSegmentRef?.current && segmentsRef.current) {
11102
+ const {
11103
+ style
11104
+ } = segmentsRef.current;
11105
+ style.setProperty('--segment-highlight-width', `${selectedSegmentRef.current.offsetWidth}px`);
11106
+ style.setProperty('--segment-highlight-x', `${selectedSegmentRef.current.offsetLeft}px`);
11107
+ }
11108
+ };
11109
+ React.useEffect(() => {
11110
+ updateSegmentPosition();
11111
+ const handleWindowSizeChange = () => {
11112
+ setAnimate(false);
11113
+ updateSegmentPosition();
11114
+ };
11115
+ window.addEventListener('resize', handleWindowSizeChange);
11116
+ return () => {
11117
+ window.removeEventListener('resize', handleWindowSizeChange);
11118
+ };
11119
+ // eslint-disable-next-line react-hooks/exhaustive-deps
11120
+ }, [segmentsWithRefs, selectedValue]);
11121
+ React.useEffect(() => {
11122
+ onChange(selectedValue);
11123
+ }, [onChange, selectedValue]);
11124
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
11125
+ ref: segmentsRef,
11126
+ "data-testid": "segmented-control",
11127
+ className: classNames__default.default('segmented-control', {
11128
+ 'segmented-control--input': mode === 'input'
11129
+ }),
11130
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
11131
+ className: classNames__default.default('segmented-control__segments', {
11132
+ 'segmented-control__segments--no-animate': !animate
11133
+ }),
11134
+ children: segmentsWithRefs.map(segment => mode === 'input' ? /*#__PURE__*/jsxRuntime.jsxs("label", {
11135
+ ref: segment.ref,
11136
+ htmlFor: segment.id,
11137
+ className: classNames__default.default('segmented-control__segment', {
11138
+ 'segmented-control__selected-segment': selectedValue === segment.value
11139
+ }),
11140
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
11141
+ type: "radio",
11142
+ className: "segmented-control__radio-input",
11143
+ id: segment.id,
11144
+ name: name,
11145
+ value: segment.value,
11146
+ checked: selectedValue === segment.value,
11147
+ onChange: () => {
11148
+ setAnimate(true);
11149
+ setSelectedValue(segment.value);
11150
+ }
11151
+ }), /*#__PURE__*/jsxRuntime.jsx(Body, {
11152
+ className: "segmented-control__text",
11153
+ as: "span",
11154
+ type: selectedValue === segment.value ? exports.Typography.BODY_DEFAULT_BOLD : exports.Typography.BODY_DEFAULT,
11155
+ children: segment.label
11156
+ })]
11157
+ }, segment.id) : /*#__PURE__*/jsxRuntime.jsx("button", {
11158
+ ref: segment.ref,
11159
+ type: "button",
11160
+ role: "tab",
11161
+ id: segment.id,
11162
+ "aria-controls": segment.controls,
11163
+ "aria-selected": selectedValue === segment.value,
11164
+ className: classNames__default.default('segmented-control__segment', 'segmented-control__button', {
11165
+ 'segmented-control__selected-segment': selectedValue === segment.value
11166
+ }),
11167
+ onClick: () => {
11168
+ setAnimate(true);
11169
+ setSelectedValue(segment.value);
11170
+ },
11171
+ children: /*#__PURE__*/jsxRuntime.jsx(Body, {
11172
+ as: "span",
11173
+ className: "segmented-control__text",
11174
+ type: selectedValue === segment.value ? exports.Typography.BODY_DEFAULT_BOLD : exports.Typography.BODY_DEFAULT,
11175
+ children: segment.label
11176
+ })
11177
+ }, segment.id))
11178
+ })
11179
+ });
11180
+ };
11181
+
11080
11182
  const CSS_TRANSITION_DURATION = 400;
11081
11183
  class Snackbar extends React.Component {
11082
11184
  /** @type {RefObject<HTMLSpanElement>} */
@@ -13861,7 +13963,6 @@ const UploadButton = ({
13861
13963
  if (areAllFilesAllowed) {
13862
13964
  return null; //file input by default allows all files
13863
13965
  }
13864
-
13865
13966
  if (Array.isArray(fileTypes)) {
13866
13967
  return {
13867
13968
  accept: fileTypes.join(',')
@@ -14059,7 +14160,6 @@ const UploadItem = ({
14059
14160
  children: processIndicator
14060
14161
  }); // Scale down ProcessIndicator to be 20px*20px to match `icons`
14061
14162
  };
14062
-
14063
14163
  const getErrorMessage = () => typeof error === 'object' && error.message || error || formatMessage(MESSAGES.uploadingFailed);
14064
14164
  const getDescription = () => {
14065
14165
  if (error || status === exports.Status.FAILED) {
@@ -15546,6 +15646,7 @@ exports.RadioOption = RadioOption$1;
15546
15646
  exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
15547
15647
  exports.SearchInput = SearchInput;
15548
15648
  exports.Section = Section;
15649
+ exports.SegmentedControl = SegmentedControl;
15549
15650
  exports.Select = Select;
15550
15651
  exports.SelectInput = SelectInput;
15551
15652
  exports.SelectInputOptionContent = SelectInputOptionContent;