{"version":3,"file":"SegmentedControl.mjs","sources":["../../src/segmentedControl/SegmentedControl.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { createRef, useEffect, useRef, useState } from 'react';\n\nimport Body from '../body';\nimport { Typography } from '../common';\n\ntype SegmentBase = { id: string; label: string; value: string };\n\ntype Segment = SegmentBase & { controls?: never };\ntype SegmentWithControls = SegmentBase & { controls: string };\n\nexport type Segments = readonly Segment[] | readonly SegmentWithControls[];\n\ntype SegmentedControlPropsBase = {\n  name: string;\n  value: string;\n  mode: 'input' | 'view';\n  onChange: (value: string) => void;\n};\n\ntype SegmentedControlViewProps = {\n  mode: 'view';\n  segments: readonly SegmentWithControls[];\n};\n\ntype SegmentedControlInputProps = {\n  mode: 'input';\n  segments: readonly Segment[];\n};\n\nexport type SegmentedControlProps = SegmentedControlPropsBase &\n  (SegmentedControlViewProps | SegmentedControlInputProps);\n\nconst SegmentedControl = ({\n  name,\n  value,\n  mode = 'input',\n  segments,\n  onChange,\n}: SegmentedControlProps) => {\n  const [animate, setAnimate] = useState(false);\n\n  const segmentsRef = useRef<HTMLDivElement>(null);\n\n  if (segments.length > 3) {\n    throw new Error(\n      'SegmentedControl only supports up to 3 segments. Please refer to: https://wise.design/components/segmented-control',\n    );\n  }\n\n  const segmentsWithRefs = segments.map((segment) => ({\n    ...segment,\n    ref: createRef<HTMLLabelElement | HTMLButtonElement>(),\n  }));\n\n  const updateSegmentPosition = () => {\n    const selectedSegmentRef = segmentsWithRefs.find((segment) => segment.value === value)?.ref;\n\n    // We grab the active segments style object from the ref\n    // and set the css variables to the selected segments width and x position.\n    // This is so we can animate the highlight to the selected segment\n    if (selectedSegmentRef?.current && segmentsRef.current) {\n      const { style } = segmentsRef.current;\n      style.setProperty('--segment-highlight-width', `${selectedSegmentRef.current.offsetWidth}px`);\n      style.setProperty('--segment-highlight-x', `${selectedSegmentRef.current.offsetLeft}px`);\n    }\n  };\n\n  useEffect(() => {\n    setAnimate(true);\n    updateSegmentPosition();\n\n    const handleWindowSizeChange = () => {\n      setAnimate(false);\n      updateSegmentPosition();\n    };\n\n    window.addEventListener('resize', handleWindowSizeChange);\n    return () => {\n      window.removeEventListener('resize', handleWindowSizeChange);\n    };\n\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [segmentsWithRefs, value]);\n\n  return (\n    <div\n      ref={segmentsRef}\n      data-testid=\"segmented-control\"\n      className={clsx('segmented-control', {\n        'segmented-control--input': mode === 'input',\n      })}\n    >\n      <div\n        className={clsx('segmented-control__segments', {\n          'segmented-control__segments--no-animate': !animate,\n        })}\n        role={mode !== 'input' ? 'tablist' : undefined}\n      >\n        {segmentsWithRefs.map((segment) => {\n          const onSelect = () => {\n            setAnimate(true);\n            onChange(segment.value);\n          };\n          return mode === 'input' ? (\n            <label\n              ref={segment.ref as React.MutableRefObject<HTMLLabelElement | null>}\n              key={segment.id}\n              htmlFor={segment.id}\n              className={clsx('segmented-control__segment', {\n                'segmented-control__selected-segment': value === segment.value,\n              })}\n            >\n              <input\n                type=\"radio\"\n                className=\"segmented-control__radio-input\"\n                id={segment.id}\n                name={name}\n                value={segment.value}\n                checked={value === segment.value}\n                onChange={onSelect}\n              />\n              <Body\n                className=\"segmented-control__text\"\n                as=\"span\"\n                type={\n                  value === segment.value ? Typography.BODY_DEFAULT_BOLD : Typography.BODY_DEFAULT\n                }\n              >\n                {segment.label}\n              </Body>\n            </label>\n          ) : (\n            <button\n              ref={segment.ref as React.MutableRefObject<HTMLButtonElement | null>}\n              key={segment.id}\n              type=\"button\"\n              role=\"tab\"\n              id={segment.id}\n              aria-controls={segment.controls}\n              aria-selected={value === segment.value}\n              className={clsx('segmented-control__segment', 'segmented-control__button', {\n                'segmented-control__selected-segment': value === segment.value,\n              })}\n              onClick={onSelect}\n            >\n              <Body\n                as=\"span\"\n                className=\"segmented-control__text\"\n                type={\n                  value === segment.value ? Typography.BODY_DEFAULT_BOLD : Typography.BODY_DEFAULT\n                }\n              >\n                {segment.label}\n              </Body>\n            </button>\n          );\n        })}\n      </div>\n    </div>\n  );\n};\n\nexport default SegmentedControl;\n"],"names":["SegmentedControl","name","value","mode","segments","onChange","animate","setAnimate","useState","segmentsRef","useRef","length","Error","segmentsWithRefs","map","segment","ref","createRef","updateSegmentPosition","selectedSegmentRef","find","current","style","setProperty","offsetWidth","offsetLeft","useEffect","handleWindowSizeChange","window","addEventListener","removeEventListener","_jsx","className","clsx","children","role","undefined","onSelect","_jsxs","htmlFor","id","type","checked","Body","as","Typography","BODY_DEFAULT_BOLD","BODY_DEFAULT","label","controls","onClick"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAMA,gBAAgB,GAAGA,CAAC;EACxBC,IAAI;EACJC,KAAK;AACLC,EAAAA,IAAI,GAAG,OAAO;EACdC,QAAQ;AACRC,EAAAA;AAAQ,CACc,KAAI;EAC1B,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAGC,QAAQ,CAAC,KAAK,CAAC;AAE7C,EAAA,MAAMC,WAAW,GAAGC,MAAM,CAAiB,IAAI,CAAC;AAEhD,EAAA,IAAIN,QAAQ,CAACO,MAAM,GAAG,CAAC,EAAE;AACvB,IAAA,MAAM,IAAIC,KAAK,CACb,oHAAoH,CACrH;AACH,EAAA;AAEA,EAAA,MAAMC,gBAAgB,GAAGT,QAAQ,CAACU,GAAG,CAAEC,OAAO,KAAM;AAClD,IAAA,GAAGA,OAAO;IACVC,GAAG,eAAEC,SAAS;AACf,GAAA,CAAC,CAAC;EAEH,MAAMC,qBAAqB,GAAGA,MAAK;AACjC,IAAA,MAAMC,kBAAkB,GAAGN,gBAAgB,CAACO,IAAI,CAAEL,OAAO,IAAKA,OAAO,CAACb,KAAK,KAAKA,KAAK,CAAC,EAAEc,GAAG;AAE3F;AACA;AACA;AACA,IAAA,IAAIG,kBAAkB,EAAEE,OAAO,IAAIZ,WAAW,CAACY,OAAO,EAAE;MACtD,MAAM;AAAEC,QAAAA;OAAO,GAAGb,WAAW,CAACY,OAAO;AACrCC,MAAAA,KAAK,CAACC,WAAW,CAAC,2BAA2B,EAAE,CAAA,EAAGJ,kBAAkB,CAACE,OAAO,CAACG,WAAW,CAAA,EAAA,CAAI,CAAC;AAC7FF,MAAAA,KAAK,CAACC,WAAW,CAAC,uBAAuB,EAAE,CAAA,EAAGJ,kBAAkB,CAACE,OAAO,CAACI,UAAU,CAAA,EAAA,CAAI,CAAC;AAC1F,IAAA;EACF,CAAC;AAEDC,EAAAA,SAAS,CAAC,MAAK;IACbnB,UAAU,CAAC,IAAI,CAAC;AAChBW,IAAAA,qBAAqB,EAAE;IAEvB,MAAMS,sBAAsB,GAAGA,MAAK;MAClCpB,UAAU,CAAC,KAAK,CAAC;AACjBW,MAAAA,qBAAqB,EAAE;IACzB,CAAC;AAEDU,IAAAA,MAAM,CAACC,gBAAgB,CAAC,QAAQ,EAAEF,sBAAsB,CAAC;AACzD,IAAA,OAAO,MAAK;AACVC,MAAAA,MAAM,CAACE,mBAAmB,CAAC,QAAQ,EAAEH,sBAAsB,CAAC;IAC9D,CAAC;AAED;AACF,EAAA,CAAC,EAAE,CAACd,gBAAgB,EAAEX,KAAK,CAAC,CAAC;AAE7B,EAAA,oBACE6B,GAAA,CAAA,KAAA,EAAA;AACEf,IAAAA,GAAG,EAAEP,WAAY;AACjB,IAAA,aAAA,EAAY,mBAAmB;AAC/BuB,IAAAA,SAAS,EAAEC,IAAI,CAAC,mBAAmB,EAAE;MACnC,0BAA0B,EAAE9B,IAAI,KAAK;AACtC,KAAA,CAAE;AAAA+B,IAAAA,QAAA,eAEHH,GAAA,CAAA,KAAA,EAAA;AACEC,MAAAA,SAAS,EAAEC,IAAI,CAAC,6BAA6B,EAAE;AAC7C,QAAA,yCAAyC,EAAE,CAAC3B;AAC7C,OAAA,CAAE;AACH6B,MAAAA,IAAI,EAAEhC,IAAI,KAAK,OAAO,GAAG,SAAS,GAAGiC,SAAU;AAAAF,MAAAA,QAAA,EAE9CrB,gBAAgB,CAACC,GAAG,CAAEC,OAAO,IAAI;QAChC,MAAMsB,QAAQ,GAAGA,MAAK;UACpB9B,UAAU,CAAC,IAAI,CAAC;AAChBF,UAAAA,QAAQ,CAACU,OAAO,CAACb,KAAK,CAAC;QACzB,CAAC;AACD,QAAA,OAAOC,IAAI,KAAK,OAAO,gBACrBmC,IAAA,CAAA,OAAA,EAAA;UACEtB,GAAG,EAAED,OAAO,CAACC,GAAuD;UAEpEuB,OAAO,EAAExB,OAAO,CAACyB,EAAG;AACpBR,UAAAA,SAAS,EAAEC,IAAI,CAAC,4BAA4B,EAAE;AAC5C,YAAA,qCAAqC,EAAE/B,KAAK,KAAKa,OAAO,CAACb;AAC1D,WAAA,CAAE;AAAAgC,UAAAA,QAAA,gBAEHH,GAAA,CAAA,OAAA,EAAA;AACEU,YAAAA,IAAI,EAAC,OAAO;AACZT,YAAAA,SAAS,EAAC,gCAAgC;YAC1CQ,EAAE,EAAEzB,OAAO,CAACyB,EAAG;AACfvC,YAAAA,IAAI,EAAEA,IAAK;YACXC,KAAK,EAAEa,OAAO,CAACb,KAAM;AACrBwC,YAAAA,OAAO,EAAExC,KAAK,KAAKa,OAAO,CAACb,KAAM;AACjCG,YAAAA,QAAQ,EAAEgC;AAAS,WAAA,CAErB,eAAAN,GAAA,CAACY,IAAI,EAAA;AACHX,YAAAA,SAAS,EAAC,yBAAyB;AACnCY,YAAAA,EAAE,EAAC,MAAM;AACTH,YAAAA,IAAI,EACFvC,KAAK,KAAKa,OAAO,CAACb,KAAK,GAAG2C,UAAU,CAACC,iBAAiB,GAAGD,UAAU,CAACE,YACrE;YAAAb,QAAA,EAEAnB,OAAO,CAACiC;AAAK,WACV,CACR;AAAA,SAAA,EAxBOjC,OAAO,CAACyB,EAwBR,CAAC,gBAERT,GAAA,CAAA,QAAA,EAAA;UACEf,GAAG,EAAED,OAAO,CAACC,GAAwD;AAErEyB,UAAAA,IAAI,EAAC,QAAQ;AACbN,UAAAA,IAAI,EAAC,KAAK;UACVK,EAAE,EAAEzB,OAAO,CAACyB,EAAG;UACf,eAAA,EAAezB,OAAO,CAACkC,QAAS;AAChC,UAAA,eAAA,EAAe/C,KAAK,KAAKa,OAAO,CAACb,KAAM;AACvC8B,UAAAA,SAAS,EAAEC,IAAI,CAAC,4BAA4B,EAAE,2BAA2B,EAAE;AACzE,YAAA,qCAAqC,EAAE/B,KAAK,KAAKa,OAAO,CAACb;AAC1D,WAAA,CAAE;AACHgD,UAAAA,OAAO,EAAEb,QAAS;UAAAH,QAAA,eAElBH,GAAA,CAACY,IAAI,EAAA;AACHC,YAAAA,EAAE,EAAC,MAAM;AACTZ,YAAAA,SAAS,EAAC,yBAAyB;AACnCS,YAAAA,IAAI,EACFvC,KAAK,KAAKa,OAAO,CAACb,KAAK,GAAG2C,UAAU,CAACC,iBAAiB,GAAGD,UAAU,CAACE,YACrE;YAAAb,QAAA,EAEAnB,OAAO,CAACiC;WACL;SACR,EApBOjC,OAAO,CAACyB,EAoBP,CACT;MACH,CAAC;KACE;AACP,GAAK,CAAC;AAEV;;;;"}