@transferwise/components 0.0.0-experimental-4b360b4 → 0.0.0-experimental-0dd9635

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
@@ -11233,6 +11233,102 @@ Select.defaultProps = {
11233
11233
  dropdownProps: {}
11234
11234
  };
11235
11235
 
11236
+ const SegmentedControl = ({
11237
+ name,
11238
+ defaultValue,
11239
+ mode = 'input',
11240
+ segments,
11241
+ onChange
11242
+ }) => {
11243
+ const [selectedValue, setSelectedValue] = React.useState(defaultValue || segments[0].value);
11244
+ const [animate, setAnimate] = React.useState(false);
11245
+ const segmentsRef = React.useRef(null);
11246
+ if (segments.length > 3) {
11247
+ throw new Error('SegmentedControl only supports up to 3 segments');
11248
+ }
11249
+ const segmentsWithRefs = segments.map(segment => ({
11250
+ ...segment,
11251
+ ref: /*#__PURE__*/React.createRef()
11252
+ }));
11253
+ const updateSegmentPosition = () => {
11254
+ const selectedSegmentRef = segmentsWithRefs.find(segment => segment.value === selectedValue)?.ref;
11255
+ // We grab the active segments style object from the ref
11256
+ // and set the css variables to the selected segments width and x position.
11257
+ // This is so we can animate the highlight to the selected segment
11258
+ if (selectedSegmentRef?.current && segmentsRef.current) {
11259
+ const {
11260
+ style
11261
+ } = segmentsRef.current;
11262
+ style.setProperty('--segment-highlight-width', `${selectedSegmentRef.current.offsetWidth}px`);
11263
+ style.setProperty('--segment-highlight-x', `${selectedSegmentRef.current.offsetLeft}px`);
11264
+ }
11265
+ };
11266
+ React.useEffect(() => {
11267
+ updateSegmentPosition();
11268
+ const handleWindowSizeChange = () => {
11269
+ setAnimate(false);
11270
+ updateSegmentPosition();
11271
+ };
11272
+ window.addEventListener('resize', handleWindowSizeChange);
11273
+ return () => {
11274
+ window.removeEventListener('resize', handleWindowSizeChange);
11275
+ };
11276
+ // eslint-disable-next-line react-hooks/exhaustive-deps
11277
+ }, [segmentsWithRefs, selectedValue]);
11278
+ React.useEffect(() => {
11279
+ onChange(selectedValue);
11280
+ }, [onChange, selectedValue]);
11281
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
11282
+ ref: segmentsRef,
11283
+ "data-testid": "segmented-control",
11284
+ className: classNames__default.default('segmented-control', {
11285
+ 'segmented-control--input': mode === 'input'
11286
+ }),
11287
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
11288
+ className: classNames__default.default('segmented-control__segments', {
11289
+ 'segmented-control__segments--no-animate': !animate
11290
+ }),
11291
+ children: segmentsWithRefs.map(segment => mode === 'input' ? /*#__PURE__*/jsxRuntime.jsxs("label", {
11292
+ ref: segment.ref,
11293
+ htmlFor: segment.id,
11294
+ className: classNames__default.default('segmented-control__segment', {
11295
+ 'segmented-control__selected-segment': selectedValue === segment.value
11296
+ }),
11297
+ children: [/*#__PURE__*/jsxRuntime.jsx("input", {
11298
+ type: "radio",
11299
+ className: "segmented-control__radio-input",
11300
+ id: segment.id,
11301
+ name: name,
11302
+ value: segment.value,
11303
+ checked: selectedValue === segment.value,
11304
+ onChange: () => {
11305
+ setAnimate(true);
11306
+ setSelectedValue(segment.value);
11307
+ }
11308
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
11309
+ className: "segmented-control__label-text",
11310
+ children: segment.label
11311
+ })]
11312
+ }, segment.id) : /*#__PURE__*/jsxRuntime.jsx("button", {
11313
+ ref: segment.ref,
11314
+ type: "button",
11315
+ role: "tab",
11316
+ id: segment.id,
11317
+ "aria-controls": segment.controls,
11318
+ "aria-selected": selectedValue === segment.value,
11319
+ className: classNames__default.default('segmented-control__segment', 'segmented-control__button', {
11320
+ 'segmented-control__selected-segment': selectedValue === segment.value
11321
+ }),
11322
+ onClick: () => {
11323
+ setAnimate(true);
11324
+ setSelectedValue(segment.value);
11325
+ },
11326
+ children: segment.label
11327
+ }, segment.id))
11328
+ })
11329
+ });
11330
+ };
11331
+
11236
11332
  const CSS_TRANSITION_DURATION = 400;
11237
11333
  class Snackbar extends React.Component {
11238
11334
  /** @type {RefObject<HTMLSpanElement>} */
@@ -15702,6 +15798,7 @@ exports.RadioOption = RadioOption$1;
15702
15798
  exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
15703
15799
  exports.SearchInput = SearchInput;
15704
15800
  exports.Section = Section;
15801
+ exports.SegmentedControl = SegmentedControl;
15705
15802
  exports.Select = Select;
15706
15803
  exports.SelectInput = SelectInput;
15707
15804
  exports.SelectInputOptionContent = SelectInputOptionContent;