@transferwise/components 0.0.0-experimental-af6dee0 → 0.0.0-experimental-199a021

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.
Files changed (145) hide show
  1. package/build/avatarWrapper/AvatarWrapper.js +3 -4
  2. package/build/avatarWrapper/AvatarWrapper.js.map +1 -1
  3. package/build/avatarWrapper/AvatarWrapper.mjs +4 -5
  4. package/build/avatarWrapper/AvatarWrapper.mjs.map +1 -1
  5. package/build/button/LegacyButton.js.map +1 -1
  6. package/build/button/LegacyButton.mjs.map +1 -1
  7. package/build/common/hooks/useHasIntersected/useHasIntersected.js +6 -4
  8. package/build/common/hooks/useHasIntersected/useHasIntersected.js.map +1 -1
  9. package/build/common/hooks/useHasIntersected/useHasIntersected.mjs +6 -4
  10. package/build/common/hooks/useHasIntersected/useHasIntersected.mjs.map +1 -1
  11. package/build/common/liveRegion/LiveRegion.js +4 -1
  12. package/build/common/liveRegion/LiveRegion.js.map +1 -1
  13. package/build/common/liveRegion/LiveRegion.mjs +4 -1
  14. package/build/common/liveRegion/LiveRegion.mjs.map +1 -1
  15. package/build/dateInput/DateInput.js +10 -10
  16. package/build/dateInput/DateInput.js.map +1 -1
  17. package/build/dateInput/DateInput.mjs +10 -10
  18. package/build/dateInput/DateInput.mjs.map +1 -1
  19. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.js +1 -1
  20. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.js.map +1 -1
  21. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.mjs +1 -1
  22. package/build/dateLookup/monthCalendar/table/MonthCalendarTable.mjs.map +1 -1
  23. package/build/dateLookup/yearCalendar/table/YearCalendarTable.js +1 -1
  24. package/build/dateLookup/yearCalendar/table/YearCalendarTable.js.map +1 -1
  25. package/build/dateLookup/yearCalendar/table/YearCalendarTable.mjs +1 -1
  26. package/build/dateLookup/yearCalendar/table/YearCalendarTable.mjs.map +1 -1
  27. package/build/expressiveMoneyInput/ExpressiveMoneyInput.js.map +1 -1
  28. package/build/expressiveMoneyInput/ExpressiveMoneyInput.mjs.map +1 -1
  29. package/build/expressiveMoneyInput/amountInput/AmountInput.js +17 -11
  30. package/build/expressiveMoneyInput/amountInput/AmountInput.js.map +1 -1
  31. package/build/expressiveMoneyInput/amountInput/AmountInput.mjs +18 -12
  32. package/build/expressiveMoneyInput/amountInput/AmountInput.mjs.map +1 -1
  33. package/build/expressiveMoneyInput/hooks/useInputStyle.js +8 -6
  34. package/build/expressiveMoneyInput/hooks/useInputStyle.js.map +1 -1
  35. package/build/expressiveMoneyInput/hooks/useInputStyle.mjs +9 -7
  36. package/build/expressiveMoneyInput/hooks/useInputStyle.mjs.map +1 -1
  37. package/build/header/Header.js +1 -1
  38. package/build/header/Header.js.map +1 -1
  39. package/build/header/Header.mjs +1 -1
  40. package/build/header/Header.mjs.map +1 -1
  41. package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.js.map +1 -1
  42. package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.mjs.map +1 -1
  43. package/build/inputs/SelectInput/Options/SelectInputOptions.js +31 -22
  44. package/build/inputs/SelectInput/Options/SelectInputOptions.js.map +1 -1
  45. package/build/inputs/SelectInput/Options/SelectInputOptions.mjs +32 -23
  46. package/build/inputs/SelectInput/Options/SelectInputOptions.mjs.map +1 -1
  47. package/build/inputs/SelectInput/Popover/SelectInputPopover.js.map +1 -1
  48. package/build/inputs/SelectInput/Popover/SelectInputPopover.mjs.map +1 -1
  49. package/build/inputs/SelectInput/SelectInput.js +8 -6
  50. package/build/inputs/SelectInput/SelectInput.js.map +1 -1
  51. package/build/inputs/SelectInput/SelectInput.mjs +9 -7
  52. package/build/inputs/SelectInput/SelectInput.mjs.map +1 -1
  53. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.js.map +1 -1
  54. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.mjs.map +1 -1
  55. package/build/loader/Loader.js +6 -16
  56. package/build/loader/Loader.js.map +1 -1
  57. package/build/loader/Loader.mjs +7 -17
  58. package/build/loader/Loader.mjs.map +1 -1
  59. package/build/main.css +4 -15
  60. package/build/nudge/Nudge.js +26 -15
  61. package/build/nudge/Nudge.js.map +1 -1
  62. package/build/nudge/Nudge.mjs +26 -15
  63. package/build/nudge/Nudge.mjs.map +1 -1
  64. package/build/phoneNumberInput/PhoneNumberInput.js +9 -12
  65. package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
  66. package/build/phoneNumberInput/PhoneNumberInput.mjs +9 -12
  67. package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
  68. package/build/promoCard/PromoCardGroup.js +34 -16
  69. package/build/promoCard/PromoCardGroup.js.map +1 -1
  70. package/build/promoCard/PromoCardGroup.mjs +35 -17
  71. package/build/promoCard/PromoCardGroup.mjs.map +1 -1
  72. package/build/segmentedControl/SegmentedControl.js +6 -1
  73. package/build/segmentedControl/SegmentedControl.js.map +1 -1
  74. package/build/segmentedControl/SegmentedControl.mjs +7 -2
  75. package/build/segmentedControl/SegmentedControl.mjs.map +1 -1
  76. package/build/styles/loader/Loader.css +4 -14
  77. package/build/styles/main.css +4 -15
  78. package/build/tabs/Tabs.js +1 -1
  79. package/build/tabs/Tabs.js.map +1 -1
  80. package/build/tabs/Tabs.mjs +1 -1
  81. package/build/tabs/Tabs.mjs.map +1 -1
  82. package/build/tooltip/Tooltip.js +6 -3
  83. package/build/tooltip/Tooltip.js.map +1 -1
  84. package/build/tooltip/Tooltip.mjs +6 -3
  85. package/build/tooltip/Tooltip.mjs.map +1 -1
  86. package/build/types/avatarWrapper/AvatarWrapper.d.ts.map +1 -1
  87. package/build/types/common/hooks/useHasIntersected/useHasIntersected.d.ts.map +1 -1
  88. package/build/types/common/liveRegion/LiveRegion.d.ts.map +1 -1
  89. package/build/types/dateLookup/monthCalendar/table/MonthCalendarTable.d.ts.map +1 -1
  90. package/build/types/expressiveMoneyInput/ExpressiveMoneyInput.d.ts.map +1 -1
  91. package/build/types/expressiveMoneyInput/amountInput/AmountInput.d.ts.map +1 -1
  92. package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts +2 -2
  93. package/build/types/expressiveMoneyInput/hooks/useInputStyle.d.ts.map +1 -1
  94. package/build/types/expressiveMoneyInput/hooks/useSelectionRange.d.ts.map +1 -1
  95. package/build/types/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.d.ts.map +1 -1
  96. package/build/types/inputs/SelectInput/Options/SelectInputOptions.d.ts.map +1 -1
  97. package/build/types/inputs/SelectInput/Popover/SelectInputPopover.d.ts.map +1 -1
  98. package/build/types/inputs/SelectInput/SelectInput.d.ts.map +1 -1
  99. package/build/types/loader/Loader.d.ts +1 -4
  100. package/build/types/loader/Loader.d.ts.map +1 -1
  101. package/build/types/nudge/Nudge.d.ts.map +1 -1
  102. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  103. package/build/types/promoCard/PromoCardGroup.d.ts.map +1 -1
  104. package/build/types/segmentedControl/SegmentedControl.d.ts.map +1 -1
  105. package/build/types/tooltip/Tooltip.d.ts.map +1 -1
  106. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  107. package/build/uploadInput/UploadInput.js +29 -28
  108. package/build/uploadInput/UploadInput.js.map +1 -1
  109. package/build/uploadInput/UploadInput.mjs +29 -28
  110. package/build/uploadInput/UploadInput.mjs.map +1 -1
  111. package/package.json +3 -3
  112. package/src/avatarWrapper/AvatarWrapper.tsx +5 -6
  113. package/src/button/LegacyButton.tsx +1 -1
  114. package/src/button/_stories/Button.test.story.tsx +3 -3
  115. package/src/common/hooks/useContainerSize.test.tsx +1 -1
  116. package/src/common/hooks/useHasIntersected/useHasIntersected.ts +12 -4
  117. package/src/common/liveRegion/LiveRegion.tsx +5 -2
  118. package/src/dateInput/DateInput.tsx +10 -10
  119. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.tsx +1 -5
  120. package/src/dateLookup/yearCalendar/table/YearCalendarTable.tsx +1 -1
  121. package/src/expressiveMoneyInput/ExpressiveMoneyInput.tsx +1 -1
  122. package/src/expressiveMoneyInput/amountInput/AmountInput.tsx +22 -15
  123. package/src/expressiveMoneyInput/hooks/useInputStyle.ts +20 -8
  124. package/src/expressiveMoneyInput/hooks/useSelectionRange.ts +2 -0
  125. package/src/header/Header.tsx +2 -2
  126. package/src/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.tsx +4 -0
  127. package/src/inputs/SelectInput/Options/SelectInputOptions.tsx +39 -26
  128. package/src/inputs/SelectInput/Popover/SelectInputPopover.tsx +4 -0
  129. package/src/inputs/SelectInput/SelectInput.tsx +21 -15
  130. package/src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx +1 -1
  131. package/src/loader/Loader.css +4 -14
  132. package/src/loader/Loader.less +88 -54
  133. package/src/loader/Loader.story.tsx +0 -4
  134. package/src/loader/Loader.test.tsx +5 -20
  135. package/src/loader/Loader.tsx +7 -18
  136. package/src/main.css +4 -15
  137. package/src/nudge/Nudge.tsx +22 -19
  138. package/src/phoneNumberInput/PhoneNumberInput.tsx +11 -13
  139. package/src/promoCard/PromoCard.story.tsx +3 -3
  140. package/src/promoCard/PromoCardGroup.tsx +39 -21
  141. package/src/segmentedControl/SegmentedControl.tsx +7 -1
  142. package/src/select/Select.story.tsx +1 -1
  143. package/src/tabs/Tabs.tsx +1 -1
  144. package/src/tooltip/Tooltip.tsx +3 -0
  145. package/src/uploadInput/UploadInput.tsx +28 -27
