@transferwise/components 0.0.0-experimental-dd495d2 → 0.0.0-experimental-3776330

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
@@ -11077,6 +11077,102 @@ Select.defaultProps = {
11077
11077
  dropdownProps: {}
11078
11078
  };
11079
11079
 
11080
+ const SegmentedControl = ({
11081
+ name,
11082
+ defaultValue,
11083
+ mode = 'input',
11084
+ segments,
11085
+ onChange
11086
+ }) => {
11087
+ const [selectedValue, setSelectedValue] = React.useState(defaultValue || segments[0].value);
11088
+ const [animate, setAnimate] = React.useState(false);
11089
+ const segmentsRef = React.useRef(null);
11090
+ if (segments.length > 3) {
11091
+ throw new Error('SegmentedControl only supports up to 3 segments. Please refer to: https://wise.design/components/segmented-control');
11092
+ }
11093
+ const segmentsWithRefs = segments.map(segment => ({
11094
+ ...segment,
11095
+ ref: /*#__PURE__*/React.createRef()
11096
+ }));
11097
+ const updateSegmentPosition = () => {
11098
+ const selectedSegmentRef = segmentsWithRefs.find(segment => segment.value === selectedValue)?.ref;
11099
+ // We grab the active segments style object from the ref
11100
+ // and set the css variables to the selected segments width and x position.
11101
+ // This is so we can animate the highlight to the selected segment
11102
+ if (selectedSegmentRef?.current && segmentsRef.current) {
11103
+ const {
11104
+ style
11105
+ } = segmentsRef.current;
11106
+ style.setProperty('--segment-highlight-width', `${selectedSegmentRef.current.offsetWidth}px`);
11107
+ style.setProperty('--segment-highlight-x', `${selectedSegmentRef.current.offsetLeft}px`);
11108
+ }
11109
+ };
11110
+ React.useEffect(() => {
11111
+ updateSegmentPosition();
11112
+ const handleWindowSizeChange = () => {
11113
+ setAnimate(false);
11114
+ updateSegmentPosition();
11115
+ };
11116
+ window.addEventListener('resize', handleWindowSizeChange);
11117
+ return () => {
11118
+ window.removeEventListener('resize', handleWindowSizeChange);
11119
+ };
11120
+ // eslint-disable-next-line react-hooks/exhaustive-deps
11121
+ }, [segmentsWithRefs, selectedValue]);
11122
+ React.useEffect(() => {
11123
+ onChange(selectedValue);
11124
+ }, [onChange, selectedValue]);
11125
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
11126
+ ref: segmentsRef,
11127
+ "data-testid": "segmented-control",
11128
+ className: classNames__default.default('segmented-control', {
11129
+ 'segmented-control--input': mode === 'input'
11130
+ }),
11131
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
11132
+ className: classNames__default.default('segmented-control__segments', {
11133
+ 'segmented-control__segments--no-animate': !animate
11134
+ }),
11135
+ children: segmentsWithRefs.map(segment => mode === 'input' ? /*#__PURE__*/jsxRuntime.jsxs("label", {
11136
+ ref: segment.ref,
11137
+ htmlFor: segment.id,
11138
+ className: classNames__default.default('segmented-control__segment', {
11139
+ 'segmented-control__selected-segment': selectedValue === segment.value
11140
+ }),
11141
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
11142
+ type: "radio",
11143
+ className: "segmented-control__radio-input",
11144
+ id: segment.id,
11145
+ name: name,
11146
+ value: segment.value,
11147
+ checked: selectedValue === segment.value,
11148
+ onChange: () => {
11149
+ setAnimate(true);
11150
+ setSelectedValue(segment.value);
11151
+ }
11152
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
11153
+ className: "segmented-control__label-text",
11154
+ children: segment.label
11155
+ })]
11156
+ }, segment.id) : /*#__PURE__*/jsxRuntime.jsx("button", {
11157
+ ref: segment.ref,
11158
+ type: "button",
11159
+ role: "tab",
11160
+ id: segment.id,
11161
+ "aria-controls": segment.controls,
11162
+ "aria-selected": selectedValue === segment.value,
11163
+ className: classNames__default.default('segmented-control__segment', 'segmented-control__button', {
11164
+ 'segmented-control__selected-segment': selectedValue === segment.value
11165
+ }),
11166
+ onClick: () => {
11167
+ setAnimate(true);
11168
+ setSelectedValue(segment.value);
11169
+ },
11170
+ children: segment.label
11171
+ }, segment.id))
11172
+ })
11173
+ });
11174
+ };
11175
+
11080
11176
  const CSS_TRANSITION_DURATION = 400;
11081
11177
  class Snackbar extends React.Component {
11082
11178
  /** @type {RefObject<HTMLSpanElement>} */
@@ -15546,6 +15642,7 @@ exports.RadioOption = RadioOption$1;
15546
15642
  exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
15547
15643
  exports.SearchInput = SearchInput;
15548
15644
  exports.Section = Section;
15645
+ exports.SegmentedControl = SegmentedControl;
15549
15646
  exports.Select = Select;
15550
15647
  exports.SelectInput = SelectInput;
15551
15648
  exports.SelectInputOptionContent = SelectInputOptionContent;