@@ -1 +1 @@
1
- {"version":3,"file":"PhoneNumberInput.mjs","sources":["../../src/phoneNumberInput/PhoneNumberInput.tsx"],"sourcesContent":["import { useState, useEffect, useMemo, useRef } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { Size, SizeLarge, SizeMedium, SizeSmall } from '../common';\nimport { useFieldLabelRef, useInputAttributes } from '../inputs/contexts';\nimport { useInputPaddings } from '../inputs/InputGroup';\nimport { SelectInput, SelectInputOptionContent, SelectInputProps } from '../inputs/SelectInput';\nimport messages from './PhoneNumberInput.messages';\nimport countries from './data/countries';\nimport {\n explodeNumberModel,\n isValidPhoneNumber,\n cleanNumber,\n setDefaultPrefix,\n sortArrayByProperty,\n groupCountriesByPrefix,\n excludeCountries,\n findCountryByPrefix,\n} from './utils';\nimport { PhoneNumber } from './utils/explodeNumberModel';\nimport { Input } from '../inputs/Input';\n\nconst ALLOWED_PHONE_CHARS = /^$|^[\\d-\\s]+$/;\n\nexport interface PhoneNumberInputProps {\n id?: string;\n 'aria-labelledby'?: string;\n required?: boolean;\n disabled?: boolean;\n initialValue?: string;\n onChange: (value: string | null, prefix: string) => void;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onBlur?: () => void;\n countryCode?: string;\n /** @default 'Prefix' */\n searchPlaceholder?: string;\n /** @default 'md' */\n size?: SizeSmall | SizeMedium | SizeLarge;\n placeholder?: string;\n /** @default {} */\n selectProps?: Partial<SelectInputProps<string | null>>;\n /**\n * List of iso3 codes of countries to remove from the list\n * @default []\n */\n disabledCountries?: readonly string[];\n}\n\nconst defaultSelectProps = {} satisfies PhoneNumberInputProps['selectProps'];\nconst defaultDisabledCountries = [] satisfies PhoneNumberInputProps['disabledCountries'];\n\nconst PhoneNumberInput = ({\n id,\n 'aria-labelledby': ariaLabelledByProp,\n required,\n disabled,\n initialValue,\n onChange,\n onFocus,\n onBlur,\n countryCode,\n searchPlaceholder = 'Prefix',\n size = Size.MEDIUM,\n placeholder,\n selectProps = defaultSelectProps,\n disabledCountries = defaultDisabledCountries,\n}: PhoneNumberInputProps) => {\n const countryCodeSelectRef = useRef<HTMLButtonElement>(null);\n const phoneNumberInputRef = useRef<HTMLInputElement>(null);\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const { paddingInlineStart } = useInputPaddings();\n const hasInputGroupAddonStart = paddingInlineStart != null;\n const fieldLabelRef = useFieldLabelRef();\n const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];\n\n const { locale, formatMessage } = useIntl();\n\n const createId = (customID: string | undefined, backup: string): string => {\n if (customID) {\n return customID + (backup ? `-${backup}` : '');\n }\n const random = Math.random().toString(36).slice(2, 8);\n return `${backup}-${random}`;\n };\n\n // Link the first non-disabled input to the the Field label, if present\n const ids = {\n countryCode: {\n label: createId(id, 'country-code-label'),\n select: createId(id, 'country-code-select'),\n },\n phoneNumber: {\n label: createId(id, 'phone-number-label'),\n input: createId(id, id ? '' : 'phone-number-input'),\n },\n };\n\n const [internalValue, setInternalValue] = useState<PhoneNumber>(() => {\n const cleanValue = initialValue ? cleanNumber(initialValue) : null;\n\n if (!cleanValue || !isValidPhoneNumber(cleanValue, 1)) {\n return {\n prefix: setDefaultPrefix(locale, countryCode),\n suffix: '',\n };\n }\n\n return explodeNumberModel(cleanValue);\n });\n const [broadcastedValue, setBroadcastedValue] = useState<PhoneNumber | null>(null);\n\n const [suffixDirty, setSuffixDirty] = useState(false);\n useEffect(() => {\n if (internalValue.suffix) {\n setSuffixDirty(true);\n }\n }, [internalValue.suffix]);\n\n const countriesByPrefix = useMemo(\n () =>\n groupCountriesByPrefix(\n sortArrayByProperty(excludeCountries(countries, disabledCountries), 'iso3'),\n ),\n [disabledCountries],\n );\n\n const onSuffixChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {\n const suffix = event.target.value;\n if (ALLOWED_PHONE_CHARS.test(suffix)) {\n setInternalValue((prev) => ({ ...prev, suffix }));\n }\n };\n\n const onPaste: React.ClipboardEventHandler<HTMLInputElement> = (event) => {\n if (!event.nativeEvent.clipboardData) {\n return;\n }\n\n const pastedValue = (event.nativeEvent.clipboardData.getData('text/plain') || '').replace(\n /(\\s|-)+/g,\n '',\n );\n const pastedNumber = explodeNumberModel(pastedValue);\n\n if (\n pastedNumber.prefix != null &&\n countriesByPrefix.has(pastedNumber.prefix) &&\n ALLOWED_PHONE_CHARS.test(pastedNumber.suffix)\n ) {\n setInternalValue(pastedNumber);\n }\n };\n\n useEffect(() => {\n if (broadcastedValue === null) {\n setBroadcastedValue(internalValue);\n return;\n }\n\n const internalPhoneNumber = `${internalValue.prefix ?? ''}${internalValue.suffix}`;\n const broadcastedPhoneNumber = `${broadcastedValue.prefix ?? ''}${broadcastedValue.suffix}`;\n\n if (internalPhoneNumber === broadcastedPhoneNumber) {\n return;\n }\n\n const newValue = isValidPhoneNumber(internalPhoneNumber)\n ? cleanNumber(internalPhoneNumber)\n : null;\n\n onChange(\n newValue,\n internalValue.prefix ?? '', // TODO: Allow `null` in public API\n );\n setBroadcastedValue(internalValue);\n }, [onChange, broadcastedValue, internalValue]);\n\n useEffect(() => {\n const labelRef = fieldLabelRef?.current;\n\n if (labelRef) {\n const handleLabelClick = () => {\n if (!selectProps.disabled) {\n countryCodeSelectRef.current?.click();\n } else {\n phoneNumberInputRef.current?.focus();\n }\n };\n\n labelRef.addEventListener('click', handleLabelClick);\n\n return () => {\n labelRef?.removeEventListener('click', handleLabelClick);\n };\n }\n }, [fieldLabelRef, selectProps.disabled]);\n\n return (\n <fieldset {...inputAttributes} aria-labelledby={ariaLabelledBy} className=\"tw-telephone\">\n <label className=\"sr-only\" id={ids.countryCode.label} htmlFor={ids.countryCode.select}>\n {formatMessage(messages.countryCodeLabel)}\n </label>\n <div\n className={`tw-telephone__country-select${\n hasInputGroupAddonStart\n ? ' tw-telephone__country-select--with-input-group-addon-start'\n : ''\n }`}\n >\n <SelectInput\n triggerRef={countryCodeSelectRef}\n placeholder={formatMessage(messages.selectInputPlaceholder)}\n items={[...countriesByPrefix].map(([prefix, countries]) => ({\n type: 'option',\n value: prefix,\n filterMatchers: [\n prefix,\n ...countries.map((country) => country.name),\n ...countries.map((country) => country.iso3),\n ],\n }))}\n value={internalValue.prefix}\n renderValue={(prefix, withinTrigger) => (\n <SelectInputOptionContent\n title={prefix}\n note={\n withinTrigger\n ? undefined\n : countriesByPrefix\n .get(prefix)\n ?.map((country) => country.iso3)\n .join(', ')\n }\n />\n )}\n filterable\n filterPlaceholder={searchPlaceholder}\n disabled={disabled}\n size={size}\n id={ids.countryCode.select}\n UNSAFE_triggerButtonProps={{\n id: ids.countryCode.select,\n 'aria-labelledby': ids.countryCode.label,\n 'aria-describedby': undefined,\n 'aria-invalid': undefined,\n }}\n onChange={(prefix) => {\n const country = prefix != null ? findCountryByPrefix(prefix) : null;\n setInternalValue((prev) => ({ ...prev, prefix, format: country?.phoneFormat }));\n }}\n onClose={() => {\n if (suffixDirty) {\n onBlur?.();\n }\n }}\n {...selectProps}\n />\n </div>\n <label className=\"sr-only\" id={ids.phoneNumber.label} htmlFor={ids.phoneNumber.input}>\n {formatMessage(messages.phoneNumberLabel)}\n </label>\n <div className=\"tw-telephone__number-input\">\n <div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>\n <Input\n ref={phoneNumberInputRef}\n id={ids.phoneNumber.input}\n autoComplete=\"tel-national\"\n name=\"phoneNumber\"\n inputMode=\"numeric\"\n value={internalValue.suffix}\n disabled={disabled}\n required={required}\n placeholder={placeholder}\n aria-labelledby={ids.phoneNumber.label}\n onChange={onSuffixChange}\n onPaste={onPaste}\n onFocus={onFocus}\n onBlur={() => onBlur?.()}\n />\n </div>\n </div>\n </fieldset>\n );\n};\n\nexport default PhoneNumberInput;\n"],"names":["ALLOWED_PHONE_CHARS","defaultSelectProps","defaultDisabledCountries","PhoneNumberInput","id","ariaLabelledByProp","required","disabled","initialValue","onChange","onFocus","onBlur","countryCode","searchPlaceholder","size","Size","MEDIUM","placeholder","selectProps","disabledCountries","countryCodeSelectRef","useRef","phoneNumberInputRef","inputAttributes","useInputAttributes","nonLabelable","paddingInlineStart","useInputPaddings","hasInputGroupAddonStart","fieldLabelRef","useFieldLabelRef","ariaLabelledBy","locale","formatMessage","useIntl","createId","customID","backup","random","Math","toString","slice","ids","label","select","phoneNumber","input","internalValue","setInternalValue","useState","cleanValue","cleanNumber","isValidPhoneNumber","prefix","setDefaultPrefix","suffix","explodeNumberModel","broadcastedValue","setBroadcastedValue","suffixDirty","setSuffixDirty","useEffect","countriesByPrefix","useMemo","groupCountriesByPrefix","sortArrayByProperty","excludeCountries","countries","onSuffixChange","event","target","value","test","prev","onPaste","nativeEvent","clipboardData","pastedValue","getData","replace","pastedNumber","has","internalPhoneNumber","broadcastedPhoneNumber","newValue","labelRef","current","handleLabelClick","click","focus","addEventListener","removeEventListener","_jsxs","className","children","_jsx","htmlFor","messages","countryCodeLabel","SelectInput","triggerRef","selectInputPlaceholder","items","map","type","filterMatchers","country","name","iso3","renderValue","withinTrigger","SelectInputOptionContent","title","note","undefined","get","join","filterable","filterPlaceholder","UNSAFE_triggerButtonProps","findCountryByPrefix","format","phoneFormat","onClose","phoneNumberLabel","Input","ref","autoComplete","inputMode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAMA,mBAAmB,GAAG,eAAe;AA0B3C,MAAMC,kBAAkB,GAAG,EAAiD;AAC5E,MAAMC,wBAAwB,GAAG,EAAuD;AAExF,MAAMC,gBAAgB,GAAGA,CAAC;EACxBC,EAAE;AACF,EAAA,iBAAiB,EAAEC,kBAAkB;EACrCC,QAAQ;EACRC,QAAQ;EACRC,YAAY;EACZC,QAAQ;EACRC,OAAO;EACPC,MAAM;EACNC,WAAW;AACXC,EAAAA,iBAAiB,GAAG,QAAQ;EAC5BC,IAAI,GAAGC,IAAI,CAACC,MAAM;EAClBC,WAAW;AACXC,EAAAA,WAAW,GAAGjB,kBAAkB;AAChCkB,EAAAA,iBAAiB,GAAGjB;AAAwB,CACtB,KAAI;AAC1B,EAAA,MAAMkB,oBAAoB,GAAGC,MAAM,CAAoB,IAAI,CAAC;AAC5D,EAAA,MAAMC,mBAAmB,GAAGD,MAAM,CAAmB,IAAI,CAAC;EAC1D,MAAME,eAAe,GAAGC,kBAAkB,CAAC;AAAEC,IAAAA,YAAY,EAAE;AAAI,GAAE,CAAC;EAClE,MAAM;AAAEC,IAAAA;GAAoB,GAAGC,gBAAgB,EAAE;AACjD,EAAA,MAAMC,uBAAuB,GAAGF,kBAAkB,IAAI,IAAI;AAC1D,EAAA,MAAMG,aAAa,GAAGC,gBAAgB,EAAE;AACxC,EAAA,MAAMC,cAAc,GAAG1B,kBAAkB,IAAIkB,eAAe,CAAC,iBAAiB,CAAC;EAE/E,MAAM;IAAES,MAAM;AAAEC,IAAAA;GAAe,GAAGC,OAAO,EAAE;AAE3C,EAAA,MAAMC,QAAQ,GAAGA,CAACC,QAA4B,EAAEC,MAAc,KAAY;AACxE,IAAA,IAAID,QAAQ,EAAE;MACZ,OAAOA,QAAQ,IAAIC,MAAM,GAAG,IAAIA,MAAM,CAAA,CAAE,GAAG,EAAE,CAAC;AAChD,IAAA;AACA,IAAA,MAAMC,MAAM,GAAGC,IAAI,CAACD,MAAM,EAAE,CAACE,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AACrD,IAAA,OAAO,CAAA,EAAGJ,MAAM,CAAA,CAAA,EAAIC,MAAM,CAAA,CAAE;EAC9B,CAAC;AAED;AACA,EAAA,MAAMI,GAAG,GAAG;AACV9B,IAAAA,WAAW,EAAE;AACX+B,MAAAA,KAAK,EAAER,QAAQ,CAAC/B,EAAE,EAAE,oBAAoB,CAAC;AACzCwC,MAAAA,MAAM,EAAET,QAAQ,CAAC/B,EAAE,EAAE,qBAAqB;KAC3C;AACDyC,IAAAA,WAAW,EAAE;AACXF,MAAAA,KAAK,EAAER,QAAQ,CAAC/B,EAAE,EAAE,oBAAoB,CAAC;MACzC0C,KAAK,EAAEX,QAAQ,CAAC/B,EAAE,EAAEA,EAAE,GAAG,EAAE,GAAG,oBAAoB;AACnD;GACF;EAED,MAAM,CAAC2C,aAAa,EAAEC,gBAAgB,CAAC,GAAGC,QAAQ,CAAc,MAAK;IACnE,MAAMC,UAAU,GAAG1C,YAAY,GAAG2C,WAAW,CAAC3C,YAAY,CAAC,GAAG,IAAI;IAElE,IAAI,CAAC0C,UAAU,IAAI,CAACE,kBAAkB,CAACF,UAAU,EAAE,CAAC,CAAC,EAAE;MACrD,OAAO;AACLG,QAAAA,MAAM,EAAEC,gBAAgB,CAACtB,MAAM,EAAEpB,WAAW,CAAC;AAC7C2C,QAAAA,MAAM,EAAE;OACT;AACH,IAAA;IAEA,OAAOC,kBAAkB,CAACN,UAAU,CAAC;AACvC,EAAA,CAAC,CAAC;EACF,MAAM,CAACO,gBAAgB,EAAEC,mBAAmB,CAAC,GAAGT,QAAQ,CAAqB,IAAI,CAAC;EAElF,MAAM,CAACU,WAAW,EAAEC,cAAc,CAAC,GAAGX,QAAQ,CAAC,KAAK,CAAC;AACrDY,EAAAA,SAAS,CAAC,MAAK;IACb,IAAId,aAAa,CAACQ,MAAM,EAAE;MACxBK,cAAc,CAAC,IAAI,CAAC;AACtB,IAAA;AACF,EAAA,CAAC,EAAE,CAACb,aAAa,CAACQ,MAAM,CAAC,CAAC;EAE1B,MAAMO,iBAAiB,GAAGC,OAAO,CAC/B,MACEC,sBAAsB,CACpBC,mBAAmB,CAACC,gBAAgB,CAACC,SAAS,EAAEhD,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAC5E,EACH,CAACA,iBAAiB,CAAC,CACpB;EAED,MAAMiD,cAAc,GAAgDC,KAAK,IAAI;AAC3E,IAAA,MAAMd,MAAM,GAAGc,KAAK,CAACC,MAAM,CAACC,KAAK;AACjC,IAAA,IAAIvE,mBAAmB,CAACwE,IAAI,CAACjB,MAAM,CAAC,EAAE;MACpCP,gBAAgB,CAAEyB,IAAI,KAAM;AAAE,QAAA,GAAGA,IAAI;AAAElB,QAAAA;AAAM,OAAE,CAAC,CAAC;AACnD,IAAA;EACF,CAAC;EAED,MAAMmB,OAAO,GAAmDL,KAAK,IAAI;AACvE,IAAA,IAAI,CAACA,KAAK,CAACM,WAAW,CAACC,aAAa,EAAE;AACpC,MAAA;AACF,IAAA;IAEA,MAAMC,WAAW,GAAG,CAACR,KAAK,CAACM,WAAW,CAACC,aAAa,CAACE,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,EAAEC,OAAO,CACvF,UAAU,EACV,EAAE,CACH;AACD,IAAA,MAAMC,YAAY,GAAGxB,kBAAkB,CAACqB,WAAW,CAAC;IAEpD,IACEG,YAAY,CAAC3B,MAAM,IAAI,IAAI,IAC3BS,iBAAiB,CAACmB,GAAG,CAACD,YAAY,CAAC3B,MAAM,CAAC,IAC1CrD,mBAAmB,CAACwE,IAAI,CAACQ,YAAY,CAACzB,MAAM,CAAC,EAC7C;MACAP,gBAAgB,CAACgC,YAAY,CAAC;AAChC,IAAA;EACF,CAAC;AAEDnB,EAAAA,SAAS,CAAC,MAAK;IACb,IAAIJ,gBAAgB,KAAK,IAAI,EAAE;MAC7BC,mBAAmB,CAACX,aAAa,CAAC;AAClC,MAAA;AACF,IAAA;AAEA,IAAA,MAAMmC,mBAAmB,GAAG,CAAA,EAAGnC,aAAa,CAACM,MAAM,IAAI,EAAE,CAAA,EAAGN,aAAa,CAACQ,MAAM,CAAA,CAAE;AAClF,IAAA,MAAM4B,sBAAsB,GAAG,CAAA,EAAG1B,gBAAgB,CAACJ,MAAM,IAAI,EAAE,CAAA,EAAGI,gBAAgB,CAACF,MAAM,CAAA,CAAE;IAE3F,IAAI2B,mBAAmB,KAAKC,sBAAsB,EAAE;AAClD,MAAA;AACF,IAAA;AAEA,IAAA,MAAMC,QAAQ,GAAGhC,kBAAkB,CAAC8B,mBAAmB,CAAC,GACpD/B,WAAW,CAAC+B,mBAAmB,CAAC,GAChC,IAAI;IAERzE,QAAQ,CACN2E,QAAQ,EACRrC,aAAa,CAACM,MAAM,IAAI,EAAE,CAC3B;IACDK,mBAAmB,CAACX,aAAa,CAAC;EACpC,CAAC,EAAE,CAACtC,QAAQ,EAAEgD,gBAAgB,EAAEV,aAAa,CAAC,CAAC;AAE/Cc,EAAAA,SAAS,CAAC,MAAK;AACb,IAAA,MAAMwB,QAAQ,GAAGxD,aAAa,EAAEyD,OAAO;AAEvC,IAAA,IAAID,QAAQ,EAAE;MACZ,MAAME,gBAAgB,GAAGA,MAAK;AAC5B,QAAA,IAAI,CAACrE,WAAW,CAACX,QAAQ,EAAE;AACzBa,UAAAA,oBAAoB,CAACkE,OAAO,EAAEE,KAAK,EAAE;AACvC,QAAA,CAAC,MAAM;AACLlE,UAAAA,mBAAmB,CAACgE,OAAO,EAAEG,KAAK,EAAE;AACtC,QAAA;MACF,CAAC;AAEDJ,MAAAA,QAAQ,CAACK,gBAAgB,CAAC,OAAO,EAAEH,gBAAgB,CAAC;AAEpD,MAAA,OAAO,MAAK;AACVF,QAAAA,QAAQ,EAAEM,mBAAmB,CAAC,OAAO,EAAEJ,gBAAgB,CAAC;MAC1D,CAAC;AACH,IAAA;EACF,CAAC,EAAE,CAAC1D,aAAa,EAAEX,WAAW,CAACX,QAAQ,CAAC,CAAC;AAEzC,EAAA,oBACEqF,IAAA,CAAA,UAAA,EAAA;AAAA,IAAA,GAAcrE,eAAe;AAAE,IAAA,iBAAA,EAAiBQ,cAAe;AAAC8D,IAAAA,SAAS,EAAC,cAAc;AAAAC,IAAAA,QAAA,gBACtFC,GAAA,CAAA,OAAA,EAAA;AAAOF,MAAAA,SAAS,EAAC,SAAS;AAACzF,MAAAA,EAAE,EAAEsC,GAAG,CAAC9B,WAAW,CAAC+B,KAAM;AAACqD,MAAAA,OAAO,EAAEtD,GAAG,CAAC9B,WAAW,CAACgC,MAAO;AAAAkD,MAAAA,QAAA,EACnF7D,aAAa,CAACgE,QAAQ,CAACC,gBAAgB;KACnC,CACP,eAAAH,GAAA,CAAA,KAAA,EAAA;AACEF,MAAAA,SAAS,EAAE,CAAA,4BAAA,EACTjE,uBAAuB,GACnB,6DAA6D,GAC7D,EACN,CAAA,CAAG;MAAAkE,QAAA,eAEHC,GAAA,CAACI,WAAW,EAAA;AACVC,QAAAA,UAAU,EAAEhF,oBAAqB;AACjCH,QAAAA,WAAW,EAAEgB,aAAa,CAACgE,QAAQ,CAACI,sBAAsB,CAAE;AAC5DC,QAAAA,KAAK,EAAE,CAAC,GAAGxC,iBAAiB,CAAC,CAACyC,GAAG,CAAC,CAAC,CAAClD,MAAM,EAAEc,SAAS,CAAC,MAAM;AAC1DqC,UAAAA,IAAI,EAAE,QAAQ;AACdjC,UAAAA,KAAK,EAAElB,MAAM;UACboD,cAAc,EAAE,CACdpD,MAAM,EACN,GAAGc,SAAS,CAACoC,GAAG,CAAEG,OAAO,IAAKA,OAAO,CAACC,IAAI,CAAC,EAC3C,GAAGxC,SAAS,CAACoC,GAAG,CAAEG,OAAO,IAAKA,OAAO,CAACE,IAAI,CAAC;AAE9C,SAAA,CAAC,CAAE;QACJrC,KAAK,EAAExB,aAAa,CAACM,MAAO;QAC5BwD,WAAW,EAAEA,CAACxD,MAAM,EAAEyD,aAAa,kBACjCf,GAAA,CAACgB,wBAAwB,EAAA;AACvBC,UAAAA,KAAK,EAAE3D,MAAO;UACd4D,IAAI,EACFH,aAAa,GACTI,SAAS,GACTpD,iBAAiB,CACdqD,GAAG,CAAC9D,MAAM,CAAC,EACVkD,GAAG,CAAEG,OAAO,IAAKA,OAAO,CAACE,IAAI,CAAC,CAC/BQ,IAAI,CAAC,IAAI;AACjB,SAAA,CAEH;QACFC,UAAU,EAAA,IAAA;AACVC,QAAAA,iBAAiB,EAAEzG,iBAAkB;AACrCN,QAAAA,QAAQ,EAAEA,QAAS;AACnBO,QAAAA,IAAI,EAAEA,IAAK;AACXV,QAAAA,EAAE,EAAEsC,GAAG,CAAC9B,WAAW,CAACgC,MAAO;AAC3B2E,QAAAA,yBAAyB,EAAE;AACzBnH,UAAAA,EAAE,EAAEsC,GAAG,CAAC9B,WAAW,CAACgC,MAAM;AAC1B,UAAA,iBAAiB,EAAEF,GAAG,CAAC9B,WAAW,CAAC+B,KAAK;AACxC,UAAA,kBAAkB,EAAEuE,SAAS;AAC7B,UAAA,cAAc,EAAEA;SAChB;QACFzG,QAAQ,EAAG4C,MAAM,IAAI;UACnB,MAAMqD,OAAO,GAAGrD,MAAM,IAAI,IAAI,GAAGmE,mBAAmB,CAACnE,MAAM,CAAC,GAAG,IAAI;UACnEL,gBAAgB,CAAEyB,IAAI,KAAM;AAAE,YAAA,GAAGA,IAAI;YAAEpB,MAAM;YAAEoE,MAAM,EAAEf,OAAO,EAAEgB;AAAW,WAAE,CAAC,CAAC;QACjF,CAAE;QACFC,OAAO,EAAEA,MAAK;AACZ,UAAA,IAAIhE,WAAW,EAAE;AACfhD,YAAAA,MAAM,IAAI;AACZ,UAAA;QACF,CAAE;QAAA,GACEO;OAAY;KAEf,CACL,eAAA6E,GAAA,CAAA,OAAA,EAAA;AAAOF,MAAAA,SAAS,EAAC,SAAS;AAACzF,MAAAA,EAAE,EAAEsC,GAAG,CAACG,WAAW,CAACF,KAAM;AAACqD,MAAAA,OAAO,EAAEtD,GAAG,CAACG,WAAW,CAACC,KAAM;AAAAgD,MAAAA,QAAA,EAClF7D,aAAa,CAACgE,QAAQ,CAAC2B,gBAAgB;KACnC,CACP,eAAA7B,GAAA,CAAA,KAAA,EAAA;AAAKF,MAAAA,SAAS,EAAC,4BAA4B;AAAAC,MAAAA,QAAA,eACzCC,GAAA,CAAA,KAAA,EAAA;QAAKF,SAAS,EAAE,2BAA2B/E,IAAI,CAAA,CAAA,EAAIP,QAAQ,GAAG,UAAU,GAAG,EAAE,CAAA,CAAG;QAAAuF,QAAA,eAC9EC,GAAA,CAAC8B,KAAK,EAAA;AACJC,UAAAA,GAAG,EAAExG,mBAAoB;AACzBlB,UAAAA,EAAE,EAAEsC,GAAG,CAACG,WAAW,CAACC,KAAM;AAC1BiF,UAAAA,YAAY,EAAC,cAAc;AAC3BpB,UAAAA,IAAI,EAAC,aAAa;AAClBqB,UAAAA,SAAS,EAAC,SAAS;UACnBzD,KAAK,EAAExB,aAAa,CAACQ,MAAO;AAC5BhD,UAAAA,QAAQ,EAAEA,QAAS;AACnBD,UAAAA,QAAQ,EAAEA,QAAS;AACnBW,UAAAA,WAAW,EAAEA,WAAY;AACzB,UAAA,iBAAA,EAAiByB,GAAG,CAACG,WAAW,CAACF,KAAM;AACvClC,UAAAA,QAAQ,EAAE2D,cAAe;AACzBM,UAAAA,OAAO,EAAEA,OAAQ;AACjBhE,UAAAA,OAAO,EAAEA,OAAQ;AACjBC,UAAAA,MAAM,EAAEA,MAAMA,MAAM;SAAK;OAExB;AACP,KAAK,CACP;AAAA,GAAU,CAAC;AAEf;;;;"}
1
+ {"version":3,"file":"PhoneNumberInput.mjs","sources":["../../src/phoneNumberInput/PhoneNumberInput.tsx"],"sourcesContent":["import { useState, useEffect, useMemo, useRef } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport { Size, SizeLarge, SizeMedium, SizeSmall } from '../common';\nimport { useFieldLabelRef, useInputAttributes } from '../inputs/contexts';\nimport { useInputPaddings } from '../inputs/InputGroup';\nimport { SelectInput, SelectInputOptionContent, SelectInputProps } from '../inputs/SelectInput';\nimport messages from './PhoneNumberInput.messages';\nimport countries from './data/countries';\nimport {\n explodeNumberModel,\n isValidPhoneNumber,\n cleanNumber,\n setDefaultPrefix,\n sortArrayByProperty,\n groupCountriesByPrefix,\n excludeCountries,\n findCountryByPrefix,\n} from './utils';\nimport { PhoneNumber } from './utils/explodeNumberModel';\nimport { Input } from '../inputs/Input';\n\nconst ALLOWED_PHONE_CHARS = /^$|^[\\d-\\s]+$/;\n\nexport interface PhoneNumberInputProps {\n id?: string;\n 'aria-labelledby'?: string;\n required?: boolean;\n disabled?: boolean;\n initialValue?: string;\n onChange: (value: string | null, prefix: string) => void;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onBlur?: () => void;\n countryCode?: string;\n /** @default 'Prefix' */\n searchPlaceholder?: string;\n /** @default 'md' */\n size?: SizeSmall | SizeMedium | SizeLarge;\n placeholder?: string;\n /** @default {} */\n selectProps?: Partial<SelectInputProps<string | null>>;\n /**\n * List of iso3 codes of countries to remove from the list\n * @default []\n */\n disabledCountries?: readonly string[];\n}\n\nconst defaultSelectProps = {} satisfies PhoneNumberInputProps['selectProps'];\nconst defaultDisabledCountries = [] satisfies PhoneNumberInputProps['disabledCountries'];\n\nconst PhoneNumberInput = ({\n id,\n 'aria-labelledby': ariaLabelledByProp,\n required,\n disabled,\n initialValue,\n onChange,\n onFocus,\n onBlur,\n countryCode,\n searchPlaceholder = 'Prefix',\n size = Size.MEDIUM,\n placeholder,\n selectProps = defaultSelectProps,\n disabledCountries = defaultDisabledCountries,\n}: PhoneNumberInputProps) => {\n const countryCodeSelectRef = useRef<HTMLButtonElement>(null);\n const phoneNumberInputRef = useRef<HTMLInputElement>(null);\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const { paddingInlineStart } = useInputPaddings();\n const hasInputGroupAddonStart = paddingInlineStart != null;\n const fieldLabelRef = useFieldLabelRef();\n const ariaLabelledBy = ariaLabelledByProp ?? inputAttributes['aria-labelledby'];\n\n const { locale, formatMessage } = useIntl();\n\n const [randomId] = useState(() => Math.random().toString(36).slice(2, 8));\n\n const createId = (customID: string | undefined, backup: string): string => {\n if (customID) {\n return customID + (backup ? `-${backup}` : '');\n }\n return `${backup}-${randomId}`;\n };\n\n // Link the first non-disabled input to the the Field label, if present\n const ids = {\n countryCode: {\n label: createId(id, 'country-code-label'),\n select: createId(id, 'country-code-select'),\n },\n phoneNumber: {\n label: createId(id, 'phone-number-label'),\n input: createId(id, id ? '' : 'phone-number-input'),\n },\n };\n\n const [internalValue, setInternalValue] = useState<PhoneNumber>(() => {\n const cleanValue = initialValue ? cleanNumber(initialValue) : null;\n\n if (!cleanValue || !isValidPhoneNumber(cleanValue, 1)) {\n return {\n prefix: setDefaultPrefix(locale, countryCode),\n suffix: '',\n };\n }\n\n return explodeNumberModel(cleanValue);\n });\n const broadcastedValueRef = useRef<PhoneNumber>(internalValue);\n\n const [suffixDirty, setSuffixDirty] = useState(false);\n\n useEffect(() => {\n if (!suffixDirty && internalValue.suffix) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Tracking when suffix becomes dirty\n setSuffixDirty(true);\n }\n }, [internalValue.suffix, suffixDirty]);\n\n const countriesByPrefix = useMemo(\n () =>\n groupCountriesByPrefix(\n sortArrayByProperty(excludeCountries(countries, disabledCountries), 'iso3'),\n ),\n [disabledCountries],\n );\n\n const onSuffixChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {\n const suffix = event.target.value;\n if (ALLOWED_PHONE_CHARS.test(suffix)) {\n setInternalValue((prev) => ({ ...prev, suffix }));\n }\n };\n\n const onPaste: React.ClipboardEventHandler<HTMLInputElement> = (event) => {\n if (!event.nativeEvent.clipboardData) {\n return;\n }\n\n const pastedValue = (event.nativeEvent.clipboardData.getData('text/plain') || '').replace(\n /(\\s|-)+/g,\n '',\n );\n const pastedNumber = explodeNumberModel(pastedValue);\n\n if (\n pastedNumber.prefix != null &&\n countriesByPrefix.has(pastedNumber.prefix) &&\n ALLOWED_PHONE_CHARS.test(pastedNumber.suffix)\n ) {\n setInternalValue(pastedNumber);\n }\n };\n\n useEffect(() => {\n const internalPhoneNumber = `${internalValue.prefix ?? ''}${internalValue.suffix}`;\n const broadcastedPhoneNumber = `${broadcastedValueRef.current.prefix ?? ''}${broadcastedValueRef.current.suffix}`;\n\n if (internalPhoneNumber === broadcastedPhoneNumber) {\n return;\n }\n\n const newValue = isValidPhoneNumber(internalPhoneNumber)\n ? cleanNumber(internalPhoneNumber)\n : null;\n\n onChange(\n newValue,\n internalValue.prefix ?? '', // TODO: Allow `null` in public API\n );\n broadcastedValueRef.current = internalValue;\n }, [onChange, internalValue]);\n\n useEffect(() => {\n const labelRef = fieldLabelRef?.current;\n\n if (labelRef) {\n const handleLabelClick = () => {\n if (!selectProps.disabled) {\n countryCodeSelectRef.current?.click();\n } else {\n phoneNumberInputRef.current?.focus();\n }\n };\n\n labelRef.addEventListener('click', handleLabelClick);\n\n return () => {\n labelRef?.removeEventListener('click', handleLabelClick);\n };\n }\n }, [fieldLabelRef, selectProps.disabled]);\n\n return (\n <fieldset {...inputAttributes} aria-labelledby={ariaLabelledBy} className=\"tw-telephone\">\n <label className=\"sr-only\" id={ids.countryCode.label} htmlFor={ids.countryCode.select}>\n {formatMessage(messages.countryCodeLabel)}\n </label>\n <div\n className={`tw-telephone__country-select${\n hasInputGroupAddonStart\n ? ' tw-telephone__country-select--with-input-group-addon-start'\n : ''\n }`}\n >\n <SelectInput\n triggerRef={countryCodeSelectRef}\n placeholder={formatMessage(messages.selectInputPlaceholder)}\n items={[...countriesByPrefix].map(([prefix, countries]) => ({\n type: 'option',\n value: prefix,\n filterMatchers: [\n prefix,\n ...countries.map((country) => country.name),\n ...countries.map((country) => country.iso3),\n ],\n }))}\n value={internalValue.prefix}\n renderValue={(prefix, withinTrigger) => (\n <SelectInputOptionContent\n title={prefix}\n note={\n withinTrigger\n ? undefined\n : countriesByPrefix\n .get(prefix)\n ?.map((country) => country.iso3)\n .join(', ')\n }\n />\n )}\n filterable\n filterPlaceholder={searchPlaceholder}\n disabled={disabled}\n size={size}\n id={ids.countryCode.select}\n UNSAFE_triggerButtonProps={{\n id: ids.countryCode.select,\n 'aria-labelledby': ids.countryCode.label,\n 'aria-describedby': undefined,\n 'aria-invalid': undefined,\n }}\n onChange={(prefix) => {\n const country = prefix != null ? findCountryByPrefix(prefix) : null;\n setInternalValue((prev) => ({ ...prev, prefix, format: country?.phoneFormat }));\n }}\n onClose={() => {\n if (suffixDirty) {\n onBlur?.();\n }\n }}\n {...selectProps}\n />\n </div>\n <label className=\"sr-only\" id={ids.phoneNumber.label} htmlFor={ids.phoneNumber.input}>\n {formatMessage(messages.phoneNumberLabel)}\n </label>\n <div className=\"tw-telephone__number-input\">\n <div className={`input-group input-group-${size} ${disabled ? 'disabled' : ''}`}>\n <Input\n ref={phoneNumberInputRef}\n id={ids.phoneNumber.input}\n autoComplete=\"tel-national\"\n name=\"phoneNumber\"\n inputMode=\"numeric\"\n value={internalValue.suffix}\n disabled={disabled}\n required={required}\n placeholder={placeholder}\n aria-labelledby={ids.phoneNumber.label}\n onChange={onSuffixChange}\n onPaste={onPaste}\n onFocus={onFocus}\n onBlur={() => onBlur?.()}\n />\n </div>\n </div>\n </fieldset>\n );\n};\n\nexport default PhoneNumberInput;\n"],"names":["ALLOWED_PHONE_CHARS","defaultSelectProps","defaultDisabledCountries","PhoneNumberInput","id","ariaLabelledByProp","required","disabled","initialValue","onChange","onFocus","onBlur","countryCode","searchPlaceholder","size","Size","MEDIUM","placeholder","selectProps","disabledCountries","countryCodeSelectRef","useRef","phoneNumberInputRef","inputAttributes","useInputAttributes","nonLabelable","paddingInlineStart","useInputPaddings","hasInputGroupAddonStart","fieldLabelRef","useFieldLabelRef","ariaLabelledBy","locale","formatMessage","useIntl","randomId","useState","Math","random","toString","slice","createId","customID","backup","ids","label","select","phoneNumber","input","internalValue","setInternalValue","cleanValue","cleanNumber","isValidPhoneNumber","prefix","setDefaultPrefix","suffix","explodeNumberModel","broadcastedValueRef","suffixDirty","setSuffixDirty","useEffect","countriesByPrefix","useMemo","groupCountriesByPrefix","sortArrayByProperty","excludeCountries","countries","onSuffixChange","event","target","value","test","prev","onPaste","nativeEvent","clipboardData","pastedValue","getData","replace","pastedNumber","has","internalPhoneNumber","broadcastedPhoneNumber","current","newValue","labelRef","handleLabelClick","click","focus","addEventListener","removeEventListener","_jsxs","className","children","_jsx","htmlFor","messages","countryCodeLabel","SelectInput","triggerRef","selectInputPlaceholder","items","map","type","filterMatchers","country","name","iso3","renderValue","withinTrigger","SelectInputOptionContent","title","note","undefined","get","join","filterable","filterPlaceholder","UNSAFE_triggerButtonProps","findCountryByPrefix","format","phoneFormat","onClose","phoneNumberLabel","Input","ref","autoComplete","inputMode"],"mappings":"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"}
@@ -20,8 +20,40 @@ const PromoCardGroup = ({
20
20
  onChange = () => {},
21
21
  testId
22
22
  }) => {
23
- const [state, setState] = React.useState(defaultChecked);
24
- const [containerRole, setContainerRole] = React.useState(null);
23
+ const [promoCardState, setPromoCardState] = React.useState({
24
+ defaultChecked,
25
+ state: defaultChecked
26
+ });
27
+ React.useEffect(() => {
28
+ if (promoCardState.defaultChecked !== defaultChecked) {
29
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing defaultChecked prop to internal state
30
+ setPromoCardState({
31
+ defaultChecked,
32
+ state: defaultChecked
33
+ });
34
+ }
35
+ }, [defaultChecked, promoCardState.defaultChecked]);
36
+ const {
37
+ state
38
+ } = promoCardState;
39
+ const setState = newState => setPromoCardState(prev => ({
40
+ ...prev,
41
+ state: newState
42
+ }));
43
+ // Derive container role from children
44
+ const containerRole = React.useMemo(() => {
45
+ // Collect an array of types from the children PromoCard components
46
+ const types = React__default.default.Children.map(children, child => {
47
+ if (/*#__PURE__*/React__default.default.isValidElement(child) && child.props.type) {
48
+ return child.props.type;
49
+ }
50
+ return null;
51
+ })?.filter(type => type !== null && type !== undefined) ?? [];
52
+ // Check if all types are the same
53
+ const allTypesAreTheSame = types.every(type => type === types[0]);
54
+ // If all types are the same and the type is 'radio', return 'radiogroup'
55
+ return allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null;
56
+ }, [children]);
25
57
  /**
26
58
  * The context value for the PromoCardGroup.
27
59
  *
@@ -52,20 +84,6 @@ const PromoCardGroup = ({
52
84
  'data-testid': testId,
53
85
  role: containerRole // Add the role attribute here
54
86
  };
55
- React.useEffect(() => {
56
- setState(defaultChecked);
57
- // Collect an array of types from the children PromoCard components
58
- const types = React__default.default.Children.map(children, child => {
59
- if (/*#__PURE__*/React__default.default.isValidElement(child) && child.props.type) {
60
- return child.props.type;
61
- }
62
- return null;
63
- })?.filter(type => type !== null && type !== undefined) ?? [];
64
- // Check if all types are the same
65
- const allTypesAreTheSame = types.every(type => type === types[0]);
66
- // If all types are the same and the type is 'radio', set the container role
67
- setContainerRole(allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null);
68
- }, [defaultChecked, children]);
69
87
  return /*#__PURE__*/jsxRuntime.jsx(PromoCardContext.PromoCardContext.Provider, {
70
88
  value: contextValue,
71
89
  children: /*#__PURE__*/jsxRuntime.jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"PromoCardGroup.js","sources":["../../src/promoCard/PromoCardGroup.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { FunctionComponent, ReactNode, useState, useEffect, useMemo } from 'react';\n\nimport { PromoCardProps } from './PromoCard';\nimport PromoCardContext from './PromoCardContext';\n\nexport type AriaRoleRadioGroup = 'radiogroup';\n\nexport interface PromoCardGroupProps {\n /**\n * Optional class name(s) to add to the group container.\n */\n className?: string;\n /**\n * The PromoCard components to display inside the group.\n */\n children: ReactNode;\n /**\n * The default checked for the group.\n */\n defaultChecked?: string;\n /**\n * Optional ID to add to the group container.\n */\n id?: string;\n /**\n * Whether the group is disabled or not.\n */\n isDisabled?: boolean;\n /**\n * Optional label to display above the group.\n */\n label?: string;\n /**\n * Optional function to call when the group value changes.\n */\n onChange?: (value: string) => void;\n /**\n * Optional ID to add to the group container for testing purposes.\n */\n testId?: string;\n}\n\n/**\n * PromoCardGroup component.\n *\n * A PromoCardGroup is a container for PromoCard components that allows the user to select one or more\n * cards from a group. It can be used to display a set of related options, and can be customized with\n * various props to suit different use cases.\n *\n * @param {ReactNode} children - The PromoCard components to display inside the group.\n * @param {string} className - Optional class name(s) to add to the group container.\n * @param {string} defaultChecked - The default value for the group.\n * @param {string} id - Optional ID to add to the group container.\n * @param {boolean} isDisabled=false - Whether the group is disabled or not.\n * @param {string} label - Optional label to display above the group.\n * @param {Function} onChange - Optional function to call when the group value changes.\n * @param {string} testId - Optional ID to add to the group container for testing purposes.\n * @returns {React.JSX.Element} - The PromoCardGroup component.\n */\nconst PromoCardGroup: FunctionComponent<PromoCardGroupProps> = ({\n children,\n className,\n defaultChecked = '',\n id,\n isDisabled = false,\n onChange = () => {},\n testId,\n}) => {\n const [state, setState] = useState<string>(defaultChecked);\n const [containerRole, setContainerRole] = useState<string | null>(null);\n\n /**\n * The context value for the PromoCardGroup.\n *\n * The context value is an object that contains the current state of the\n * group, whether the group is disabled or not, and a function to call when\n * the group value changes. This value is used to provide context to child\n * PromoCard components, allowing them to interact with the group and update\n * its state.\n */\n const contextValue = useMemo(() => {\n const handleOnChange = (value: string) => {\n setState(value);\n onChange(value);\n };\n\n return { state, isDisabled, onChange: handleOnChange };\n }, [state, isDisabled, onChange]);\n\n const commonClasses = clsx(\n {\n 'np-CardGroup': true,\n 'is-disabled': isDisabled,\n },\n className,\n );\n\n const commonProps = {\n className: commonClasses,\n id,\n 'data-testid': testId,\n role: containerRole as AriaRoleRadioGroup | undefined, // Add the role attribute here\n };\n\n useEffect(() => {\n setState(defaultChecked);\n\n // Collect an array of types from the children PromoCard components\n const types =\n React.Children.map(children, (child) => {\n if (React.isValidElement<PromoCardProps>(child) && child.props.type) {\n return child.props.type;\n }\n return null;\n })?.filter((type): type is 'radio' | 'checkbox' => type !== null && type !== undefined) ?? [];\n\n // Check if all types are the same\n const allTypesAreTheSame = types.every((type) => type === types[0]);\n\n // If all types are the same and the type is 'radio', set the container role\n setContainerRole(allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null);\n }, [defaultChecked, children]);\n\n return (\n <PromoCardContext.Provider value={contextValue}>\n <div {...commonProps}>{children}</div>\n </PromoCardContext.Provider>\n );\n};\n\nexport default React.memo(PromoCardGroup);\n"],"names":["PromoCardGroup","children","className","defaultChecked","id","isDisabled","onChange","testId","state","setState","useState","containerRole","setContainerRole","contextValue","useMemo","handleOnChange","value","commonClasses","clsx","commonProps","role","useEffect","types","React","Children","map","child","isValidElement","props","type","filter","undefined","allTypesAreTheSame","every","_jsx","PromoCardContext","Provider","memo"],"mappings":";;;;;;;;;;;;;AA4DA,MAAMA,cAAc,GAA2CA,CAAC;EAC9DC,QAAQ;EACRC,SAAS;AACTC,EAAAA,cAAc,GAAG,EAAE;EACnBC,EAAE;AACFC,EAAAA,UAAU,GAAG,KAAK;AAClBC,EAAAA,QAAQ,GAAGA,MAAK,CAAE,CAAC;AACnBC,EAAAA;AAAM,CACP,KAAI;EACH,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGC,cAAQ,CAASP,cAAc,CAAC;EAC1D,MAAM,CAACQ,aAAa,EAAEC,gBAAgB,CAAC,GAAGF,cAAQ,CAAgB,IAAI,CAAC;AAEvE;;;;;;;;AAQG;AACH,EAAA,MAAMG,YAAY,GAAGC,aAAO,CAAC,MAAK;IAChC,MAAMC,cAAc,GAAIC,KAAa,IAAI;MACvCP,QAAQ,CAACO,KAAK,CAAC;MACfV,QAAQ,CAACU,KAAK,CAAC;IACjB,CAAC;IAED,OAAO;MAAER,KAAK;MAAEH,UAAU;AAAEC,MAAAA,QAAQ,EAAES;KAAgB;EACxD,CAAC,EAAE,CAACP,KAAK,EAAEH,UAAU,EAAEC,QAAQ,CAAC,CAAC;EAEjC,MAAMW,aAAa,GAAGC,SAAI,CACxB;AACE,IAAA,cAAc,EAAE,IAAI;AACpB,IAAA,aAAa,EAAEb;GAChB,EACDH,SAAS,CACV;AAED,EAAA,MAAMiB,WAAW,GAAG;AAClBjB,IAAAA,SAAS,EAAEe,aAAa;IACxBb,EAAE;AACF,IAAA,aAAa,EAAEG,MAAM;IACrBa,IAAI,EAAET,aAA+C;GACtD;AAEDU,EAAAA,eAAS,CAAC,MAAK;IACbZ,QAAQ,CAACN,cAAc,CAAC;AAExB;IACA,MAAMmB,KAAK,GACTC,sBAAK,CAACC,QAAQ,CAACC,GAAG,CAACxB,QAAQ,EAAGyB,KAAK,IAAI;AACrC,MAAA,iBAAIH,sBAAK,CAACI,cAAc,CAAiBD,KAAK,CAAC,IAAIA,KAAK,CAACE,KAAK,CAACC,IAAI,EAAE;AACnE,QAAA,OAAOH,KAAK,CAACE,KAAK,CAACC,IAAI;AACzB,MAAA;AACA,MAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC,EAAEC,MAAM,CAAED,IAAI,IAAmCA,IAAI,KAAK,IAAI,IAAIA,IAAI,KAAKE,SAAS,CAAC,IAAI,EAAE;AAE/F;AACA,IAAA,MAAMC,kBAAkB,GAAGV,KAAK,CAACW,KAAK,CAAEJ,IAAI,IAAKA,IAAI,KAAKP,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnE;AACAV,IAAAA,gBAAgB,CAACoB,kBAAkB,IAAIV,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,YAAY,GAAG,IAAI,CAAC;AACpF,EAAA,CAAC,EAAE,CAACnB,cAAc,EAAEF,QAAQ,CAAC,CAAC;AAE9B,EAAA,oBACEiC,cAAA,CAACC,iCAAgB,CAACC,QAAQ,EAAA;AAACpB,IAAAA,KAAK,EAAEH,YAAa;AAAAZ,IAAAA,QAAA,eAC7CiC,cAAA,CAAA,KAAA,EAAA;AAAA,MAAA,GAASf,WAAW;AAAAlB,MAAAA,QAAA,EAAGA;KAAc;AACvC,GAA2B,CAAC;AAEhC,CAAC;AAED,6BAAA,aAAesB,sBAAK,CAACc,IAAI,CAACrC,cAAc,CAAC;;;;"}
1
+ {"version":3,"file":"PromoCardGroup.js","sources":["../../src/promoCard/PromoCardGroup.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { FunctionComponent, ReactNode, useState, useEffect, useMemo } from 'react';\n\nimport { PromoCardProps } from './PromoCard';\nimport PromoCardContext from './PromoCardContext';\n\nexport type AriaRoleRadioGroup = 'radiogroup';\n\nexport interface PromoCardGroupProps {\n /**\n * Optional class name(s) to add to the group container.\n */\n className?: string;\n /**\n * The PromoCard components to display inside the group.\n */\n children: ReactNode;\n /**\n * The default checked for the group.\n */\n defaultChecked?: string;\n /**\n * Optional ID to add to the group container.\n */\n id?: string;\n /**\n * Whether the group is disabled or not.\n */\n isDisabled?: boolean;\n /**\n * Optional label to display above the group.\n */\n label?: string;\n /**\n * Optional function to call when the group value changes.\n */\n onChange?: (value: string) => void;\n /**\n * Optional ID to add to the group container for testing purposes.\n */\n testId?: string;\n}\n\n/**\n * PromoCardGroup component.\n *\n * A PromoCardGroup is a container for PromoCard components that allows the user to select one or more\n * cards from a group. It can be used to display a set of related options, and can be customized with\n * various props to suit different use cases.\n *\n * @param {ReactNode} children - The PromoCard components to display inside the group.\n * @param {string} className - Optional class name(s) to add to the group container.\n * @param {string} defaultChecked - The default value for the group.\n * @param {string} id - Optional ID to add to the group container.\n * @param {boolean} isDisabled=false - Whether the group is disabled or not.\n * @param {string} label - Optional label to display above the group.\n * @param {Function} onChange - Optional function to call when the group value changes.\n * @param {string} testId - Optional ID to add to the group container for testing purposes.\n * @returns {React.JSX.Element} - The PromoCardGroup component.\n */\nconst PromoCardGroup: FunctionComponent<PromoCardGroupProps> = ({\n children,\n className,\n defaultChecked = '',\n id,\n isDisabled = false,\n onChange = () => {},\n testId,\n}) => {\n const [promoCardState, setPromoCardState] = useState<{\n defaultChecked: string;\n state: string;\n }>({\n defaultChecked,\n state: defaultChecked,\n });\n\n useEffect(() => {\n if (promoCardState.defaultChecked !== defaultChecked) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing defaultChecked prop to internal state\n setPromoCardState({\n defaultChecked,\n state: defaultChecked,\n });\n }\n }, [defaultChecked, promoCardState.defaultChecked]);\n\n const { state } = promoCardState;\n const setState = (newState: string) =>\n setPromoCardState((prev) => ({ ...prev, state: newState }));\n\n // Derive container role from children\n const containerRole = useMemo(() => {\n // Collect an array of types from the children PromoCard components\n const types =\n React.Children.map(children, (child) => {\n if (React.isValidElement<PromoCardProps>(child) && child.props.type) {\n return child.props.type;\n }\n return null;\n })?.filter((type): type is 'radio' | 'checkbox' => type !== null && type !== undefined) ?? [];\n\n // Check if all types are the same\n const allTypesAreTheSame = types.every((type) => type === types[0]);\n\n // If all types are the same and the type is 'radio', return 'radiogroup'\n return allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null;\n }, [children]);\n\n /**\n * The context value for the PromoCardGroup.\n *\n * The context value is an object that contains the current state of the\n * group, whether the group is disabled or not, and a function to call when\n * the group value changes. This value is used to provide context to child\n * PromoCard components, allowing them to interact with the group and update\n * its state.\n */\n const contextValue = useMemo(() => {\n const handleOnChange = (value: string) => {\n setState(value);\n onChange(value);\n };\n\n return { state, isDisabled, onChange: handleOnChange };\n }, [state, isDisabled, onChange]);\n\n const commonClasses = clsx(\n {\n 'np-CardGroup': true,\n 'is-disabled': isDisabled,\n },\n className,\n );\n\n const commonProps = {\n className: commonClasses,\n id,\n 'data-testid': testId,\n role: containerRole as AriaRoleRadioGroup | undefined, // Add the role attribute here\n };\n\n return (\n <PromoCardContext.Provider value={contextValue}>\n <div {...commonProps}>{children}</div>\n </PromoCardContext.Provider>\n );\n};\n\nexport default React.memo(PromoCardGroup);\n"],"names":["PromoCardGroup","children","className","defaultChecked","id","isDisabled","onChange","testId","promoCardState","setPromoCardState","useState","state","useEffect","setState","newState","prev","containerRole","useMemo","types","React","Children","map","child","isValidElement","props","type","filter","undefined","allTypesAreTheSame","every","contextValue","handleOnChange","value","commonClasses","clsx","commonProps","role","_jsx","PromoCardContext","Provider","memo"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx';
2
- import React__default, { useState, useMemo, useEffect } from 'react';
2
+ import React__default, { useState, useEffect, useMemo } from 'react';
3
3
  import { PromoCardContext } from './PromoCardContext.mjs';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -12,8 +12,40 @@ const PromoCardGroup = ({
12
12
  onChange = () => {},
13
13
  testId
14
14
  }) => {
15
- const [state, setState] = useState(defaultChecked);
16
- const [containerRole, setContainerRole] = useState(null);
15
+ const [promoCardState, setPromoCardState] = useState({
16
+ defaultChecked,
17
+ state: defaultChecked
18
+ });
19
+ useEffect(() => {
20
+ if (promoCardState.defaultChecked !== defaultChecked) {
21
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing defaultChecked prop to internal state
22
+ setPromoCardState({
23
+ defaultChecked,
24
+ state: defaultChecked
25
+ });
26
+ }
27
+ }, [defaultChecked, promoCardState.defaultChecked]);
28
+ const {
29
+ state
30
+ } = promoCardState;
31
+ const setState = newState => setPromoCardState(prev => ({
32
+ ...prev,
33
+ state: newState
34
+ }));
35
+ // Derive container role from children
36
+ const containerRole = useMemo(() => {
37
+ // Collect an array of types from the children PromoCard components
38
+ const types = React__default.Children.map(children, child => {
39
+ if (/*#__PURE__*/React__default.isValidElement(child) && child.props.type) {
40
+ return child.props.type;
41
+ }
42
+ return null;
43
+ })?.filter(type => type !== null && type !== undefined) ?? [];
44
+ // Check if all types are the same
45
+ const allTypesAreTheSame = types.every(type => type === types[0]);
46
+ // If all types are the same and the type is 'radio', return 'radiogroup'
47
+ return allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null;
48
+ }, [children]);
17
49
  /**
18
50
  * The context value for the PromoCardGroup.
19
51
  *
@@ -44,20 +76,6 @@ const PromoCardGroup = ({
44
76
  'data-testid': testId,
45
77
  role: containerRole // Add the role attribute here
46
78
  };
47
- useEffect(() => {
48
- setState(defaultChecked);
49
- // Collect an array of types from the children PromoCard components
50
- const types = React__default.Children.map(children, child => {
51
- if (/*#__PURE__*/React__default.isValidElement(child) && child.props.type) {
52
- return child.props.type;
53
- }
54
- return null;
55
- })?.filter(type => type !== null && type !== undefined) ?? [];
56
- // Check if all types are the same
57
- const allTypesAreTheSame = types.every(type => type === types[0]);
58
- // If all types are the same and the type is 'radio', set the container role
59
- setContainerRole(allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null);
60
- }, [defaultChecked, children]);
61
79
  return /*#__PURE__*/jsx(PromoCardContext.Provider, {
62
80
  value: contextValue,
63
81
  children: /*#__PURE__*/jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"PromoCardGroup.mjs","sources":["../../src/promoCard/PromoCardGroup.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { FunctionComponent, ReactNode, useState, useEffect, useMemo } from 'react';\n\nimport { PromoCardProps } from './PromoCard';\nimport PromoCardContext from './PromoCardContext';\n\nexport type AriaRoleRadioGroup = 'radiogroup';\n\nexport interface PromoCardGroupProps {\n /**\n * Optional class name(s) to add to the group container.\n */\n className?: string;\n /**\n * The PromoCard components to display inside the group.\n */\n children: ReactNode;\n /**\n * The default checked for the group.\n */\n defaultChecked?: string;\n /**\n * Optional ID to add to the group container.\n */\n id?: string;\n /**\n * Whether the group is disabled or not.\n */\n isDisabled?: boolean;\n /**\n * Optional label to display above the group.\n */\n label?: string;\n /**\n * Optional function to call when the group value changes.\n */\n onChange?: (value: string) => void;\n /**\n * Optional ID to add to the group container for testing purposes.\n */\n testId?: string;\n}\n\n/**\n * PromoCardGroup component.\n *\n * A PromoCardGroup is a container for PromoCard components that allows the user to select one or more\n * cards from a group. It can be used to display a set of related options, and can be customized with\n * various props to suit different use cases.\n *\n * @param {ReactNode} children - The PromoCard components to display inside the group.\n * @param {string} className - Optional class name(s) to add to the group container.\n * @param {string} defaultChecked - The default value for the group.\n * @param {string} id - Optional ID to add to the group container.\n * @param {boolean} isDisabled=false - Whether the group is disabled or not.\n * @param {string} label - Optional label to display above the group.\n * @param {Function} onChange - Optional function to call when the group value changes.\n * @param {string} testId - Optional ID to add to the group container for testing purposes.\n * @returns {React.JSX.Element} - The PromoCardGroup component.\n */\nconst PromoCardGroup: FunctionComponent<PromoCardGroupProps> = ({\n children,\n className,\n defaultChecked = '',\n id,\n isDisabled = false,\n onChange = () => {},\n testId,\n}) => {\n const [state, setState] = useState<string>(defaultChecked);\n const [containerRole, setContainerRole] = useState<string | null>(null);\n\n /**\n * The context value for the PromoCardGroup.\n *\n * The context value is an object that contains the current state of the\n * group, whether the group is disabled or not, and a function to call when\n * the group value changes. This value is used to provide context to child\n * PromoCard components, allowing them to interact with the group and update\n * its state.\n */\n const contextValue = useMemo(() => {\n const handleOnChange = (value: string) => {\n setState(value);\n onChange(value);\n };\n\n return { state, isDisabled, onChange: handleOnChange };\n }, [state, isDisabled, onChange]);\n\n const commonClasses = clsx(\n {\n 'np-CardGroup': true,\n 'is-disabled': isDisabled,\n },\n className,\n );\n\n const commonProps = {\n className: commonClasses,\n id,\n 'data-testid': testId,\n role: containerRole as AriaRoleRadioGroup | undefined, // Add the role attribute here\n };\n\n useEffect(() => {\n setState(defaultChecked);\n\n // Collect an array of types from the children PromoCard components\n const types =\n React.Children.map(children, (child) => {\n if (React.isValidElement<PromoCardProps>(child) && child.props.type) {\n return child.props.type;\n }\n return null;\n })?.filter((type): type is 'radio' | 'checkbox' => type !== null && type !== undefined) ?? [];\n\n // Check if all types are the same\n const allTypesAreTheSame = types.every((type) => type === types[0]);\n\n // If all types are the same and the type is 'radio', set the container role\n setContainerRole(allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null);\n }, [defaultChecked, children]);\n\n return (\n <PromoCardContext.Provider value={contextValue}>\n <div {...commonProps}>{children}</div>\n </PromoCardContext.Provider>\n );\n};\n\nexport default React.memo(PromoCardGroup);\n"],"names":["PromoCardGroup","children","className","defaultChecked","id","isDisabled","onChange","testId","state","setState","useState","containerRole","setContainerRole","contextValue","useMemo","handleOnChange","value","commonClasses","clsx","commonProps","role","useEffect","types","React","Children","map","child","isValidElement","props","type","filter","undefined","allTypesAreTheSame","every","_jsx","PromoCardContext","Provider","memo"],"mappings":";;;;;AA4DA,MAAMA,cAAc,GAA2CA,CAAC;EAC9DC,QAAQ;EACRC,SAAS;AACTC,EAAAA,cAAc,GAAG,EAAE;EACnBC,EAAE;AACFC,EAAAA,UAAU,GAAG,KAAK;AAClBC,EAAAA,QAAQ,GAAGA,MAAK,CAAE,CAAC;AACnBC,EAAAA;AAAM,CACP,KAAI;EACH,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGC,QAAQ,CAASP,cAAc,CAAC;EAC1D,MAAM,CAACQ,aAAa,EAAEC,gBAAgB,CAAC,GAAGF,QAAQ,CAAgB,IAAI,CAAC;AAEvE;;;;;;;;AAQG;AACH,EAAA,MAAMG,YAAY,GAAGC,OAAO,CAAC,MAAK;IAChC,MAAMC,cAAc,GAAIC,KAAa,IAAI;MACvCP,QAAQ,CAACO,KAAK,CAAC;MACfV,QAAQ,CAACU,KAAK,CAAC;IACjB,CAAC;IAED,OAAO;MAAER,KAAK;MAAEH,UAAU;AAAEC,MAAAA,QAAQ,EAAES;KAAgB;EACxD,CAAC,EAAE,CAACP,KAAK,EAAEH,UAAU,EAAEC,QAAQ,CAAC,CAAC;EAEjC,MAAMW,aAAa,GAAGC,IAAI,CACxB;AACE,IAAA,cAAc,EAAE,IAAI;AACpB,IAAA,aAAa,EAAEb;GAChB,EACDH,SAAS,CACV;AAED,EAAA,MAAMiB,WAAW,GAAG;AAClBjB,IAAAA,SAAS,EAAEe,aAAa;IACxBb,EAAE;AACF,IAAA,aAAa,EAAEG,MAAM;IACrBa,IAAI,EAAET,aAA+C;GACtD;AAEDU,EAAAA,SAAS,CAAC,MAAK;IACbZ,QAAQ,CAACN,cAAc,CAAC;AAExB;IACA,MAAMmB,KAAK,GACTC,cAAK,CAACC,QAAQ,CAACC,GAAG,CAACxB,QAAQ,EAAGyB,KAAK,IAAI;AACrC,MAAA,iBAAIH,cAAK,CAACI,cAAc,CAAiBD,KAAK,CAAC,IAAIA,KAAK,CAACE,KAAK,CAACC,IAAI,EAAE;AACnE,QAAA,OAAOH,KAAK,CAACE,KAAK,CAACC,IAAI;AACzB,MAAA;AACA,MAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC,EAAEC,MAAM,CAAED,IAAI,IAAmCA,IAAI,KAAK,IAAI,IAAIA,IAAI,KAAKE,SAAS,CAAC,IAAI,EAAE;AAE/F;AACA,IAAA,MAAMC,kBAAkB,GAAGV,KAAK,CAACW,KAAK,CAAEJ,IAAI,IAAKA,IAAI,KAAKP,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnE;AACAV,IAAAA,gBAAgB,CAACoB,kBAAkB,IAAIV,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,YAAY,GAAG,IAAI,CAAC;AACpF,EAAA,CAAC,EAAE,CAACnB,cAAc,EAAEF,QAAQ,CAAC,CAAC;AAE9B,EAAA,oBACEiC,GAAA,CAACC,gBAAgB,CAACC,QAAQ,EAAA;AAACpB,IAAAA,KAAK,EAAEH,YAAa;AAAAZ,IAAAA,QAAA,eAC7CiC,GAAA,CAAA,KAAA,EAAA;AAAA,MAAA,GAASf,WAAW;AAAAlB,MAAAA,QAAA,EAAGA;KAAc;AACvC,GAA2B,CAAC;AAEhC,CAAC;AAED,6BAAA,aAAesB,cAAK,CAACc,IAAI,CAACrC,cAAc,CAAC;;;;"}
1
+ {"version":3,"file":"PromoCardGroup.mjs","sources":["../../src/promoCard/PromoCardGroup.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { FunctionComponent, ReactNode, useState, useEffect, useMemo } from 'react';\n\nimport { PromoCardProps } from './PromoCard';\nimport PromoCardContext from './PromoCardContext';\n\nexport type AriaRoleRadioGroup = 'radiogroup';\n\nexport interface PromoCardGroupProps {\n /**\n * Optional class name(s) to add to the group container.\n */\n className?: string;\n /**\n * The PromoCard components to display inside the group.\n */\n children: ReactNode;\n /**\n * The default checked for the group.\n */\n defaultChecked?: string;\n /**\n * Optional ID to add to the group container.\n */\n id?: string;\n /**\n * Whether the group is disabled or not.\n */\n isDisabled?: boolean;\n /**\n * Optional label to display above the group.\n */\n label?: string;\n /**\n * Optional function to call when the group value changes.\n */\n onChange?: (value: string) => void;\n /**\n * Optional ID to add to the group container for testing purposes.\n */\n testId?: string;\n}\n\n/**\n * PromoCardGroup component.\n *\n * A PromoCardGroup is a container for PromoCard components that allows the user to select one or more\n * cards from a group. It can be used to display a set of related options, and can be customized with\n * various props to suit different use cases.\n *\n * @param {ReactNode} children - The PromoCard components to display inside the group.\n * @param {string} className - Optional class name(s) to add to the group container.\n * @param {string} defaultChecked - The default value for the group.\n * @param {string} id - Optional ID to add to the group container.\n * @param {boolean} isDisabled=false - Whether the group is disabled or not.\n * @param {string} label - Optional label to display above the group.\n * @param {Function} onChange - Optional function to call when the group value changes.\n * @param {string} testId - Optional ID to add to the group container for testing purposes.\n * @returns {React.JSX.Element} - The PromoCardGroup component.\n */\nconst PromoCardGroup: FunctionComponent<PromoCardGroupProps> = ({\n children,\n className,\n defaultChecked = '',\n id,\n isDisabled = false,\n onChange = () => {},\n testId,\n}) => {\n const [promoCardState, setPromoCardState] = useState<{\n defaultChecked: string;\n state: string;\n }>({\n defaultChecked,\n state: defaultChecked,\n });\n\n useEffect(() => {\n if (promoCardState.defaultChecked !== defaultChecked) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing defaultChecked prop to internal state\n setPromoCardState({\n defaultChecked,\n state: defaultChecked,\n });\n }\n }, [defaultChecked, promoCardState.defaultChecked]);\n\n const { state } = promoCardState;\n const setState = (newState: string) =>\n setPromoCardState((prev) => ({ ...prev, state: newState }));\n\n // Derive container role from children\n const containerRole = useMemo(() => {\n // Collect an array of types from the children PromoCard components\n const types =\n React.Children.map(children, (child) => {\n if (React.isValidElement<PromoCardProps>(child) && child.props.type) {\n return child.props.type;\n }\n return null;\n })?.filter((type): type is 'radio' | 'checkbox' => type !== null && type !== undefined) ?? [];\n\n // Check if all types are the same\n const allTypesAreTheSame = types.every((type) => type === types[0]);\n\n // If all types are the same and the type is 'radio', return 'radiogroup'\n return allTypesAreTheSame && types[0] === 'radio' ? 'radiogroup' : null;\n }, [children]);\n\n /**\n * The context value for the PromoCardGroup.\n *\n * The context value is an object that contains the current state of the\n * group, whether the group is disabled or not, and a function to call when\n * the group value changes. This value is used to provide context to child\n * PromoCard components, allowing them to interact with the group and update\n * its state.\n */\n const contextValue = useMemo(() => {\n const handleOnChange = (value: string) => {\n setState(value);\n onChange(value);\n };\n\n return { state, isDisabled, onChange: handleOnChange };\n }, [state, isDisabled, onChange]);\n\n const commonClasses = clsx(\n {\n 'np-CardGroup': true,\n 'is-disabled': isDisabled,\n },\n className,\n );\n\n const commonProps = {\n className: commonClasses,\n id,\n 'data-testid': testId,\n role: containerRole as AriaRoleRadioGroup | undefined, // Add the role attribute here\n };\n\n return (\n <PromoCardContext.Provider value={contextValue}>\n <div {...commonProps}>{children}</div>\n </PromoCardContext.Provider>\n );\n};\n\nexport default React.memo(PromoCardGroup);\n"],"names":["PromoCardGroup","children","className","defaultChecked","id","isDisabled","onChange","testId","promoCardState","setPromoCardState","useState","state","useEffect","setState","newState","prev","containerRole","useMemo","types","React","Children","map","child","isValidElement","props","type","filter","undefined","allTypesAreTheSame","every","contextValue","handleOnChange","value","commonClasses","clsx","commonProps","role","_jsx","PromoCardContext","Provider","memo"],"mappings":"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"}
@@ -37,6 +37,7 @@ const SegmentedControl = ({
37
37
  segments,
38
38
  onChange
39
39
  }) => {
40
+ const isMountedRef = React.useRef(false);
40
41
  const [animate, setAnimate] = React.useState(false);
41
42
  const segmentsRef = React.useRef(null);
42
43
  if (segments.length > 3) {
@@ -60,7 +61,11 @@ const SegmentedControl = ({
60
61
  }
61
62
  };
62
63
  React.useEffect(() => {
63
- setAnimate(true);
64
+ if (isMountedRef.current) {
65
+ setAnimate(true);
66
+ } else {
67
+ isMountedRef.current = true;
68
+ }
64
69
  updateSegmentPosition();
65
70
  const handleWindowSizeChange = () => {
66
71
  setAnimate(false);
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.js","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":"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"}
1
+ {"version":3,"file":"SegmentedControl.js","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 isMountedRef = useRef(false);\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 if (isMountedRef.current) {\n setAnimate(true);\n } else {\n isMountedRef.current = true;\n }\n\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","isMountedRef","useRef","animate","setAnimate","useState","segmentsRef","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":"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"}
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx';
2
- import { useState, useRef, createRef, useEffect } from 'react';
2
+ import { useRef, useState, createRef, useEffect } from 'react';
3
3
  import Body from '../body/Body.mjs';
4
4
  import '../common/theme.mjs';
5
5
  import '../common/direction.mjs';
@@ -33,6 +33,7 @@ const SegmentedControl = ({
33
33
  segments,
34
34
  onChange
35
35
  }) => {
36
+ const isMountedRef = useRef(false);
36
37
  const [animate, setAnimate] = useState(false);
37
38
  const segmentsRef = useRef(null);
38
39
  if (segments.length > 3) {
@@ -56,7 +57,11 @@ const SegmentedControl = ({
56
57
  }
57
58
  };
58
59
  useEffect(() => {
59
- setAnimate(true);
60
+ if (isMountedRef.current) {
61
+ setAnimate(true);
62
+ } else {
63
+ isMountedRef.current = true;
64
+ }
60
65
  updateSegmentPosition();
61
66
  const handleWindowSizeChange = () => {
62
67
  setAnimate(false);
@@ -1 +1 @@
1
- {"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":"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"}
1
+ {"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 isMountedRef = useRef(false);\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 if (isMountedRef.current) {\n setAnimate(true);\n } else {\n isMountedRef.current = true;\n }\n\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","isMountedRef","useRef","animate","setAnimate","useState","segmentsRef","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":"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"}
@@ -8,16 +8,6 @@
8
8
  --coins-image: url("data:image/png;base64,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");
9
9
  }
10
10
  .tw-loader {
11
- display: flex;
12
- flex-direction: column;
13
- align-items: center;
14
- gap: 16px;
15
- gap: var(--size-16);
16
- width: 190px;
17
- text-align: center;
18
- word-break: break-word;
19
- }
20
- .tw-loader-asset {
21
11
  overflow: hidden;
22
12
  border-radius: 50%;
23
13
  backface-visibility: hidden;
@@ -33,10 +23,10 @@
33
23
  opacity: 0;
34
24
  transition: opacity 300ms cubic-bezier(0.24, 0, 0.3, 1);
35
25
  }
36
- .tw-loader-asset--visible {
26
+ .tw-loader--visible {
37
27
  opacity: 1;
38
28
  }
39
- .tw-loader-asset::before {
29
+ .tw-loader::before {
40
30
  content: "";
41
31
  display: block;
42
32
  width: 4.5rem;
@@ -55,14 +45,14 @@
55
45
  animation-delay: 0s;
56
46
  animation-iteration-count: infinite;
57
47
  }
58
- .tw-loader-asset--sm {
48
+ .tw-loader--sm {
59
49
  --coin-size: 3rem;
60
50
  --coin-edge-width-offset: translateX(0.275rem);
61
51
  --coin-edge-width-negative-offset: translateX(-0.275rem);
62
52
  --box-shadow-forwards: 0.025rem 0 0 var(--coin-colour), 0.05rem 0 0 var(--coin-colour), 0.075rem 0 0 var(--coin-colour), 0.1rem 0 0 var(--coin-colour), 0.125rem 0 0 var(--coin-colour), 0.15rem 0 0 var(--coin-colour), 0.175rem 0 0 var(--coin-colour), 0.2rem 0 0 var(--coin-colour), 0.225rem 0 0 var(--coin-colour), 0.25rem 0 0 var(--coin-colour), 0.275rem 0 0 var(--coin-colour), 0.3rem 0 0 var(--coin-colour), 0.325rem 0 0 var(--coin-colour), 0.35rem 0 0 var(--coin-colour), 0.375rem 0 0 var(--coin-colour), 0.4rem 0 0 var(--coin-colour), 0.425rem 0 0 var(--coin-colour), 0.45rem 0 0 var(--coin-colour), 0.475rem 0 0 var(--coin-colour);
63
53
  --box-shadow-backwards: -0.025rem 0 0 var(--coin-colour), -0.05rem 0 0 var(--coin-colour), -0.075rem 0 0 var(--coin-colour), -0.1rem 0 0 var(--coin-colour), -0.125rem 0 0 var(--coin-colour), -0.15rem 0 0 var(--coin-colour), -0.175rem 0 0 var(--coin-colour), -0.2rem 0 0 var(--coin-colour), -0.225rem 0 0 var(--coin-colour), -0.25rem 0 0 var(--coin-colour), -0.275rem 0 0 var(--coin-colour), -0.3rem 0 0 var(--coin-colour), -0.325rem 0 0 var(--coin-colour), -0.35rem 0 0 var(--coin-colour), -0.375rem 0 0 var(--coin-colour), -0.4rem 0 0 var(--coin-colour), -0.425rem 0 0 var(--coin-colour), -0.45rem 0 0 var(--coin-colour), -0.475rem 0 0 var(--coin-colour);
64
54
  }
65
- .tw-loader-asset--md {
55
+ .tw-loader--md {
66
56
  --coin-size: 4.5rem;
67
57
  --coin-edge-width-offset: translateX(0.375rem);
68
58
  --coin-edge-width-negative-offset: translateX(-0.375rem);