@flipdish/portal-library 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/components/atoms/Badge/index.cjs.js +1 -1
  2. package/dist/components/atoms/Badge/index.cjs.js.map +1 -1
  3. package/dist/components/atoms/Badge/index.d.ts +8 -6
  4. package/dist/components/atoms/Badge/index.js +1 -1
  5. package/dist/components/atoms/Badge/index.js.map +1 -1
  6. package/dist/components/atoms/Card/index.cjs.js +1 -1
  7. package/dist/components/atoms/Card/index.cjs.js.map +1 -1
  8. package/dist/components/atoms/Card/index.js +1 -1
  9. package/dist/components/atoms/Card/index.js.map +1 -1
  10. package/dist/components/atoms/Checkbox/index.cjs.js +1 -1
  11. package/dist/components/atoms/Checkbox/index.cjs.js.map +1 -1
  12. package/dist/components/atoms/Checkbox/index.d.ts +1 -1
  13. package/dist/components/atoms/Checkbox/index.js +1 -1
  14. package/dist/components/atoms/Checkbox/index.js.map +1 -1
  15. package/dist/components/atoms/MenuItem/index.cjs.js +1 -1
  16. package/dist/components/atoms/MenuItem/index.cjs.js.map +1 -1
  17. package/dist/components/atoms/MenuItem/index.js +1 -1
  18. package/dist/components/atoms/MenuItem/index.js.map +1 -1
  19. package/dist/components/atoms/Select/index.cjs.js +1 -1
  20. package/dist/components/atoms/Select/index.cjs.js.map +1 -1
  21. package/dist/components/atoms/Select/index.js +1 -1
  22. package/dist/components/atoms/Select/index.js.map +1 -1
  23. package/dist/components/atoms/TextField/index.cjs.js +1 -1
  24. package/dist/components/atoms/TextField/index.cjs.js.map +1 -1
  25. package/dist/components/atoms/TextField/index.js +1 -1
  26. package/dist/components/atoms/TextField/index.js.map +1 -1
  27. package/dist/components/molecules/Autocomplete/hooks/useDynamicLimitTags.cjs.js +2 -0
  28. package/dist/components/molecules/Autocomplete/hooks/useDynamicLimitTags.cjs.js.map +1 -0
  29. package/dist/components/molecules/Autocomplete/hooks/useDynamicLimitTags.d.ts +14 -0
  30. package/dist/components/molecules/Autocomplete/hooks/useDynamicLimitTags.js +2 -0
  31. package/dist/components/molecules/Autocomplete/hooks/useDynamicLimitTags.js.map +1 -0
  32. package/dist/components/molecules/Autocomplete/index.cjs.js +1 -1
  33. package/dist/components/molecules/Autocomplete/index.cjs.js.map +1 -1
  34. package/dist/components/molecules/Autocomplete/index.d.ts +55 -2
  35. package/dist/components/molecules/Autocomplete/index.js +1 -1
  36. package/dist/components/molecules/Autocomplete/index.js.map +1 -1
  37. package/dist/components/molecules/CheckboxGroup/index.cjs.js +1 -1
  38. package/dist/components/molecules/CheckboxGroup/index.cjs.js.map +1 -1
  39. package/dist/components/molecules/CheckboxGroup/index.d.ts +1 -1
  40. package/dist/components/molecules/CheckboxGroup/index.js +1 -1
  41. package/dist/components/molecules/CheckboxGroup/index.js.map +1 -1
  42. package/dist/themes/flipdishPublicTheme.cjs.js +1 -1
  43. package/dist/themes/flipdishPublicTheme.cjs.js.map +1 -1
  44. package/dist/themes/flipdishPublicTheme.js +1 -1
  45. package/dist/themes/flipdishPublicTheme.js.map +1 -1
  46. package/dist/themes/overrides/autocompleteOverrides.cjs.js +2 -0
  47. package/dist/themes/overrides/autocompleteOverrides.cjs.js.map +1 -0
  48. package/dist/themes/overrides/autocompleteOverrides.d.ts +5 -0
  49. package/dist/themes/overrides/autocompleteOverrides.js +2 -0
  50. package/dist/themes/overrides/autocompleteOverrides.js.map +1 -0
  51. package/dist/themes/overrides/inputBaseOverrides.cjs.js +1 -1
  52. package/dist/themes/overrides/inputBaseOverrides.cjs.js.map +1 -1
  53. package/dist/themes/overrides/inputBaseOverrides.js +1 -1
  54. package/dist/themes/overrides/inputBaseOverrides.js.map +1 -1
  55. package/dist/themes/overrides/menuItemOverrides.cjs.js +1 -1
  56. package/dist/themes/overrides/menuItemOverrides.cjs.js.map +1 -1
  57. package/dist/themes/overrides/menuItemOverrides.js +1 -1
  58. package/dist/themes/overrides/menuItemOverrides.js.map +1 -1
  59. package/dist/themes/overrides/menuOverrides.cjs.js +1 -1
  60. package/dist/themes/overrides/menuOverrides.cjs.js.map +1 -1
  61. package/dist/themes/overrides/menuOverrides.js +1 -1
  62. package/dist/themes/overrides/menuOverrides.js.map +1 -1
  63. package/dist/themes/overrides/selectOverrides.cjs.js +1 -1
  64. package/dist/themes/overrides/selectOverrides.cjs.js.map +1 -1
  65. package/dist/themes/overrides/selectOverrides.js +1 -1
  66. package/dist/themes/overrides/selectOverrides.js.map +1 -1
  67. package/dist/utilities/stringUtilities.cjs.js +2 -0
  68. package/dist/utilities/stringUtilities.cjs.js.map +1 -0
  69. package/dist/utilities/stringUtilities.d.ts +7 -0
  70. package/dist/utilities/stringUtilities.js +2 -0
  71. package/dist/utilities/stringUtilities.js.map +1 -0
  72. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/MenuItem/index.tsx"],"sourcesContent":["import Box from '@mui/material/Box';\nimport ListItemText from '@mui/material/ListItemText';\nimport MuiMenuItem, { type MenuItemProps as MuiMenuItemProps } from '@mui/material/MenuItem';\nimport { styled } from '@mui/material/styles';\n\nimport Checkbox from '../Checkbox';\n\ntype BaseProps = Omit<MuiMenuItemProps, 'children'> & {\n children?: React.ReactNode;\n label?: React.ReactNode;\n secondaryText?: React.ReactNode;\n type?: 'avatar' | 'checkbox' | 'icon' | 'text';\n};\n\ntype AvatarMenuItemProps = BaseProps & {\n avatar: React.ReactNode;\n checkbox?: never;\n icon?: never;\n type: 'avatar';\n};\n\ntype CheckboxMenuItemProps = BaseProps & {\n avatar?: never;\n checked?: boolean;\n icon?: never;\n onCheckedChange?: (\n checked: boolean,\n e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLLIElement>,\n ) => void;\n type: 'checkbox';\n};\n\ntype IconMenuItemProps = BaseProps & {\n avatar?: never;\n checkbox?: never;\n icon: React.ReactNode;\n type: 'icon';\n};\n\ntype TextMenuItemProps = BaseProps & {\n avatar?: never;\n checkbox?: never;\n icon?: never;\n type?: 'text';\n};\n\nexport type MenuItemProps =\n | AvatarMenuItemProps\n | CheckboxMenuItemProps\n | IconMenuItemProps\n | TextMenuItemProps;\n\nconst StyledStartAdornment = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n alignItems: 'center',\n display: 'inline-flex',\n justifyContent: 'center',\n\n '& .MuiAvatar-img': {\n opacity: disabled ? theme.palette.action.disabledOpacity : 1,\n },\n}));\n\nconst StyledCheckbox = styled(Checkbox)(() => ({\n padding: 0,\n margin: 0,\n}));\n\nexport const MenuItem = ({\n children,\n disabled = false,\n label,\n secondaryText,\n type = 'text',\n ...props\n}: MenuItemProps): JSX.Element => {\n // Remove type-specific props from props object to avoid passing them to MuiMenuItem\n const muiProps: MuiMenuItemProps = ((): MuiMenuItemProps => {\n switch (type) {\n case 'checkbox': {\n const { checked: _c, onCheckedChange: _h, ...rest } = props as CheckboxMenuItemProps;\n return rest as MuiMenuItemProps;\n }\n case 'avatar': {\n const { avatar: _a, ...rest } = props as AvatarMenuItemProps;\n return rest as MuiMenuItemProps;\n }\n case 'icon': {\n const { icon: _i, ...rest } = props as IconMenuItemProps;\n return rest as MuiMenuItemProps;\n }\n default:\n return props as MuiMenuItemProps;\n }\n })();\n\n const handleClick = (event: React.MouseEvent<HTMLLIElement>): void => {\n if (disabled) {\n return;\n }\n\n // If menu item is a checkbox, clicking the menu item will toggle the checkbox\n if (type === 'checkbox') {\n event.preventDefault();\n event.stopPropagation();\n\n const { checked, onCheckedChange } = props as CheckboxMenuItemProps;\n const isChecked =\n typeof checked === 'boolean' ? checked : Boolean((props as MuiMenuItemProps).selected);\n\n onCheckedChange?.(!isChecked, event);\n return;\n }\n\n muiProps?.onClick?.(event);\n };\n\n const renderAvatar = (): React.ReactNode => {\n const { avatar } = props as AvatarMenuItemProps;\n return <StyledStartAdornment disabled={disabled}>{avatar}</StyledStartAdornment>;\n };\n\n const renderCheckbox = (): React.ReactNode => {\n const { checked, onCheckedChange } = props as CheckboxMenuItemProps;\n\n const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>): void => {\n event.stopPropagation();\n onCheckedChange?.(event.target.checked, event);\n };\n\n const isChecked = typeof checked === 'boolean' ? checked : Boolean((props as MuiMenuItemProps).selected);\n\n return (\n <StyledStartAdornment>\n <StyledCheckbox\n checked={isChecked}\n disabled={disabled}\n fdKey='checkbox-menu-item'\n label='Checkbox'\n onChange={handleCheckboxChange}\n size=\"small\"\n tabIndex={-1}\n />\n </StyledStartAdornment>\n );\n };\n\n const renderIcon = (): React.ReactNode => {\n const { icon } = props as IconMenuItemProps;\n return <StyledStartAdornment>{icon}</StyledStartAdornment>;\n };\n\n const renderStartAdornment = (): React.ReactNode => {\n switch (type) {\n case 'avatar':\n return renderAvatar();\n case 'checkbox':\n return renderCheckbox();\n case 'icon':\n return renderIcon();\n default:\n return null;\n }\n };\n\n const renderText = (): React.ReactNode => {\n if (label || secondaryText) {\n return <ListItemText primary={label} secondary={secondaryText} />;\n }\n\n return children;\n };\n\n const a11yProps =\n type === 'checkbox'\n ? ({\n role: 'menuitemcheckbox',\n 'aria-checked': (props as CheckboxMenuItemProps).checked,\n } as const)\n : undefined;\n\n return (\n <MuiMenuItem {...muiProps} disabled={disabled} onClick={handleClick} {...a11yProps}>\n {renderStartAdornment()}\n {renderText()}\n </MuiMenuItem>\n );\n};\n\nexport default MenuItem;\n"],"names":["StyledStartAdornment","styled","Box","shouldForwardProp","prop","theme","disabled","alignItems","display","justifyContent","opacity","palette","action","disabledOpacity","StyledCheckbox","Checkbox","padding","margin","MenuItem","children","label","secondaryText","type","props","muiProps","checked","_c","onCheckedChange","_h","rest","avatar","_a","icon","_i","a11yProps","role","undefined","_jsxs","MuiMenuItem","onClick","event","preventDefault","stopPropagation","isChecked","Boolean","selected","_jsx","renderAvatar","fdKey","onChange","target","size","tabIndex","renderCheckbox","renderIcon","renderStartAdornment","ListItemText","primary","secondary"],"mappings":"qPAoDA,MAAMA,EAAuBC,EAAOC,EAAK,CACvCC,kBAAoBC,GAAkB,aAATA,GADFH,EAEF,EAAGI,QAAOC,YAAW,MAAO,CACrDC,WAAY,SACZC,QAAS,cACTC,eAAgB,SAEhB,mBAAoB,CAClBC,QAASJ,EAAWD,EAAMM,QAAQC,OAAOC,gBAAkB,OAIzDC,EAAiBb,EAAOc,EAAPd,EAAiB,KAAA,CACtCe,QAAS,EACTC,OAAQ,MAGGC,EAAW,EACtBC,WACAb,YAAW,EACXc,QACAC,gBACAC,OAAO,UACJC,MAGH,MAAMC,EAA6B,MACjC,OAAQF,GACN,IAAK,WAAY,CACf,MAAQG,QAASC,EAAIC,gBAAiBC,KAAOC,GAASN,EACtD,OAAOM,CACT,CACA,IAAK,SAAU,CACb,MAAQC,OAAQC,KAAOF,GAASN,EAChC,OAAOM,CACT,CACA,IAAK,OAAQ,CACX,MAAQG,KAAMC,KAAOJ,GAASN,EAC9B,OAAOM,CACT,CACA,QACE,OAAON,EAEZ,EAjBkC,GAgG7BW,EACK,aAATZ,EACK,CACCa,KAAM,mBACN,eAAiBZ,EAAgCE,cAEnDW,EAEN,OACEC,EAACC,EAAW,IAAKd,EAAUlB,SAAUA,EAAUiC,QAtF5BC,IACnB,IAAIlC,EAKJ,GAAa,aAATgB,EAYJE,GAAUe,UAAUC,OAZpB,CACEA,EAAMC,iBACND,EAAME,kBAEN,MAAMjB,QAAEA,EAAOE,gBAAEA,GAAoBJ,EAC/BoB,EACe,kBAAZlB,EAAwBA,EAAUmB,QAASrB,EAA2BsB,UAE/ElB,KAAmBgB,EAAWH,EAEhC,MAsEyEN,EAASf,SAAA,CA9BvD,MAC3B,OAAQG,GACN,IAAK,SACH,MAtCe,MACnB,MAAMQ,OAAEA,GAAWP,EACnB,OAAOuB,EAAC9C,EAAoB,CAACM,SAAUA,EAAQa,SAAGW,KAoCvCiB,GACT,IAAK,WACH,MAnCiB,MACrB,MAAMtB,QAAEA,EAAOE,gBAAEA,GAAoBJ,EAO/BoB,EAA+B,kBAAZlB,EAAwBA,EAAUmB,QAASrB,EAA2BsB,UAE/F,OACEC,EAAC9C,EAAoB,CAAAmB,SACnB2B,EAAChC,EAAc,CACbW,QAASkB,EACTrC,SAAUA,EACV0C,MAAM,qBACN5B,MAAM,WACN6B,SAdwBT,IAC5BA,EAAME,kBACNf,IAAkBa,EAAMU,OAAOzB,QAASe,IAapCW,KAAK,QACLC,iBAgBKC,GACT,IAAK,OACH,MAZa,MACjB,MAAMrB,KAAEA,GAAST,EACjB,OAAOuB,EAAC9C,EAAoB,CAAAmB,SAAEa,KAUnBsB,GACT,QACE,OAAO,OAsBRC,GAjBCnC,GAASC,EACJyB,EAACU,EAAY,CAACC,QAASrC,EAAOsC,UAAWrC,IAG3CF"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/MenuItem/index.tsx"],"sourcesContent":["import Box from '@mui/material/Box';\nimport ListItemText from '@mui/material/ListItemText';\nimport MuiMenuItem, { type MenuItemProps as MuiMenuItemProps } from '@mui/material/MenuItem';\nimport { styled } from '@mui/material/styles';\n\nimport Checkbox from '../Checkbox';\n\ntype BaseProps = Omit<MuiMenuItemProps, 'children'> & {\n children?: React.ReactNode;\n label?: React.ReactNode;\n secondaryText?: React.ReactNode;\n type?: 'avatar' | 'checkbox' | 'icon' | 'text';\n};\n\ntype AvatarMenuItemProps = BaseProps & {\n avatar: React.ReactNode;\n checkbox?: never;\n icon?: never;\n type: 'avatar';\n};\n\ntype CheckboxMenuItemProps = BaseProps & {\n avatar?: never;\n checked?: boolean;\n icon?: never;\n onCheckedChange?: (\n checked: boolean,\n e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLLIElement>,\n ) => void;\n type: 'checkbox';\n};\n\ntype IconMenuItemProps = BaseProps & {\n avatar?: never;\n checkbox?: never;\n icon: React.ReactNode;\n type: 'icon';\n};\n\ntype TextMenuItemProps = BaseProps & {\n avatar?: never;\n checkbox?: never;\n icon?: never;\n type?: 'text';\n};\n\nexport type MenuItemProps =\n | AvatarMenuItemProps\n | CheckboxMenuItemProps\n | IconMenuItemProps\n | TextMenuItemProps;\n\nconst StyledStartAdornment = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n alignItems: 'center',\n display: 'inline-flex',\n justifyContent: 'center',\n\n '& .MuiAvatar-img': {\n opacity: disabled ? theme.palette.action.disabledOpacity : 1,\n },\n}));\n\nconst StyledCheckbox = styled(Checkbox)(() => ({\n pointerEvents: 'none',\n}));\n\nexport const MenuItem = ({\n children,\n disabled = false,\n label,\n secondaryText,\n type = 'text',\n ...props\n}: MenuItemProps): JSX.Element => {\n // Remove type-specific props from props object to avoid passing them to MuiMenuItem\n const muiProps: MuiMenuItemProps = ((): MuiMenuItemProps => {\n switch (type) {\n case 'checkbox': {\n const { checked: _c, onCheckedChange: _h, ...rest } = props as CheckboxMenuItemProps;\n return rest as MuiMenuItemProps;\n }\n case 'avatar': {\n const { avatar: _a, ...rest } = props as AvatarMenuItemProps;\n return rest as MuiMenuItemProps;\n }\n case 'icon': {\n const { icon: _i, ...rest } = props as IconMenuItemProps;\n return rest as MuiMenuItemProps;\n }\n default:\n return props as MuiMenuItemProps;\n }\n })();\n\n const handleClick = (event: React.MouseEvent<HTMLLIElement>): void => {\n if (disabled) {\n return;\n }\n\n // If menu item is a checkbox, clicking the menu item will toggle the checkbox\n if (type === 'checkbox') {\n event.preventDefault();\n event.stopPropagation();\n\n const { checked, onCheckedChange } = props as CheckboxMenuItemProps;\n const isChecked =\n typeof checked === 'boolean' ? checked : Boolean((props as MuiMenuItemProps).selected);\n\n onCheckedChange?.(!isChecked, event);\n return;\n }\n\n muiProps?.onClick?.(event);\n };\n\n const renderAvatar = (): React.ReactNode => {\n const { avatar } = props as AvatarMenuItemProps;\n return <StyledStartAdornment disabled={disabled}>{avatar}</StyledStartAdornment>;\n };\n\n const renderCheckbox = (): React.ReactNode => {\n const { checked } = props as CheckboxMenuItemProps;\n const isChecked = typeof checked === 'boolean' ? checked : Boolean((props as MuiMenuItemProps).selected);\n\n return (\n <StyledCheckbox\n aria-hidden\n checked={isChecked}\n disabled={disabled}\n fdKey=\"checkbox-menu-item\"\n size=\"small\"\n tabIndex={-1}\n />\n );\n };\n\n const renderIcon = (): React.ReactNode => {\n const { icon } = props as IconMenuItemProps;\n return <StyledStartAdornment>{icon}</StyledStartAdornment>;\n };\n\n const renderStartAdornment = (): React.ReactNode => {\n switch (type) {\n case 'avatar':\n return renderAvatar();\n case 'checkbox':\n return renderCheckbox();\n case 'icon':\n return renderIcon();\n default:\n return null;\n }\n };\n\n const renderText = (): React.ReactNode => {\n if (label || secondaryText) {\n return <ListItemText primary={label} secondary={secondaryText} />;\n }\n\n return children;\n };\n\n return (\n <MuiMenuItem {...muiProps} disabled={disabled} onClick={handleClick}>\n {renderStartAdornment()}\n {renderText()}\n </MuiMenuItem>\n );\n};\n\nexport default MenuItem;\n"],"names":["StyledStartAdornment","styled","Box","shouldForwardProp","prop","theme","disabled","alignItems","display","justifyContent","opacity","palette","action","disabledOpacity","StyledCheckbox","Checkbox","pointerEvents","MenuItem","children","label","secondaryText","type","props","muiProps","checked","_c","onCheckedChange","_h","rest","avatar","_a","icon","_i","_jsxs","MuiMenuItem","onClick","event","preventDefault","stopPropagation","isChecked","Boolean","selected","_jsx","renderAvatar","fdKey","size","tabIndex","renderCheckbox","renderIcon","renderStartAdornment","ListItemText","primary","secondary"],"mappings":"qPAoDA,MAAMA,EAAuBC,EAAOC,EAAK,CACvCC,kBAAoBC,GAAkB,aAATA,GADFH,EAEF,EAAGI,QAAOC,YAAW,MAAO,CACrDC,WAAY,SACZC,QAAS,cACTC,eAAgB,SAEhB,mBAAoB,CAClBC,QAASJ,EAAWD,EAAMM,QAAQC,OAAOC,gBAAkB,OAIzDC,EAAiBb,EAAOc,EAAPd,EAAiB,KAAA,CACtCe,cAAe,WAGJC,EAAW,EACtBC,WACAZ,YAAW,EACXa,QACAC,gBACAC,OAAO,UACJC,MAGH,MAAMC,EAA6B,MACjC,OAAQF,GACN,IAAK,WAAY,CACf,MAAQG,QAASC,EAAIC,gBAAiBC,KAAOC,GAASN,EACtD,OAAOM,CACT,CACA,IAAK,SAAU,CACb,MAAQC,OAAQC,KAAOF,GAASN,EAChC,OAAOM,CACT,CACA,IAAK,OAAQ,CACX,MAAQG,KAAMC,KAAOJ,GAASN,EAC9B,OAAOM,CACT,CACA,QACE,OAAON,EAEZ,EAjBkC,GAuFnC,OACEW,EAACC,EAAW,IAAKX,EAAUjB,SAAUA,EAAU6B,QArE5BC,IACnB,IAAI9B,EAKJ,GAAa,aAATe,EAYJE,GAAUY,UAAUC,OAZpB,CACEA,EAAMC,iBACND,EAAME,kBAEN,MAAMd,QAAEA,EAAOE,gBAAEA,GAAoBJ,EAC/BiB,EACe,kBAAZf,EAAwBA,EAAUgB,QAASlB,EAA2BmB,UAE/Ef,KAAmBa,EAAWH,EAEhC,aA+B2B,MAC3B,OAAQf,GACN,IAAK,SACH,MA7Be,MACnB,MAAMQ,OAAEA,GAAWP,EACnB,OAAOoB,EAAC1C,EAAoB,CAACM,SAAUA,EAAQY,SAAGW,KA2BvCc,GACT,IAAK,WACH,MA1BiB,MACrB,MAAMnB,QAAEA,GAAYF,EACdiB,EAA+B,kBAAZf,EAAwBA,EAAUgB,QAASlB,EAA2BmB,UAE/F,OACEC,EAAC5B,EAAc,CAAA,eAAA,EAEbU,QAASe,EACTjC,SAAUA,EACVsC,MAAM,qBACNC,KAAK,QACLC,UAAU,KAeHC,GACT,IAAK,OACH,MAZa,MACjB,MAAMhB,KAAEA,GAAST,EACjB,OAAOoB,EAAC1C,EAAoB,CAAAkB,SAAEa,KAUnBiB,GACT,QACE,OAAO,OAcRC,GATC9B,GAASC,EACJsB,EAACQ,EAAY,CAACC,QAAShC,EAAOiC,UAAWhC,IAG3CF"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("react"),l=require("@mui/material/Box"),i=require("@mui/material/FormHelperText"),t=require("@mui/material/InputLabel"),s=require("@mui/material/Select"),d=require("@mui/material/styles"),o=require("../../../icons/ArrowDown01/index.cjs.js"),a=require("../../../icons/ArrowUp01/index.cjs.js"),n=require("../../../icons/CancelCircle/index.cjs.js"),u=require("../MenuItem/index.cjs.js");const c=d.styled(l,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:r=!1})=>({display:"flex",flexDirection:"column",gap:e.spacing(.5),width:r?"100%":"min(364px, 100%)"}))),p=d.styled(s,{shouldForwardProp:e=>!["fullWidth","showPlaceholder"].includes(e)})((({theme:e,fullWidth:r=!1,showPlaceholder:l=!1})=>({display:"flex",width:r?"100%":"auto","& .MuiSelect-select":{color:l?e.palette.semantic.text["text-weak"]:e.palette.semantic.text["text-strong"]}}))),h=d.styled(l,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:r=!1})=>({alignItems:"center",cursor:r?"not-allowed":"pointer",display:"flex",justifyContent:"center",pointerEvents:"auto","& svg":{color:r?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),x=d.styled(u.MenuItem)((()=>({display:"none"}))),m=({children:s,disabled:d=!1,errorText:m,fdKey:j,fullWidth:b=!1,helperText:f,label:v,onChange:q,options:y=[],placeholder:w,required:g=!1,value:P,...C})=>{const[I,W]=r.useState(!1),M=f?`${j}-helper-text`:void 0,F=m?`${j}-error-message`:void 0,S=[M,F].filter(Boolean).join(" ")||void 0,k=!!m&&!d,D=!(!w||P&&""!==P),T=()=>{d||W((e=>!e))},A=r.useMemo((()=>y.map((r=>e.jsx(u.MenuItem,{disabled:r.disabled,value:r.value,children:r.label},r.value)))),[y]);return e.jsxs(c,{fullWidth:b,children:[e.jsxs(l,{children:[v&&e.jsx(t,{disabled:d,htmlFor:j,required:g,children:v}),f&&e.jsx(i,{disabled:d,id:M,children:f})]}),k&&e.jsxs(i,{error:!0,id:F,children:[e.jsx(n,{}),m]}),e.jsx(p,{"data-fd":j,disabled:d,error:k,fullWidth:b,IconComponent:()=>e.jsx(h,{disabled:d,onClick:e=>{d||(e.stopPropagation(),T())},children:I?e.jsx(a,{}):e.jsx(o,{})}),id:j,inputProps:{"aria-describedby":S},label:"",onChange:(e,r)=>{!(r&&"object"==typeof r&&"props"in r&&r.props?.disabled)?q&&q(e,r):e.preventDefault()},onClick:T,open:I,required:g,showPlaceholder:D,value:D?w:String(P),variant:"outlined",...C,children:(()=>{const r=[];return D&&r.push(e.jsx(x,{disabled:!0,"aria-hidden":"true",tabIndex:-1,value:w,children:w},"placeholder")),y?.length>0?r.push(...A):r.push(s),r})()})]})};exports.Select=m,exports.default=m;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("react"),i=require("@mui/material/Box"),l=require("@mui/material/FormHelperText"),t=require("@mui/material/InputLabel"),s=require("@mui/material/Select"),d=require("@mui/material/styles"),o=require("../../../icons/ArrowDown01/index.cjs.js"),a=require("../../../icons/ArrowUp01/index.cjs.js"),n=require("../../../icons/CancelCircle/index.cjs.js"),u=require("../MenuItem/index.cjs.js");const c=d.styled(i,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:r=!1})=>({display:"flex",flexDirection:"column",gap:e.spacing(.5),width:r?"100%":"min(364px, 100%)"}))),p=d.styled(s,{shouldForwardProp:e=>!["fullWidth","showPlaceholder"].includes(e)})((({theme:e,fullWidth:r=!1,showPlaceholder:i=!1})=>({display:"flex",width:r?"100%":"auto","& .MuiSelect-select":{color:i?e.palette.semantic.text["text-weak"]:e.palette.semantic.text["text-strong"]}}))),h=d.styled(i,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:r=!1})=>({alignItems:"center",cursor:r?"not-allowed":"pointer",display:"flex",justifyContent:"center",paddingRight:e.spacing(2),pointerEvents:"auto","& svg":{color:r?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),x=d.styled(u.MenuItem)((()=>({display:"none"}))),m=({children:s,disabled:d=!1,errorText:m,fdKey:j,fullWidth:b=!1,helperText:f,label:v,onChange:g,options:q=[],placeholder:y,required:w=!1,value:P,...C})=>{const[I,W]=r.useState(!1),M=f?`${j}-helper-text`:void 0,F=m?`${j}-error-message`:void 0,S=[M,F].filter(Boolean).join(" ")||void 0,D=!!m&&!d,T=!(!y||P&&""!==P);r.useEffect((()=>{d&&W(!1)}),[d]);const k=e=>{d||W(void 0===e?e=>!e:e)},A=r.useMemo((()=>q.map((r=>e.jsx(u.MenuItem,{disabled:r.disabled,value:r.value,children:r.label},r.value)))),[q]);return e.jsxs(c,{fullWidth:b,children:[e.jsxs(i,{children:[v&&e.jsx(t,{disabled:d,htmlFor:j,required:w,children:v}),f&&e.jsx(l,{disabled:d,id:M,children:f})]}),D&&e.jsxs(l,{error:!0,id:F,children:[e.jsx(n,{}),m]}),e.jsx(p,{"data-fd":j,disabled:d,error:D,fullWidth:b,IconComponent:()=>e.jsx(h,{disabled:d,onClick:e=>{d||(e.stopPropagation(),k())},children:I?e.jsx(a,{}):e.jsx(o,{})}),id:j,inputProps:{"aria-describedby":S},label:"",onChange:(e,r)=>{!(r&&"object"==typeof r&&"props"in r&&r.props?.disabled)?g&&g(e,r):e.preventDefault()},onClose:()=>k(!1),onOpen:()=>k(!0),open:I,required:w,showPlaceholder:T,value:T?y:String(P),variant:"outlined",...C,children:(()=>{const r=[];return T&&r.push(e.jsx(x,{disabled:!0,"aria-hidden":"true",tabIndex:-1,value:y,children:y},"placeholder")),q?.length>0?r.push(...A):r.push(s),r})()})]})};exports.Select=m,exports.default=m;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/Select/index.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport MuiSelect, { type SelectChangeEvent, type SelectProps as MuiSelectProps } from '@mui/material/Select';\nimport { styled } from '@mui/material/styles';\n\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\n\nimport MenuItem from '../MenuItem';\n\nexport interface SelectOption {\n value: number | string;\n label: string;\n disabled?: boolean;\n}\n\nexport type SelectProps = Omit<MuiSelectProps, 'error' | 'id' | 'value' | 'variant'> & {\n errorText?: string;\n fdKey: string;\n helperText?: string;\n options?: SelectOption[];\n placeholder?: string;\n value?: number | string;\n};\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain minWidth to a maximum of 100% of the container width\n}));\n\nconst StyledSelect = styled(MuiSelect, {\n shouldForwardProp: (prop) => !['fullWidth', 'showPlaceholder'].includes(prop as string),\n})<{ fullWidth?: boolean; showPlaceholder?: boolean }>(\n ({ theme, fullWidth = false, showPlaceholder = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n\n '& .MuiSelect-select': {\n color: showPlaceholder\n ? theme.palette.semantic.text['text-weak']\n : theme.palette.semantic.text['text-strong'],\n },\n }),\n);\n\nconst StyledIconContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n alignItems: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n display: 'flex',\n justifyContent: 'center',\n pointerEvents: 'auto',\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledHiddenPlaceholderMenuItem = styled(MenuItem)(() => ({\n display: 'none',\n}));\n\nexport const Select = ({\n children,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n onChange,\n options = [],\n placeholder,\n required = false,\n value,\n ...props\n}: SelectProps): JSX.Element => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const showPlaceholder = !!placeholder && (!value || value === '');\n\n const handleOpen = (): void => {\n if (disabled) {\n return;\n }\n\n setIsOpen((open) => !open);\n };\n\n const handleChange = (event: SelectChangeEvent<unknown>, child?: React.ReactNode): void => {\n // Check if the child is disabled\n const isMenuItemDisabled = !!(\n child &&\n typeof child === 'object' &&\n 'props' in (child as React.ReactElement) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (child as React.ReactElement).props?.disabled\n );\n if (isMenuItemDisabled) {\n event.preventDefault();\n return;\n }\n\n // Call the original onChange handler if provided\n if (onChange) {\n onChange(event, child);\n }\n };\n\n const getDisplayValue = (): string => {\n if (showPlaceholder) {\n return placeholder;\n }\n\n return String(value);\n };\n\n const renderIcon = (): JSX.Element => {\n const handleIconClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n handleOpen();\n };\n\n return (\n <StyledIconContainer disabled={disabled} onClick={handleIconClick}>\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledIconContainer>\n );\n };\n\n const optionsMenuItems = useMemo((): React.ReactNode[] => {\n return options.map((option) => (\n <MenuItem key={option.value} disabled={option.disabled} value={option.value}>\n {option.label}\n </MenuItem>\n ));\n }, [options]);\n\n const renderMenuItems = (): React.ReactNode => {\n const menuItems = [];\n\n // Workaround to get the placeholder to show up when no value is selected\n // Placeholder must be a menu item to be displayed\n if (showPlaceholder) {\n menuItems.push(\n <StyledHiddenPlaceholderMenuItem\n key=\"placeholder\"\n disabled\n aria-hidden=\"true\"\n tabIndex={-1}\n value={placeholder}\n >\n {placeholder}\n </StyledHiddenPlaceholderMenuItem>,\n );\n }\n\n // Add either options or children\n if (options?.length > 0) {\n menuItems.push(...optionsMenuItems);\n } else {\n // If no options are provided, use the children\n menuItems.push(children);\n }\n\n return menuItems;\n };\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledSelect\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n IconComponent={renderIcon}\n id={fdKey}\n inputProps={{\n 'aria-describedby': ariaDescribedBy,\n }}\n label=\"\" // Remove label from Select since we're rendering it separately\n onChange={handleChange}\n onClick={handleOpen}\n open={isOpen}\n required={required}\n showPlaceholder={showPlaceholder}\n value={getDisplayValue()}\n variant=\"outlined\"\n {...props}\n >\n {renderMenuItems()}\n </StyledSelect>\n </StyledContainer>\n );\n};\n\nexport type { SelectChangeEvent };\nexport default Select;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledSelect","MuiSelect","includes","showPlaceholder","color","palette","semantic","text","StyledIconContainer","disabled","alignItems","cursor","justifyContent","pointerEvents","icon","StyledHiddenPlaceholderMenuItem","MenuItem","Select","children","errorText","fdKey","helperText","label","onChange","options","placeholder","required","value","props","isOpen","setIsOpen","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","handleOpen","open","optionsMenuItems","useMemo","map","option","_jsx","_jsxs","MuiInputLabel","htmlFor","MuiFormHelperText","id","error","CancelCircleIcon","IconComponent","onClick","event","stopPropagation","ArrowUp01Icon","ArrowDown01Icon","inputProps","child","preventDefault","String","variant","menuItems","push","tabIndex","length","renderMenuItems"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/Select/index.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport MuiSelect, { type SelectChangeEvent, type SelectProps as MuiSelectProps } from '@mui/material/Select';\nimport { styled } from '@mui/material/styles';\n\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\n\nimport MenuItem from '../MenuItem';\n\nexport interface SelectOption {\n value: number | string;\n label: string;\n disabled?: boolean;\n}\n\nexport type SelectProps = Omit<MuiSelectProps, 'error' | 'id' | 'value' | 'variant'> & {\n errorText?: string;\n fdKey: string;\n helperText?: string;\n options?: SelectOption[];\n placeholder?: string;\n value?: number | string;\n};\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain minWidth to a maximum of 100% of the container width\n}));\n\nconst StyledSelect = styled(MuiSelect, {\n shouldForwardProp: (prop) => !['fullWidth', 'showPlaceholder'].includes(prop as string),\n})<{ fullWidth?: boolean; showPlaceholder?: boolean }>(\n ({ theme, fullWidth = false, showPlaceholder = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n\n '& .MuiSelect-select': {\n color: showPlaceholder\n ? theme.palette.semantic.text['text-weak']\n : theme.palette.semantic.text['text-strong'],\n },\n }),\n);\n\nconst StyledIconContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n alignItems: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n display: 'flex',\n justifyContent: 'center',\n paddingRight: theme.spacing(2),\n pointerEvents: 'auto',\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledHiddenPlaceholderMenuItem = styled(MenuItem)(() => ({\n display: 'none',\n}));\n\nexport const Select = ({\n children,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n onChange,\n options = [],\n placeholder,\n required = false,\n value,\n ...props\n}: SelectProps): JSX.Element => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const showPlaceholder = !!placeholder && (!value || value === '');\n\n // Close the dropdown (if open) when the component is dynamically disabled\n useEffect(() => {\n if (disabled) {\n setIsOpen(false);\n }\n }, [disabled]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when the component is disabled.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) {\n return;\n }\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const handleChange = (event: SelectChangeEvent<unknown>, child?: React.ReactNode): void => {\n // Check if the child is disabled\n const isMenuItemDisabled = !!(\n child &&\n typeof child === 'object' &&\n 'props' in (child as React.ReactElement) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (child as React.ReactElement).props?.disabled\n );\n if (isMenuItemDisabled) {\n event.preventDefault();\n return;\n }\n\n // Call the original onChange handler if provided\n if (onChange) {\n onChange(event, child);\n }\n };\n\n const getDisplayValue = (): string => {\n if (showPlaceholder) {\n return placeholder;\n }\n\n return String(value);\n };\n\n const renderIcon = (): JSX.Element => {\n const handleIconClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n return (\n <StyledIconContainer disabled={disabled} onClick={handleIconClick}>\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledIconContainer>\n );\n };\n\n const optionsMenuItems = useMemo((): React.ReactNode[] => {\n return options.map((option) => (\n <MenuItem key={option.value} disabled={option.disabled} value={option.value}>\n {option.label}\n </MenuItem>\n ));\n }, [options]);\n\n const renderMenuItems = (): React.ReactNode => {\n const menuItems = [];\n\n // Workaround to get the placeholder to show up when no value is selected\n // Placeholder must be a menu item to be displayed\n if (showPlaceholder) {\n menuItems.push(\n <StyledHiddenPlaceholderMenuItem\n key=\"placeholder\"\n disabled\n aria-hidden=\"true\"\n tabIndex={-1}\n value={placeholder}\n >\n {placeholder}\n </StyledHiddenPlaceholderMenuItem>,\n );\n }\n\n // Add either options or children\n if (options?.length > 0) {\n menuItems.push(...optionsMenuItems);\n } else {\n // If no options are provided, use the children\n menuItems.push(children);\n }\n\n return menuItems;\n };\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledSelect\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n IconComponent={renderIcon}\n id={fdKey}\n inputProps={{\n 'aria-describedby': ariaDescribedBy,\n }}\n label=\"\" // Remove label from Select since we're rendering it separately\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n required={required}\n showPlaceholder={showPlaceholder}\n value={getDisplayValue()}\n variant=\"outlined\"\n {...props}\n >\n {renderMenuItems()}\n </StyledSelect>\n </StyledContainer>\n );\n};\n\nexport type { SelectChangeEvent };\nexport default Select;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledSelect","MuiSelect","includes","showPlaceholder","color","palette","semantic","text","StyledIconContainer","disabled","alignItems","cursor","justifyContent","paddingRight","pointerEvents","icon","StyledHiddenPlaceholderMenuItem","MenuItem","Select","children","errorText","fdKey","helperText","label","onChange","options","placeholder","required","value","props","isOpen","setIsOpen","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","useEffect","toggleOpen","open","prevOpen","optionsMenuItems","useMemo","map","option","_jsx","_jsxs","MuiInputLabel","htmlFor","MuiFormHelperText","id","error","CancelCircleIcon","IconComponent","onClick","event","stopPropagation","ArrowUp01Icon","ArrowDown01Icon","inputProps","child","preventDefault","onClose","onOpen","String","variant","menuItems","push","tabIndex","length","renderMenuItems"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import{useState as i,useMemo as l}from"react";import o from"@mui/material/Box";import t from"@mui/material/FormHelperText";import d from"@mui/material/InputLabel";import a from"@mui/material/Select";import{styled as n}from"@mui/material/styles";import s from"../../../icons/ArrowDown01/index.js";import p from"../../../icons/ArrowUp01/index.js";import c from"../../../icons/CancelCircle/index.js";import{MenuItem as m}from"../MenuItem/index.js";const u=n(o,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:r=!1})=>({display:"flex",flexDirection:"column",gap:e.spacing(.5),width:r?"100%":"min(364px, 100%)"}))),h=n(a,{shouldForwardProp:e=>!["fullWidth","showPlaceholder"].includes(e)})((({theme:e,fullWidth:r=!1,showPlaceholder:i=!1})=>({display:"flex",width:r?"100%":"auto","& .MuiSelect-select":{color:i?e.palette.semantic.text["text-weak"]:e.palette.semantic.text["text-strong"]}}))),f=n(o,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:r=!1})=>({alignItems:"center",cursor:r?"not-allowed":"pointer",display:"flex",justifyContent:"center",pointerEvents:"auto","& svg":{color:r?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),x=n(m)((()=>({display:"none"}))),b=({children:a,disabled:n=!1,errorText:b,fdKey:v,fullWidth:w=!1,helperText:g,label:y,onChange:j,options:C=[],placeholder:P,required:W=!1,value:F,...I})=>{const[k,q]=i(!1),D=g?`${v}-helper-text`:void 0,S=b?`${v}-error-message`:void 0,T=[D,S].filter(Boolean).join(" ")||void 0,A=!!b&&!n,B=!(!P||F&&""!==F),M=()=>{n||q((e=>!e))},$=l((()=>C.map((r=>e(m,{disabled:r.disabled,value:r.value,children:r.label},r.value)))),[C]);return r(u,{fullWidth:w,children:[r(o,{children:[y&&e(d,{disabled:n,htmlFor:v,required:W,children:y}),g&&e(t,{disabled:n,id:D,children:g})]}),A&&r(t,{error:!0,id:S,children:[e(c,{}),b]}),e(h,{"data-fd":v,disabled:n,error:A,fullWidth:w,IconComponent:()=>e(f,{disabled:n,onClick:e=>{n||(e.stopPropagation(),M())},children:e(k?p:s,{})}),id:v,inputProps:{"aria-describedby":T},label:"",onChange:(e,r)=>{!(r&&"object"==typeof r&&"props"in r&&r.props?.disabled)?j&&j(e,r):e.preventDefault()},onClick:M,open:k,required:W,showPlaceholder:B,value:B?P:String(F),variant:"outlined",...I,children:(()=>{const r=[];return B&&r.push(e(x,{disabled:!0,"aria-hidden":"true",tabIndex:-1,value:P,children:P},"placeholder")),C?.length>0?r.push(...$):r.push(a),r})()})]})};export{b as Select,b as default};
1
+ import{jsx as e,jsxs as i}from"react/jsx-runtime";import{useState as r,useEffect as o,useMemo as l}from"react";import t from"@mui/material/Box";import d from"@mui/material/FormHelperText";import a from"@mui/material/InputLabel";import n from"@mui/material/Select";import{styled as s}from"@mui/material/styles";import p from"../../../icons/ArrowDown01/index.js";import c from"../../../icons/ArrowUp01/index.js";import m from"../../../icons/CancelCircle/index.js";import{MenuItem as h}from"../MenuItem/index.js";const u=s(t,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:i=!1})=>({display:"flex",flexDirection:"column",gap:e.spacing(.5),width:i?"100%":"min(364px, 100%)"}))),f=s(n,{shouldForwardProp:e=>!["fullWidth","showPlaceholder"].includes(e)})((({theme:e,fullWidth:i=!1,showPlaceholder:r=!1})=>({display:"flex",width:i?"100%":"auto","& .MuiSelect-select":{color:r?e.palette.semantic.text["text-weak"]:e.palette.semantic.text["text-strong"]}}))),x=s(t,{shouldForwardProp:e=>"disabled"!==e})((({theme:e,disabled:i=!1})=>({alignItems:"center",cursor:i?"not-allowed":"pointer",display:"flex",justifyContent:"center",paddingRight:e.spacing(2),pointerEvents:"auto","& svg":{color:i?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),b=s(h)((()=>({display:"none"}))),g=({children:n,disabled:s=!1,errorText:g,fdKey:v,fullWidth:w=!1,helperText:y,label:j,onChange:C,options:P=[],placeholder:W,required:F=!1,value:I,...q})=>{const[D,S]=r(!1),T=y?`${v}-helper-text`:void 0,k=g?`${v}-error-message`:void 0,A=[T,k].filter(Boolean).join(" ")||void 0,B=!!g&&!s,M=!(!W||I&&""!==I);o((()=>{s&&S(!1)}),[s]);const $=e=>{s||S(void 0===e?e=>!e:e)},E=l((()=>P.map((i=>e(h,{disabled:i.disabled,value:i.value,children:i.label},i.value)))),[P]);return i(u,{fullWidth:w,children:[i(t,{children:[j&&e(a,{disabled:s,htmlFor:v,required:F,children:j}),y&&e(d,{disabled:s,id:T,children:y})]}),B&&i(d,{error:!0,id:k,children:[e(m,{}),g]}),e(f,{"data-fd":v,disabled:s,error:B,fullWidth:w,IconComponent:()=>e(x,{disabled:s,onClick:e=>{s||(e.stopPropagation(),$())},children:e(D?c:p,{})}),id:v,inputProps:{"aria-describedby":A},label:"",onChange:(e,i)=>{!(i&&"object"==typeof i&&"props"in i&&i.props?.disabled)?C&&C(e,i):e.preventDefault()},onClose:()=>$(!1),onOpen:()=>$(!0),open:D,required:F,showPlaceholder:M,value:M?W:String(I),variant:"outlined",...q,children:(()=>{const i=[];return M&&i.push(e(b,{disabled:!0,"aria-hidden":"true",tabIndex:-1,value:W,children:W},"placeholder")),P?.length>0?i.push(...E):i.push(n),i})()})]})};export{g as Select,g as default};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/Select/index.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport MuiSelect, { type SelectChangeEvent, type SelectProps as MuiSelectProps } from '@mui/material/Select';\nimport { styled } from '@mui/material/styles';\n\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\n\nimport MenuItem from '../MenuItem';\n\nexport interface SelectOption {\n value: number | string;\n label: string;\n disabled?: boolean;\n}\n\nexport type SelectProps = Omit<MuiSelectProps, 'error' | 'id' | 'value' | 'variant'> & {\n errorText?: string;\n fdKey: string;\n helperText?: string;\n options?: SelectOption[];\n placeholder?: string;\n value?: number | string;\n};\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain minWidth to a maximum of 100% of the container width\n}));\n\nconst StyledSelect = styled(MuiSelect, {\n shouldForwardProp: (prop) => !['fullWidth', 'showPlaceholder'].includes(prop as string),\n})<{ fullWidth?: boolean; showPlaceholder?: boolean }>(\n ({ theme, fullWidth = false, showPlaceholder = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n\n '& .MuiSelect-select': {\n color: showPlaceholder\n ? theme.palette.semantic.text['text-weak']\n : theme.palette.semantic.text['text-strong'],\n },\n }),\n);\n\nconst StyledIconContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n alignItems: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n display: 'flex',\n justifyContent: 'center',\n pointerEvents: 'auto',\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledHiddenPlaceholderMenuItem = styled(MenuItem)(() => ({\n display: 'none',\n}));\n\nexport const Select = ({\n children,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n onChange,\n options = [],\n placeholder,\n required = false,\n value,\n ...props\n}: SelectProps): JSX.Element => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const showPlaceholder = !!placeholder && (!value || value === '');\n\n const handleOpen = (): void => {\n if (disabled) {\n return;\n }\n\n setIsOpen((open) => !open);\n };\n\n const handleChange = (event: SelectChangeEvent<unknown>, child?: React.ReactNode): void => {\n // Check if the child is disabled\n const isMenuItemDisabled = !!(\n child &&\n typeof child === 'object' &&\n 'props' in (child as React.ReactElement) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (child as React.ReactElement).props?.disabled\n );\n if (isMenuItemDisabled) {\n event.preventDefault();\n return;\n }\n\n // Call the original onChange handler if provided\n if (onChange) {\n onChange(event, child);\n }\n };\n\n const getDisplayValue = (): string => {\n if (showPlaceholder) {\n return placeholder;\n }\n\n return String(value);\n };\n\n const renderIcon = (): JSX.Element => {\n const handleIconClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n handleOpen();\n };\n\n return (\n <StyledIconContainer disabled={disabled} onClick={handleIconClick}>\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledIconContainer>\n );\n };\n\n const optionsMenuItems = useMemo((): React.ReactNode[] => {\n return options.map((option) => (\n <MenuItem key={option.value} disabled={option.disabled} value={option.value}>\n {option.label}\n </MenuItem>\n ));\n }, [options]);\n\n const renderMenuItems = (): React.ReactNode => {\n const menuItems = [];\n\n // Workaround to get the placeholder to show up when no value is selected\n // Placeholder must be a menu item to be displayed\n if (showPlaceholder) {\n menuItems.push(\n <StyledHiddenPlaceholderMenuItem\n key=\"placeholder\"\n disabled\n aria-hidden=\"true\"\n tabIndex={-1}\n value={placeholder}\n >\n {placeholder}\n </StyledHiddenPlaceholderMenuItem>,\n );\n }\n\n // Add either options or children\n if (options?.length > 0) {\n menuItems.push(...optionsMenuItems);\n } else {\n // If no options are provided, use the children\n menuItems.push(children);\n }\n\n return menuItems;\n };\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledSelect\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n IconComponent={renderIcon}\n id={fdKey}\n inputProps={{\n 'aria-describedby': ariaDescribedBy,\n }}\n label=\"\" // Remove label from Select since we're rendering it separately\n onChange={handleChange}\n onClick={handleOpen}\n open={isOpen}\n required={required}\n showPlaceholder={showPlaceholder}\n value={getDisplayValue()}\n variant=\"outlined\"\n {...props}\n >\n {renderMenuItems()}\n </StyledSelect>\n </StyledContainer>\n );\n};\n\nexport type { SelectChangeEvent };\nexport default Select;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledSelect","MuiSelect","includes","showPlaceholder","color","palette","semantic","text","StyledIconContainer","disabled","alignItems","cursor","justifyContent","pointerEvents","icon","StyledHiddenPlaceholderMenuItem","MenuItem","Select","children","errorText","fdKey","helperText","label","onChange","options","placeholder","required","value","props","isOpen","setIsOpen","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","handleOpen","open","optionsMenuItems","useMemo","map","option","_jsx","_jsxs","MuiInputLabel","htmlFor","MuiFormHelperText","id","error","CancelCircleIcon","IconComponent","onClick","event","stopPropagation","ArrowUp01Icon","ArrowDown01Icon","inputProps","child","preventDefault","String","variant","menuItems","push","tabIndex","length","renderMenuItems"],"mappings":"+eA6BA,MAAMA,EAAkBC,EAAOC,EAAK,CAClCC,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGI,QAAOC,aAAY,MAAO,CACvDC,QAAS,OACTC,cAAe,SACfC,IAAKJ,EAAMK,QAAQ,IACnBC,MAAOL,EAAY,OAAS,uBAGxBM,EAAeX,EAAOY,EAAW,CACrCV,kBAAoBC,IAAU,CAAC,YAAa,mBAAmBU,SAASV,IADrDH,EAGnB,EAAGI,QAAOC,aAAY,EAAOS,mBAAkB,MAAO,CACpDR,QAAS,OACTI,MAAOL,EAAY,OAAS,OAE5B,sBAAuB,CACrBU,MAAOD,EACHV,EAAMY,QAAQC,SAASC,KAAK,aAC5Bd,EAAMY,QAAQC,SAASC,KAAK,oBAKhCC,EAAsBnB,EAAOC,EAAK,CACtCC,kBAAoBC,GAAkB,aAATA,GADHH,EAED,EAAGI,QAAOgB,YAAW,MAAO,CACrDC,WAAY,SACZC,OAAQF,EAAW,cAAgB,UACnCd,QAAS,OACTiB,eAAgB,SAChBC,cAAe,OAEf,QAAS,CACPT,MAAOK,EACHhB,EAAMY,QAAQC,SAASQ,KAAK,iBAC5BrB,EAAMY,QAAQC,SAASQ,KAAK,oBAI9BC,EAAkC1B,EAAO2B,EAAP3B,EAAiB,KAAA,CACvDM,QAAS,WAGEsB,EAAS,EACpBC,WACAT,YAAW,EACXU,YACAC,QACA1B,aAAY,EACZ2B,aACAC,QACAC,WACAC,UAAU,GACVC,cACAC,YAAW,EACXC,WACGC,MAEH,MAAOC,EAAQC,GAAaC,GAAkB,GAExCC,EAAeX,EAAa,GAAGD,qBAAsBa,EACrDC,EAAiBf,EAAY,GAAGC,uBAAwBa,EAGxDE,EAAkB,CAACH,EAAcE,GAAgBE,OAAOC,SAASC,KAAK,WAAQL,EAE9EM,IAAYpB,IAAcV,EAC1BN,KAAoBsB,GAAiBE,GAAmB,KAAVA,GAE9Ca,EAAa,KACb/B,GAIJqB,GAAWW,IAAUA,KAgDjBC,EAAmBC,GAAQ,IACxBnB,EAAQoB,KAAKC,GAClBC,EAAC9B,EAAQ,CAAoBP,SAAUoC,EAAOpC,SAAUkB,MAAOkB,EAAOlB,eACnEkB,EAAOvB,OADKuB,EAAOlB,UAIvB,CAACH,IAgCJ,OACEuB,EAAC3D,EAAe,CAACM,UAAWA,YAC1BqD,EAACzD,aACEgC,GACCwB,EAACE,GAAcvC,SAAUA,EAAUwC,QAAS7B,EAAOM,SAAUA,EAAQR,SAClEI,IAIJD,GACCyB,EAACI,EAAiB,CAACzC,SAAUA,EAAU0C,GAAInB,EAAYd,SACpDG,OAKNkB,GACCQ,EAACG,EAAiB,CAACE,OAAK,EAACD,GAAIjB,EAAchB,SAAA,CACzC4B,EAACO,EAAgB,CAAA,GAEhBlC,KAIL2B,EAAC9C,aACUoB,EACTX,SAAUA,EACV2C,MAAOb,EACP7C,UAAWA,EACX4D,cApFa,IAWfR,EAACtC,EAAmB,CAACC,SAAUA,EAAU8C,QAVlBC,IACnB/C,IAIJ+C,EAAMC,kBACNjB,MAIiEtB,SACrD4B,EAATjB,EAAU6B,EAAoBC,EAAP,MAyExBR,GAAI/B,EACJwC,WAAY,CACV,mBAAoBzB,GAEtBb,MAAM,GACNC,SAtHe,CAACiC,EAAmCK,OAGrDA,GACiB,iBAAVA,GACP,UAAYA,GAEXA,EAA6BjC,OAAOnB,UAQnCc,GACFA,EAASiC,EAAOK,GANhBL,EAAMM,kBA6GJP,QAASf,EACTC,KAAMZ,EACNH,SAAUA,EACVvB,gBAAiBA,EACjBwB,MAtGAxB,EACKsB,EAGFsC,OAAOpC,GAmGVqC,QAAQ,cACJpC,WAxEc,MACtB,MAAMqC,EAAY,GA0BlB,OAtBI9D,GACF8D,EAAUC,KACRpB,EAAC/B,GAECN,UAAQ,EAAA,cACI,OACZ0D,UAAU,EACVxC,MAAOF,EAAWP,SAEjBO,GANG,gBAYND,GAAS4C,OAAS,EACpBH,EAAUC,QAAQxB,GAGlBuB,EAAUC,KAAKhD,GAGV+C,GA+CFI"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/Select/index.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport MuiSelect, { type SelectChangeEvent, type SelectProps as MuiSelectProps } from '@mui/material/Select';\nimport { styled } from '@mui/material/styles';\n\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\n\nimport MenuItem from '../MenuItem';\n\nexport interface SelectOption {\n value: number | string;\n label: string;\n disabled?: boolean;\n}\n\nexport type SelectProps = Omit<MuiSelectProps, 'error' | 'id' | 'value' | 'variant'> & {\n errorText?: string;\n fdKey: string;\n helperText?: string;\n options?: SelectOption[];\n placeholder?: string;\n value?: number | string;\n};\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain minWidth to a maximum of 100% of the container width\n}));\n\nconst StyledSelect = styled(MuiSelect, {\n shouldForwardProp: (prop) => !['fullWidth', 'showPlaceholder'].includes(prop as string),\n})<{ fullWidth?: boolean; showPlaceholder?: boolean }>(\n ({ theme, fullWidth = false, showPlaceholder = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n\n '& .MuiSelect-select': {\n color: showPlaceholder\n ? theme.palette.semantic.text['text-weak']\n : theme.palette.semantic.text['text-strong'],\n },\n }),\n);\n\nconst StyledIconContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'disabled',\n})<{ disabled?: boolean }>(({ theme, disabled = false }) => ({\n alignItems: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n display: 'flex',\n justifyContent: 'center',\n paddingRight: theme.spacing(2),\n pointerEvents: 'auto',\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n}));\n\nconst StyledHiddenPlaceholderMenuItem = styled(MenuItem)(() => ({\n display: 'none',\n}));\n\nexport const Select = ({\n children,\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n onChange,\n options = [],\n placeholder,\n required = false,\n value,\n ...props\n}: SelectProps): JSX.Element => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const showPlaceholder = !!placeholder && (!value || value === '');\n\n // Close the dropdown (if open) when the component is dynamically disabled\n useEffect(() => {\n if (disabled) {\n setIsOpen(false);\n }\n }, [disabled]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when the component is disabled.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) {\n return;\n }\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const handleChange = (event: SelectChangeEvent<unknown>, child?: React.ReactNode): void => {\n // Check if the child is disabled\n const isMenuItemDisabled = !!(\n child &&\n typeof child === 'object' &&\n 'props' in (child as React.ReactElement) &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (child as React.ReactElement).props?.disabled\n );\n if (isMenuItemDisabled) {\n event.preventDefault();\n return;\n }\n\n // Call the original onChange handler if provided\n if (onChange) {\n onChange(event, child);\n }\n };\n\n const getDisplayValue = (): string => {\n if (showPlaceholder) {\n return placeholder;\n }\n\n return String(value);\n };\n\n const renderIcon = (): JSX.Element => {\n const handleIconClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n return (\n <StyledIconContainer disabled={disabled} onClick={handleIconClick}>\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledIconContainer>\n );\n };\n\n const optionsMenuItems = useMemo((): React.ReactNode[] => {\n return options.map((option) => (\n <MenuItem key={option.value} disabled={option.disabled} value={option.value}>\n {option.label}\n </MenuItem>\n ));\n }, [options]);\n\n const renderMenuItems = (): React.ReactNode => {\n const menuItems = [];\n\n // Workaround to get the placeholder to show up when no value is selected\n // Placeholder must be a menu item to be displayed\n if (showPlaceholder) {\n menuItems.push(\n <StyledHiddenPlaceholderMenuItem\n key=\"placeholder\"\n disabled\n aria-hidden=\"true\"\n tabIndex={-1}\n value={placeholder}\n >\n {placeholder}\n </StyledHiddenPlaceholderMenuItem>,\n );\n }\n\n // Add either options or children\n if (options?.length > 0) {\n menuItems.push(...optionsMenuItems);\n } else {\n // If no options are provided, use the children\n menuItems.push(children);\n }\n\n return menuItems;\n };\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledSelect\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n IconComponent={renderIcon}\n id={fdKey}\n inputProps={{\n 'aria-describedby': ariaDescribedBy,\n }}\n label=\"\" // Remove label from Select since we're rendering it separately\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n required={required}\n showPlaceholder={showPlaceholder}\n value={getDisplayValue()}\n variant=\"outlined\"\n {...props}\n >\n {renderMenuItems()}\n </StyledSelect>\n </StyledContainer>\n );\n};\n\nexport type { SelectChangeEvent };\nexport default Select;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledSelect","MuiSelect","includes","showPlaceholder","color","palette","semantic","text","StyledIconContainer","disabled","alignItems","cursor","justifyContent","paddingRight","pointerEvents","icon","StyledHiddenPlaceholderMenuItem","MenuItem","Select","children","errorText","fdKey","helperText","label","onChange","options","placeholder","required","value","props","isOpen","setIsOpen","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","useEffect","toggleOpen","open","prevOpen","optionsMenuItems","useMemo","map","option","_jsx","_jsxs","MuiInputLabel","htmlFor","MuiFormHelperText","id","error","CancelCircleIcon","IconComponent","onClick","event","stopPropagation","ArrowUp01Icon","ArrowDown01Icon","inputProps","child","preventDefault","onClose","onOpen","String","variant","menuItems","push","tabIndex","length","renderMenuItems"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("react"),i=require("@mui/material/Box"),t=require("@mui/material/FormHelperText"),l=require("@mui/material/InputAdornment"),d=require("@mui/material/InputLabel"),s=require("@mui/material/styles"),n=require("@mui/material/TextField"),a=require("../../../icons/CancelCircle/index.cjs.js"),o=require("../../../icons/View/index.cjs.js"),u=require("../../../icons/ViewOff/index.cjs.js"),x=require("../IconButton/index.cjs.js");const c=s.styled(i,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:r=!1})=>({display:"flex",flexDirection:"column",gap:e.spacing(.5),width:r?"100%":"min(364px, 100%)"}))),m=s.styled(n,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({display:"flex",width:e?"100%":"auto"}))),h=({disabled:s=!1,endAdornment:n,errorText:h,fdKey:p,fullWidth:j=!1,helperText:f,hidePasswordAriaLabel:q,label:b,multiline:w=!1,required:y=!1,showPasswordAriaLabel:v,startAdornment:A,type:W="text",...F})=>{const[P,I]=r.useState(!1),T=f?`${p}-helper-text`:void 0,B=h?`${p}-error-message`:void 0,g=[T,B].filter(Boolean).join(" ")||void 0,C=!!h&&!s,L="password"===W,O=()=>I((e=>!e));return e.jsxs(c,{fullWidth:j,children:[e.jsxs(i,{children:[b&&e.jsx(d,{disabled:s,htmlFor:p,required:y,children:b}),f&&e.jsx(t,{disabled:s,id:T,children:f})]}),C&&e.jsxs(t,{error:!0,id:B,children:[e.jsx(a,{}),h]}),e.jsx(m,{"data-fd":p,disabled:s,error:C,fullWidth:j,id:p,label:"",multiline:w,required:y,slotProps:{input:{endAdornment:(()=>{if(L){if(!v||!q)return;return e.jsx(l,{position:"end",children:e.jsx(x.IconButton,{"aria-label":P?q:v,disabled:s,onClick:O,size:"small",tone:"neutral",variant:"tertiary",children:P?e.jsx(u,{}):e.jsx(o,{})})})}if(n)return e.jsx(l,{position:"end",children:n})})(),startAdornment:(()=>{if(A)return e.jsx(l,{position:"start",children:A})})()},htmlInput:{"aria-describedby":g}},type:L?P?"text":"password":W,variant:"outlined",...F})]})};exports.TextField=h,exports.default=h;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),r=require("react"),i=require("@mui/material/Box"),t=require("@mui/material/FormHelperText"),l=require("@mui/material/InputAdornment"),s=require("@mui/material/InputLabel"),d=require("@mui/material/styles"),n=require("@mui/material/TextField"),a=require("../../../icons/CancelCircle/index.cjs.js"),o=require("../../../icons/View/index.cjs.js"),u=require("../../../icons/ViewOff/index.cjs.js"),x=require("../IconButton/index.cjs.js");const c=d.styled(i,{shouldForwardProp:e=>"fullWidth"!==e})((({theme:e,fullWidth:r=!1})=>({display:"flex",flexDirection:"column",gap:e.spacing(.5),width:r?"100%":"min(364px, 100%)"}))),p=d.styled(n,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({display:"flex",width:e?"100%":"auto"}))),m=({disabled:d=!1,endAdornment:n,errorText:m,fdKey:h,fullWidth:j=!1,helperText:f,hidePasswordAriaLabel:q,label:b,multiline:w=!1,required:y=!1,showPasswordAriaLabel:P,startAdornment:v,type:A="text",...W})=>{const[F,I]=r.useState(!1),T=f?`${h}-helper-text`:void 0,B=m?`${h}-error-message`:void 0,g=[T,B].filter(Boolean).join(" ")||void 0,C=!!m&&!d,L="password"===A,O=()=>I((e=>!e)),V=(()=>{if(L){if(!P||!q)return;return e.jsx(l,{position:"end",children:e.jsx(x.IconButton,{"aria-label":F?q:P,disabled:d,onClick:O,size:"small",tone:"neutral",variant:"tertiary",children:F?e.jsx(u,{}):e.jsx(o,{})})})}if(n)return e.jsx(l,{position:"end",children:n})})(),$=(()=>{if(v)return e.jsx(l,{position:"start",children:v})})();return e.jsxs(c,{fullWidth:j,children:[e.jsxs(i,{children:[b&&e.jsx(s,{disabled:d,htmlFor:h,required:y,children:b}),f&&e.jsx(t,{disabled:d,id:T,children:f})]}),C&&e.jsxs(t,{error:!0,id:B,children:[e.jsx(a,{}),m]}),e.jsx(p,{"data-fd":h,disabled:d,error:C,fullWidth:j,id:h,label:"",multiline:w,required:y,slotProps:{input:{...W.slotProps?.input??{},...$&&{startAdornment:$},...V&&{endAdornment:V}},htmlInput:{...W.slotProps?.htmlInput??{},"aria-describedby":g}},type:L?F?"text":"password":A,variant:"outlined",...W})]})};exports.TextField=m,exports.default=m;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/TextField/index.tsx"],"sourcesContent":["import { type ReactNode, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport { styled } from '@mui/material/styles';\nimport MuiTextField, { type TextFieldProps as MuiTextFieldProps } from '@mui/material/TextField';\n\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\nimport ViewIcon from '@fd/icons/View';\nimport ViewOffIcon from '@fd/icons/ViewOff';\n\nimport IconButton from '../IconButton';\n\n// Common props for all TextField variants\ntype BaseTextFieldProps = Omit<MuiTextFieldProps, 'error' | 'id' | 'type' | 'variant'> & {\n endAdornment?: ReactNode;\n errorText?: string;\n fdKey: string;\n startAdornment?: ReactNode;\n};\n\n// Password TextField variant - requires aria labels\ntype PasswordTextFieldProps = BaseTextFieldProps & {\n type: 'password';\n hidePasswordAriaLabel: string;\n showPasswordAriaLabel: string;\n};\n\n// Generic TextField variant - for all other input types\ntype GenericTextFieldProps = BaseTextFieldProps & {\n type?: Exclude<MuiTextFieldProps['type'], 'password'>;\n hidePasswordAriaLabel?: never;\n showPasswordAriaLabel?: never;\n};\n\nexport type TextFieldProps = GenericTextFieldProps | PasswordTextFieldProps;\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain width to a maximum of 100% of the container width\n}));\n\nconst StyledTextField = styled(MuiTextField, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n}));\n\nexport const TextField = ({\n disabled = false,\n endAdornment = undefined,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n hidePasswordAriaLabel,\n label,\n multiline = false,\n required = false,\n showPasswordAriaLabel,\n startAdornment = undefined,\n type = 'text',\n ...props\n}: TextFieldProps): JSX.Element => {\n const [showPassword, setShowPassword] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const isPassword = type === 'password';\n\n const handleClickShowPassword = (): void => setShowPassword((show) => !show);\n\n const getFieldType = (): MuiTextFieldProps['type'] => {\n if (isPassword) {\n return showPassword ? 'text' : 'password';\n }\n\n return type;\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n if (isPassword) {\n if (!showPasswordAriaLabel || !hidePasswordAriaLabel) {\n return undefined;\n }\n\n return (\n <MuiInputAdornment position=\"end\">\n <IconButton\n aria-label={showPassword ? hidePasswordAriaLabel : showPasswordAriaLabel}\n disabled={disabled}\n onClick={handleClickShowPassword}\n size=\"small\"\n tone=\"neutral\"\n variant=\"tertiary\"\n >\n {showPassword ? <ViewOffIcon /> : <ViewIcon />}\n </IconButton>\n </MuiInputAdornment>\n );\n }\n if (endAdornment) {\n return <MuiInputAdornment position=\"end\">{endAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n const renderStartAdornment = (): React.ReactNode => {\n if (startAdornment) {\n return <MuiInputAdornment position=\"start\">{startAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledTextField\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n id={fdKey}\n label=\"\" // Remove label from TextField since we're rendering it separately\n multiline={multiline}\n required={required}\n slotProps={{\n input: {\n endAdornment: renderEndAdornment(),\n startAdornment: renderStartAdornment(),\n },\n htmlInput: {\n 'aria-describedby': ariaDescribedBy,\n },\n }}\n type={getFieldType()}\n variant=\"outlined\"\n {...props}\n />\n </StyledContainer>\n );\n};\n\nexport default TextField;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledTextField","MuiTextField","TextField","disabled","endAdornment","errorText","fdKey","helperText","hidePasswordAriaLabel","label","multiline","required","showPasswordAriaLabel","startAdornment","type","props","showPassword","setShowPassword","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","isPassword","handleClickShowPassword","show","_jsxs","_jsx","MuiInputLabel","htmlFor","children","MuiFormHelperText","id","error","CancelCircleIcon","slotProps","input","MuiInputAdornment","position","IconButton","onClick","size","tone","variant","ViewOffIcon","ViewIcon","renderEndAdornment","renderStartAdornment","htmlInput"],"mappings":"uhBAuCA,MAAMA,EAAkBC,EAAAA,OAAOC,EAAK,CAClCC,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGI,QAAOC,aAAY,MAAO,CACvDC,QAAS,OACTC,cAAe,SACfC,IAAKJ,EAAMK,QAAQ,IACnBC,MAAOL,EAAY,OAAS,uBAGxBM,EAAkBX,EAAAA,OAAOY,EAAc,CAC3CV,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGK,aAAY,MAAO,CAChDC,QAAS,OACTI,MAAOL,EAAY,OAAS,WAGjBQ,EAAY,EACvBC,YAAW,EACXC,eACAC,YACAC,QACAZ,aAAY,EACZa,aACAC,wBACAC,QACAC,aAAY,EACZC,YAAW,EACXC,wBACAC,iBACAC,OAAO,UACJC,MAEH,MAAOC,EAAcC,GAAmBC,EAAAA,UAAkB,GAEpDC,EAAeZ,EAAa,GAAGD,qBAAsBc,EACrDC,EAAiBhB,EAAY,GAAGC,uBAAwBc,EAGxDE,EAAkB,CAACH,EAAcE,GAAgBE,OAAOC,SAASC,KAAK,WAAQL,EAE9EM,IAAYrB,IAAcF,EAC1BwB,EAAsB,aAATb,EAEbc,EAA0B,IAAYX,GAAiBY,IAAUA,IA8CvE,OACEC,EAAAA,KAAC1C,EAAe,CAACM,UAAWA,YAC1BoC,EAAAA,KAACxC,aACEmB,GACCsB,EAAAA,IAACC,GAAc7B,SAAUA,EAAU8B,QAAS3B,EAAOK,SAAUA,EAAQuB,SAClEzB,IAIJF,GACCwB,EAAAA,IAACI,GAAkBhC,SAAUA,EAAUiC,GAAIjB,EAAYe,SACpD3B,OAKNmB,GACCI,EAAAA,KAACK,GAAkBE,OAAK,EAACD,GAAIf,YAC3BU,EAAAA,IAACO,MAEAjC,KAIL0B,EAAAA,IAAC/B,EAAe,CAAA,UACLM,EACTH,SAAUA,EACVkC,MAAOX,EACPhC,UAAWA,EACX0C,GAAI9B,EACJG,MAAM,GACNC,UAAWA,EACXC,SAAUA,EACV4B,UAAW,CACTC,MAAO,CACLpC,aAvEiB,MACzB,GAAIuB,EAAY,CACd,IAAKf,IAA0BJ,EAC7B,OAGF,OACEuB,EAAAA,IAACU,EAAiB,CAACC,SAAS,MAAKR,SAC/BH,MAACY,EAAAA,WAAU,CAAA,aACG3B,EAAeR,EAAwBI,EACnDT,SAAUA,EACVyC,QAAShB,EACTiB,KAAK,QACLC,KAAK,UACLC,QAAQ,WAAUb,SAEjBlB,EAAee,EAAAA,IAACiB,EAAW,CAAA,GAAMjB,EAAAA,IAACkB,EAAQ,CAAA,MAInD,CACA,GAAI7C,EACF,OAAO2B,EAAAA,IAACU,EAAiB,CAACC,SAAS,MAAKR,SAAE9B,KAiDtB8C,GACdrC,eA5CmB,MAC3B,GAAIA,EACF,OAAOkB,EAAAA,IAACU,EAAiB,CAACC,SAAS,QAAOR,SAAErB,KA0CtBsC,IAElBC,UAAW,CACT,mBAAoB9B,IAGxBR,KArFAa,EACKX,EAAe,OAAS,WAG1BF,EAkFHiC,QAAQ,cACJhC"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/TextField/index.tsx"],"sourcesContent":["import { type ReactNode, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport { styled } from '@mui/material/styles';\nimport MuiTextField, { type TextFieldProps as MuiTextFieldProps } from '@mui/material/TextField';\n\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\nimport ViewIcon from '@fd/icons/View';\nimport ViewOffIcon from '@fd/icons/ViewOff';\n\nimport IconButton from '../IconButton';\n\n// Common props for all TextField variants\ntype BaseTextFieldProps = Omit<MuiTextFieldProps, 'error' | 'id' | 'type' | 'variant'> & {\n endAdornment?: ReactNode;\n errorText?: string;\n fdKey: string;\n startAdornment?: ReactNode;\n};\n\n// Password TextField variant - requires aria labels\ntype PasswordTextFieldProps = BaseTextFieldProps & {\n type: 'password';\n hidePasswordAriaLabel: string;\n showPasswordAriaLabel: string;\n};\n\n// Generic TextField variant - for all other input types\ntype GenericTextFieldProps = BaseTextFieldProps & {\n type?: Exclude<MuiTextFieldProps['type'], 'password'>;\n hidePasswordAriaLabel?: never;\n showPasswordAriaLabel?: never;\n};\n\nexport type TextFieldProps = GenericTextFieldProps | PasswordTextFieldProps;\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain width to a maximum of 100% of the container width\n}));\n\nconst StyledTextField = styled(MuiTextField, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n}));\n\nexport const TextField = ({\n disabled = false,\n endAdornment = undefined,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n hidePasswordAriaLabel,\n label,\n multiline = false,\n required = false,\n showPasswordAriaLabel,\n startAdornment = undefined,\n type = 'text',\n ...props\n}: TextFieldProps): JSX.Element => {\n const [showPassword, setShowPassword] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const isPassword = type === 'password';\n\n const handleClickShowPassword = (): void => setShowPassword((show) => !show);\n\n const getFieldType = (): MuiTextFieldProps['type'] => {\n if (isPassword) {\n return showPassword ? 'text' : 'password';\n }\n\n return type;\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n if (isPassword) {\n if (!showPasswordAriaLabel || !hidePasswordAriaLabel) {\n return undefined;\n }\n\n return (\n <MuiInputAdornment position=\"end\">\n <IconButton\n aria-label={showPassword ? hidePasswordAriaLabel : showPasswordAriaLabel}\n disabled={disabled}\n onClick={handleClickShowPassword}\n size=\"small\"\n tone=\"neutral\"\n variant=\"tertiary\"\n >\n {showPassword ? <ViewOffIcon /> : <ViewIcon />}\n </IconButton>\n </MuiInputAdornment>\n );\n }\n if (endAdornment) {\n return <MuiInputAdornment position=\"end\">{endAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n const renderStartAdornment = (): React.ReactNode => {\n if (startAdornment) {\n return <MuiInputAdornment position=\"start\">{startAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n const renderedEndAdornment = renderEndAdornment();\n const renderedStartAdornment = renderStartAdornment();\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledTextField\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n id={fdKey}\n label=\"\" // Remove label from TextField since we're rendering it separately\n multiline={multiline}\n required={required}\n slotProps={{\n input: {\n ...(props.slotProps?.input ?? {}),\n // Only pass startAdornment and endAdornment if they are defined\n ...(renderedStartAdornment && { startAdornment: renderedStartAdornment }),\n ...(renderedEndAdornment && { endAdornment: renderedEndAdornment }),\n },\n htmlInput: {\n ...(props.slotProps?.htmlInput ?? {}),\n 'aria-describedby': ariaDescribedBy,\n },\n }}\n type={getFieldType()}\n variant=\"outlined\"\n {...props}\n />\n </StyledContainer>\n );\n};\n\nexport default TextField;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledTextField","MuiTextField","TextField","disabled","endAdornment","errorText","fdKey","helperText","hidePasswordAriaLabel","label","multiline","required","showPasswordAriaLabel","startAdornment","type","props","showPassword","setShowPassword","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","isPassword","handleClickShowPassword","show","renderedEndAdornment","_jsx","MuiInputAdornment","position","children","IconButton","onClick","size","tone","variant","ViewOffIcon","ViewIcon","renderEndAdornment","renderedStartAdornment","renderStartAdornment","_jsxs","MuiInputLabel","htmlFor","MuiFormHelperText","id","error","CancelCircleIcon","slotProps","input","htmlInput"],"mappings":"uhBAuCA,MAAMA,EAAkBC,EAAAA,OAAOC,EAAK,CAClCC,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGI,QAAOC,aAAY,MAAO,CACvDC,QAAS,OACTC,cAAe,SACfC,IAAKJ,EAAMK,QAAQ,IACnBC,MAAOL,EAAY,OAAS,uBAGxBM,EAAkBX,EAAAA,OAAOY,EAAc,CAC3CV,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGK,aAAY,MAAO,CAChDC,QAAS,OACTI,MAAOL,EAAY,OAAS,WAGjBQ,EAAY,EACvBC,YAAW,EACXC,eACAC,YACAC,QACAZ,aAAY,EACZa,aACAC,wBACAC,QACAC,aAAY,EACZC,YAAW,EACXC,wBACAC,iBACAC,OAAO,UACJC,MAEH,MAAOC,EAAcC,GAAmBC,EAAAA,UAAkB,GAEpDC,EAAeZ,EAAa,GAAGD,qBAAsBc,EACrDC,EAAiBhB,EAAY,GAAGC,uBAAwBc,EAGxDE,EAAkB,CAACH,EAAcE,GAAgBE,OAAOC,SAASC,KAAK,WAAQL,EAE9EM,IAAYrB,IAAcF,EAC1BwB,EAAsB,aAATb,EAEbc,EAA0B,IAAYX,GAAiBY,IAAUA,IA8CjEC,EApCqB,MACzB,GAAIH,EAAY,CACd,IAAKf,IAA0BJ,EAC7B,OAGF,OACEuB,EAAAA,IAACC,EAAiB,CAACC,SAAS,MAAKC,SAC/BH,MAACI,EAAAA,WAAU,CAAA,aACGnB,EAAeR,EAAwBI,EACnDT,SAAUA,EACViC,QAASR,EACTS,KAAK,QACLC,KAAK,UACLC,QAAQ,WAAUL,SAEjBlB,EAAee,EAAAA,IAACS,EAAW,CAAA,GAAMT,EAAAA,IAACU,EAAQ,CAAA,MAInD,CACA,GAAIrC,EACF,OAAO2B,EAAAA,IAACC,EAAiB,CAACC,SAAS,MAAKC,SAAE9B,KAcjBsC,GACvBC,EATuB,MAC3B,GAAI9B,EACF,OAAOkB,EAAAA,IAACC,EAAiB,CAACC,SAAS,QAAOC,SAAErB,KAOjB+B,GAE/B,OACEC,EAAAA,KAACzD,EAAe,CAACM,UAAWA,YAC1BmD,EAAAA,KAACvD,aACEmB,GACCsB,EAAAA,IAACe,GAAc3C,SAAUA,EAAU4C,QAASzC,EAAOK,SAAUA,EAAQuB,SAClEzB,IAIJF,GACCwB,EAAAA,IAACiB,GAAkB7C,SAAUA,EAAU8C,GAAI9B,EAAYe,SACpD3B,OAKNmB,GACCmB,EAAAA,KAACG,GAAkBE,OAAK,EAACD,GAAI5B,YAC3BU,EAAAA,IAACoB,MAEA9C,KAIL0B,EAAAA,IAAC/B,EAAe,CAAA,UACLM,EACTH,SAAUA,EACV+C,MAAOxB,EACPhC,UAAWA,EACXuD,GAAI3C,EACJG,MAAM,GACNC,UAAWA,EACXC,SAAUA,EACVyC,UAAW,CACTC,MAAO,IACDtC,EAAMqC,WAAWC,OAAS,MAE1BV,GAA0B,CAAE9B,eAAgB8B,MAC5Cb,GAAwB,CAAE1B,aAAc0B,IAE9CwB,UAAW,IACLvC,EAAMqC,WAAWE,WAAa,GAClC,mBAAoBhC,IAGxBR,KA3FAa,EACKX,EAAe,OAAS,WAG1BF,EAwFHyB,QAAQ,cACJxB"}
@@ -1,2 +1,2 @@
1
- import{jsxs as r,jsx as i}from"react/jsx-runtime";import{useState as e}from"react";import t from"@mui/material/Box";import o from"@mui/material/FormHelperText";import l from"@mui/material/InputAdornment";import d from"@mui/material/InputLabel";import{styled as n}from"@mui/material/styles";import a from"@mui/material/TextField";import m from"../../../icons/CancelCircle/index.js";import s from"../../../icons/View/index.js";import u from"../../../icons/ViewOff/index.js";import{IconButton as p}from"../IconButton/index.js";const f=n(t,{shouldForwardProp:r=>"fullWidth"!==r})((({theme:r,fullWidth:i=!1})=>({display:"flex",flexDirection:"column",gap:r.spacing(.5),width:i?"100%":"min(364px, 100%)"}))),h=n(a,{shouldForwardProp:r=>"fullWidth"!==r})((({fullWidth:r=!1})=>({display:"flex",width:r?"100%":"auto"}))),c=({disabled:n=!1,endAdornment:a,errorText:c,fdKey:x,fullWidth:b=!1,helperText:w,hidePasswordAriaLabel:y,label:A,multiline:W=!1,required:j=!1,showPasswordAriaLabel:v,startAdornment:F,type:P="text",...I})=>{const[T,g]=e(!1),q=w?`${x}-helper-text`:void 0,B=c?`${x}-error-message`:void 0,C=[q,B].filter(Boolean).join(" ")||void 0,L=!!c&&!n,V="password"===P,$=()=>g((r=>!r));return r(f,{fullWidth:b,children:[r(t,{children:[A&&i(d,{disabled:n,htmlFor:x,required:j,children:A}),w&&i(o,{disabled:n,id:q,children:w})]}),L&&r(o,{error:!0,id:B,children:[i(m,{}),c]}),i(h,{"data-fd":x,disabled:n,error:L,fullWidth:b,id:x,label:"",multiline:W,required:j,slotProps:{input:{endAdornment:(()=>{if(V){if(!v||!y)return;return i(l,{position:"end",children:i(p,{"aria-label":T?y:v,disabled:n,onClick:$,size:"small",tone:"neutral",variant:"tertiary",children:i(T?u:s,{})})})}if(a)return i(l,{position:"end",children:a})})(),startAdornment:(()=>{if(F)return i(l,{position:"start",children:F})})()},htmlInput:{"aria-describedby":C}},type:V?T?"text":"password":P,variant:"outlined",...I})]})};export{c as TextField,c as default};
1
+ import{jsxs as r,jsx as i}from"react/jsx-runtime";import{useState as e}from"react";import t from"@mui/material/Box";import o from"@mui/material/FormHelperText";import l from"@mui/material/InputAdornment";import d from"@mui/material/InputLabel";import{styled as n}from"@mui/material/styles";import a from"@mui/material/TextField";import m from"../../../icons/CancelCircle/index.js";import s from"../../../icons/View/index.js";import p from"../../../icons/ViewOff/index.js";import{IconButton as u}from"../IconButton/index.js";const f=n(t,{shouldForwardProp:r=>"fullWidth"!==r})((({theme:r,fullWidth:i=!1})=>({display:"flex",flexDirection:"column",gap:r.spacing(.5),width:i?"100%":"min(364px, 100%)"}))),h=n(a,{shouldForwardProp:r=>"fullWidth"!==r})((({fullWidth:r=!1})=>({display:"flex",width:r?"100%":"auto"}))),c=({disabled:n=!1,endAdornment:a,errorText:c,fdKey:x,fullWidth:b=!1,helperText:w,hidePasswordAriaLabel:y,label:A,multiline:P=!1,required:W=!1,showPasswordAriaLabel:j,startAdornment:v,type:F="text",...I})=>{const[T,g]=e(!1),q=w?`${x}-helper-text`:void 0,B=c?`${x}-error-message`:void 0,C=[q,B].filter(Boolean).join(" ")||void 0,L=!!c&&!n,V="password"===F,$=()=>g((r=>!r)),k=(()=>{if(V){if(!j||!y)return;return i(l,{position:"end",children:i(u,{"aria-label":T?y:j,disabled:n,onClick:$,size:"small",tone:"neutral",variant:"tertiary",children:i(T?p:s,{})})})}if(a)return i(l,{position:"end",children:a})})(),z=(()=>{if(v)return i(l,{position:"start",children:v})})();return r(f,{fullWidth:b,children:[r(t,{children:[A&&i(d,{disabled:n,htmlFor:x,required:W,children:A}),w&&i(o,{disabled:n,id:q,children:w})]}),L&&r(o,{error:!0,id:B,children:[i(m,{}),c]}),i(h,{"data-fd":x,disabled:n,error:L,fullWidth:b,id:x,label:"",multiline:P,required:W,slotProps:{input:{...I.slotProps?.input??{},...z&&{startAdornment:z},...k&&{endAdornment:k}},htmlInput:{...I.slotProps?.htmlInput??{},"aria-describedby":C}},type:V?T?"text":"password":F,variant:"outlined",...I})]})};export{c as TextField,c as default};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/TextField/index.tsx"],"sourcesContent":["import { type ReactNode, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport { styled } from '@mui/material/styles';\nimport MuiTextField, { type TextFieldProps as MuiTextFieldProps } from '@mui/material/TextField';\n\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\nimport ViewIcon from '@fd/icons/View';\nimport ViewOffIcon from '@fd/icons/ViewOff';\n\nimport IconButton from '../IconButton';\n\n// Common props for all TextField variants\ntype BaseTextFieldProps = Omit<MuiTextFieldProps, 'error' | 'id' | 'type' | 'variant'> & {\n endAdornment?: ReactNode;\n errorText?: string;\n fdKey: string;\n startAdornment?: ReactNode;\n};\n\n// Password TextField variant - requires aria labels\ntype PasswordTextFieldProps = BaseTextFieldProps & {\n type: 'password';\n hidePasswordAriaLabel: string;\n showPasswordAriaLabel: string;\n};\n\n// Generic TextField variant - for all other input types\ntype GenericTextFieldProps = BaseTextFieldProps & {\n type?: Exclude<MuiTextFieldProps['type'], 'password'>;\n hidePasswordAriaLabel?: never;\n showPasswordAriaLabel?: never;\n};\n\nexport type TextFieldProps = GenericTextFieldProps | PasswordTextFieldProps;\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain width to a maximum of 100% of the container width\n}));\n\nconst StyledTextField = styled(MuiTextField, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n}));\n\nexport const TextField = ({\n disabled = false,\n endAdornment = undefined,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n hidePasswordAriaLabel,\n label,\n multiline = false,\n required = false,\n showPasswordAriaLabel,\n startAdornment = undefined,\n type = 'text',\n ...props\n}: TextFieldProps): JSX.Element => {\n const [showPassword, setShowPassword] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const isPassword = type === 'password';\n\n const handleClickShowPassword = (): void => setShowPassword((show) => !show);\n\n const getFieldType = (): MuiTextFieldProps['type'] => {\n if (isPassword) {\n return showPassword ? 'text' : 'password';\n }\n\n return type;\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n if (isPassword) {\n if (!showPasswordAriaLabel || !hidePasswordAriaLabel) {\n return undefined;\n }\n\n return (\n <MuiInputAdornment position=\"end\">\n <IconButton\n aria-label={showPassword ? hidePasswordAriaLabel : showPasswordAriaLabel}\n disabled={disabled}\n onClick={handleClickShowPassword}\n size=\"small\"\n tone=\"neutral\"\n variant=\"tertiary\"\n >\n {showPassword ? <ViewOffIcon /> : <ViewIcon />}\n </IconButton>\n </MuiInputAdornment>\n );\n }\n if (endAdornment) {\n return <MuiInputAdornment position=\"end\">{endAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n const renderStartAdornment = (): React.ReactNode => {\n if (startAdornment) {\n return <MuiInputAdornment position=\"start\">{startAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledTextField\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n id={fdKey}\n label=\"\" // Remove label from TextField since we're rendering it separately\n multiline={multiline}\n required={required}\n slotProps={{\n input: {\n endAdornment: renderEndAdornment(),\n startAdornment: renderStartAdornment(),\n },\n htmlInput: {\n 'aria-describedby': ariaDescribedBy,\n },\n }}\n type={getFieldType()}\n variant=\"outlined\"\n {...props}\n />\n </StyledContainer>\n );\n};\n\nexport default TextField;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledTextField","MuiTextField","TextField","disabled","endAdornment","errorText","fdKey","helperText","hidePasswordAriaLabel","label","multiline","required","showPasswordAriaLabel","startAdornment","type","props","showPassword","setShowPassword","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","isPassword","handleClickShowPassword","show","_jsxs","_jsx","MuiInputLabel","htmlFor","children","MuiFormHelperText","id","error","CancelCircleIcon","slotProps","input","MuiInputAdornment","position","IconButton","onClick","size","tone","variant","ViewOffIcon","ViewIcon","renderEndAdornment","renderStartAdornment","htmlInput"],"mappings":"4gBAuCA,MAAMA,EAAkBC,EAAOC,EAAK,CAClCC,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGI,QAAOC,aAAY,MAAO,CACvDC,QAAS,OACTC,cAAe,SACfC,IAAKJ,EAAMK,QAAQ,IACnBC,MAAOL,EAAY,OAAS,uBAGxBM,EAAkBX,EAAOY,EAAc,CAC3CV,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGK,aAAY,MAAO,CAChDC,QAAS,OACTI,MAAOL,EAAY,OAAS,WAGjBQ,EAAY,EACvBC,YAAW,EACXC,eACAC,YACAC,QACAZ,aAAY,EACZa,aACAC,wBACAC,QACAC,aAAY,EACZC,YAAW,EACXC,wBACAC,iBACAC,OAAO,UACJC,MAEH,MAAOC,EAAcC,GAAmBC,GAAkB,GAEpDC,EAAeZ,EAAa,GAAGD,qBAAsBc,EACrDC,EAAiBhB,EAAY,GAAGC,uBAAwBc,EAGxDE,EAAkB,CAACH,EAAcE,GAAgBE,OAAOC,SAASC,KAAK,WAAQL,EAE9EM,IAAYrB,IAAcF,EAC1BwB,EAAsB,aAATb,EAEbc,EAA0B,IAAYX,GAAiBY,IAAUA,IA8CvE,OACEC,EAAC1C,EAAe,CAACM,UAAWA,YAC1BoC,EAACxC,aACEmB,GACCsB,EAACC,GAAc7B,SAAUA,EAAU8B,QAAS3B,EAAOK,SAAUA,EAAQuB,SAClEzB,IAIJF,GACCwB,EAACI,GAAkBhC,SAAUA,EAAUiC,GAAIjB,EAAYe,SACpD3B,OAKNmB,GACCI,EAACK,GAAkBE,OAAK,EAACD,GAAIf,YAC3BU,EAACO,MAEAjC,KAIL0B,EAAC/B,EAAe,CAAA,UACLM,EACTH,SAAUA,EACVkC,MAAOX,EACPhC,UAAWA,EACX0C,GAAI9B,EACJG,MAAM,GACNC,UAAWA,EACXC,SAAUA,EACV4B,UAAW,CACTC,MAAO,CACLpC,aAvEiB,MACzB,GAAIuB,EAAY,CACd,IAAKf,IAA0BJ,EAC7B,OAGF,OACEuB,EAACU,EAAiB,CAACC,SAAS,MAAKR,SAC/BH,EAACY,EAAU,CAAA,aACG3B,EAAeR,EAAwBI,EACnDT,SAAUA,EACVyC,QAAShB,EACTiB,KAAK,QACLC,KAAK,UACLC,QAAQ,WAAUb,SAEFH,EAAff,EAAgBgC,EAAkBC,EAAP,CAAA,MAIpC,CACA,GAAI7C,EACF,OAAO2B,EAACU,EAAiB,CAACC,SAAS,MAAKR,SAAE9B,KAiDtB8C,GACdrC,eA5CmB,MAC3B,GAAIA,EACF,OAAOkB,EAACU,EAAiB,CAACC,SAAS,QAAOR,SAAErB,KA0CtBsC,IAElBC,UAAW,CACT,mBAAoB9B,IAGxBR,KArFAa,EACKX,EAAe,OAAS,WAG1BF,EAkFHiC,QAAQ,cACJhC"}
1
+ {"version":3,"file":"index.js","sources":["../../../../src/components/atoms/TextField/index.tsx"],"sourcesContent":["import { type ReactNode, useState } from 'react';\n\nimport Box from '@mui/material/Box';\nimport MuiFormHelperText from '@mui/material/FormHelperText';\nimport MuiInputAdornment from '@mui/material/InputAdornment';\nimport MuiInputLabel from '@mui/material/InputLabel';\nimport { styled } from '@mui/material/styles';\nimport MuiTextField, { type TextFieldProps as MuiTextFieldProps } from '@mui/material/TextField';\n\nimport CancelCircleIcon from '@fd/icons/CancelCircle';\nimport ViewIcon from '@fd/icons/View';\nimport ViewOffIcon from '@fd/icons/ViewOff';\n\nimport IconButton from '../IconButton';\n\n// Common props for all TextField variants\ntype BaseTextFieldProps = Omit<MuiTextFieldProps, 'error' | 'id' | 'type' | 'variant'> & {\n endAdornment?: ReactNode;\n errorText?: string;\n fdKey: string;\n startAdornment?: ReactNode;\n};\n\n// Password TextField variant - requires aria labels\ntype PasswordTextFieldProps = BaseTextFieldProps & {\n type: 'password';\n hidePasswordAriaLabel: string;\n showPasswordAriaLabel: string;\n};\n\n// Generic TextField variant - for all other input types\ntype GenericTextFieldProps = BaseTextFieldProps & {\n type?: Exclude<MuiTextFieldProps['type'], 'password'>;\n hidePasswordAriaLabel?: never;\n showPasswordAriaLabel?: never;\n};\n\nexport type TextFieldProps = GenericTextFieldProps | PasswordTextFieldProps;\n\nconst StyledContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ theme, fullWidth = false }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n width: fullWidth ? '100%' : 'min(364px, 100%)', // Constrain width to a maximum of 100% of the container width\n}));\n\nconst StyledTextField = styled(MuiTextField, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n display: 'flex',\n width: fullWidth ? '100%' : 'auto',\n}));\n\nexport const TextField = ({\n disabled = false,\n endAdornment = undefined,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n hidePasswordAriaLabel,\n label,\n multiline = false,\n required = false,\n showPasswordAriaLabel,\n startAdornment = undefined,\n type = 'text',\n ...props\n}: TextFieldProps): JSX.Element => {\n const [showPassword, setShowPassword] = useState<boolean>(false);\n\n const helperTextId = helperText ? `${fdKey}-helper-text` : undefined;\n const errorMessageId = errorText ? `${fdKey}-error-message` : undefined;\n\n // Combine helper text and error message IDs for aria-describedby\n const ariaDescribedBy = [helperTextId, errorMessageId].filter(Boolean).join(' ') || undefined;\n\n const isError = !!errorText && !disabled;\n const isPassword = type === 'password';\n\n const handleClickShowPassword = (): void => setShowPassword((show) => !show);\n\n const getFieldType = (): MuiTextFieldProps['type'] => {\n if (isPassword) {\n return showPassword ? 'text' : 'password';\n }\n\n return type;\n };\n\n const renderEndAdornment = (): React.ReactNode => {\n if (isPassword) {\n if (!showPasswordAriaLabel || !hidePasswordAriaLabel) {\n return undefined;\n }\n\n return (\n <MuiInputAdornment position=\"end\">\n <IconButton\n aria-label={showPassword ? hidePasswordAriaLabel : showPasswordAriaLabel}\n disabled={disabled}\n onClick={handleClickShowPassword}\n size=\"small\"\n tone=\"neutral\"\n variant=\"tertiary\"\n >\n {showPassword ? <ViewOffIcon /> : <ViewIcon />}\n </IconButton>\n </MuiInputAdornment>\n );\n }\n if (endAdornment) {\n return <MuiInputAdornment position=\"end\">{endAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n const renderStartAdornment = (): React.ReactNode => {\n if (startAdornment) {\n return <MuiInputAdornment position=\"start\">{startAdornment}</MuiInputAdornment>;\n }\n\n return undefined;\n };\n\n const renderedEndAdornment = renderEndAdornment();\n const renderedStartAdornment = renderStartAdornment();\n\n return (\n <StyledContainer fullWidth={fullWidth}>\n <Box>\n {label && (\n <MuiInputLabel disabled={disabled} htmlFor={fdKey} required={required}>\n {label}\n </MuiInputLabel>\n )}\n\n {helperText && (\n <MuiFormHelperText disabled={disabled} id={helperTextId}>\n {helperText}\n </MuiFormHelperText>\n )}\n </Box>\n\n {isError && (\n <MuiFormHelperText error id={errorMessageId}>\n <CancelCircleIcon />\n\n {errorText}\n </MuiFormHelperText>\n )}\n\n <StyledTextField\n data-fd={fdKey}\n disabled={disabled}\n error={isError}\n fullWidth={fullWidth}\n id={fdKey}\n label=\"\" // Remove label from TextField since we're rendering it separately\n multiline={multiline}\n required={required}\n slotProps={{\n input: {\n ...(props.slotProps?.input ?? {}),\n // Only pass startAdornment and endAdornment if they are defined\n ...(renderedStartAdornment && { startAdornment: renderedStartAdornment }),\n ...(renderedEndAdornment && { endAdornment: renderedEndAdornment }),\n },\n htmlInput: {\n ...(props.slotProps?.htmlInput ?? {}),\n 'aria-describedby': ariaDescribedBy,\n },\n }}\n type={getFieldType()}\n variant=\"outlined\"\n {...props}\n />\n </StyledContainer>\n );\n};\n\nexport default TextField;\n"],"names":["StyledContainer","styled","Box","shouldForwardProp","prop","theme","fullWidth","display","flexDirection","gap","spacing","width","StyledTextField","MuiTextField","TextField","disabled","endAdornment","errorText","fdKey","helperText","hidePasswordAriaLabel","label","multiline","required","showPasswordAriaLabel","startAdornment","type","props","showPassword","setShowPassword","useState","helperTextId","undefined","errorMessageId","ariaDescribedBy","filter","Boolean","join","isError","isPassword","handleClickShowPassword","show","renderedEndAdornment","_jsx","MuiInputAdornment","position","children","IconButton","onClick","size","tone","variant","ViewOffIcon","ViewIcon","renderEndAdornment","renderedStartAdornment","renderStartAdornment","_jsxs","MuiInputLabel","htmlFor","MuiFormHelperText","id","error","CancelCircleIcon","slotProps","input","htmlInput"],"mappings":"4gBAuCA,MAAMA,EAAkBC,EAAOC,EAAK,CAClCC,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGI,QAAOC,aAAY,MAAO,CACvDC,QAAS,OACTC,cAAe,SACfC,IAAKJ,EAAMK,QAAQ,IACnBC,MAAOL,EAAY,OAAS,uBAGxBM,EAAkBX,EAAOY,EAAc,CAC3CV,kBAAoBC,GAAkB,cAATA,GADPH,EAEI,EAAGK,aAAY,MAAO,CAChDC,QAAS,OACTI,MAAOL,EAAY,OAAS,WAGjBQ,EAAY,EACvBC,YAAW,EACXC,eACAC,YACAC,QACAZ,aAAY,EACZa,aACAC,wBACAC,QACAC,aAAY,EACZC,YAAW,EACXC,wBACAC,iBACAC,OAAO,UACJC,MAEH,MAAOC,EAAcC,GAAmBC,GAAkB,GAEpDC,EAAeZ,EAAa,GAAGD,qBAAsBc,EACrDC,EAAiBhB,EAAY,GAAGC,uBAAwBc,EAGxDE,EAAkB,CAACH,EAAcE,GAAgBE,OAAOC,SAASC,KAAK,WAAQL,EAE9EM,IAAYrB,IAAcF,EAC1BwB,EAAsB,aAATb,EAEbc,EAA0B,IAAYX,GAAiBY,IAAUA,IA8CjEC,EApCqB,MACzB,GAAIH,EAAY,CACd,IAAKf,IAA0BJ,EAC7B,OAGF,OACEuB,EAACC,EAAiB,CAACC,SAAS,MAAKC,SAC/BH,EAACI,EAAU,CAAA,aACGnB,EAAeR,EAAwBI,EACnDT,SAAUA,EACViC,QAASR,EACTS,KAAK,QACLC,KAAK,UACLC,QAAQ,WAAUL,SAEFH,EAAff,EAAgBwB,EAAkBC,EAAP,CAAA,MAIpC,CACA,GAAIrC,EACF,OAAO2B,EAACC,EAAiB,CAACC,SAAS,MAAKC,SAAE9B,KAcjBsC,GACvBC,EATuB,MAC3B,GAAI9B,EACF,OAAOkB,EAACC,EAAiB,CAACC,SAAS,QAAOC,SAAErB,KAOjB+B,GAE/B,OACEC,EAACzD,EAAe,CAACM,UAAWA,YAC1BmD,EAACvD,aACEmB,GACCsB,EAACe,GAAc3C,SAAUA,EAAU4C,QAASzC,EAAOK,SAAUA,EAAQuB,SAClEzB,IAIJF,GACCwB,EAACiB,GAAkB7C,SAAUA,EAAU8C,GAAI9B,EAAYe,SACpD3B,OAKNmB,GACCmB,EAACG,GAAkBE,OAAK,EAACD,GAAI5B,YAC3BU,EAACoB,MAEA9C,KAIL0B,EAAC/B,EAAe,CAAA,UACLM,EACTH,SAAUA,EACV+C,MAAOxB,EACPhC,UAAWA,EACXuD,GAAI3C,EACJG,MAAM,GACNC,UAAWA,EACXC,SAAUA,EACVyC,UAAW,CACTC,MAAO,IACDtC,EAAMqC,WAAWC,OAAS,MAE1BV,GAA0B,CAAE9B,eAAgB8B,MAC5Cb,GAAwB,CAAE1B,aAAc0B,IAE9CwB,UAAW,IACLvC,EAAMqC,WAAWE,WAAa,GAClC,mBAAoBhC,IAGxBR,KA3FAa,EACKX,EAAe,OAAS,WAG1BF,EAwFHyB,QAAQ,cACJxB"}
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("react");exports.useDynamicLimitTags=function(t){const{chipMax:r=130,gap:n=4,horizontalPadding:s=32,reservedPx:a=0}=t??{},i=e.useRef(null),[o,c]=e.useState(1);return e.useLayoutEffect((()=>{const e=i.current;if(!e)return;const t=()=>{const t=e.clientWidth,i=Math.max(0,t-s-a),o=r+n,u=Math.max(1,Math.floor(i/o));c(u)};t();const o=new ResizeObserver(t);return o.observe(e),()=>o.disconnect()}),[r,n,s,a]),{rootRef:i,limitTags:o}};
2
+ //# sourceMappingURL=useDynamicLimitTags.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDynamicLimitTags.cjs.js","sources":["../../../../../src/components/molecules/Autocomplete/hooks/useDynamicLimitTags.ts"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from 'react';\n\nexport interface UseDynamicLimitTagsProps {\n chipMax?: number; // px\n gap?: number; // px, matches theme gap between tags\n horizontalPadding?: number; // px, inputRoot left+right padding\n reservedPx?: number; // px, start/end adornments (icons) and search input width you want to reserve\n}\n\nexport interface UseDynamicLimitTagsReturn {\n rootRef: React.RefObject<HTMLDivElement | null>;\n limitTags: number;\n}\n\nexport function useDynamicLimitTags(props?: UseDynamicLimitTagsProps): UseDynamicLimitTagsReturn {\n const {\n chipMax = 130,\n gap = 4,\n horizontalPadding = 32, // matches padding: theme.spacing(0.5, 2) → 16px each side\n reservedPx = 0, // tweak if you have more adornments or larger search input\n } = props ?? {};\n\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [limitTags, setLimitTags] = useState<number>(1);\n\n useLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n\n const update = (): void => {\n const width = el.clientWidth;\n const usable = Math.max(0, width - horizontalPadding - reservedPx);\n const perChip = chipMax + gap;\n const count = Math.max(1, Math.floor(usable / perChip));\n setLimitTags(count);\n };\n\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return (): void => ro.disconnect();\n }, [chipMax, gap, horizontalPadding, reservedPx]);\n\n return { rootRef, limitTags };\n}\n"],"names":["props","chipMax","gap","horizontalPadding","reservedPx","rootRef","useRef","limitTags","setLimitTags","useState","useLayoutEffect","el","current","update","width","clientWidth","usable","Math","max","perChip","count","floor","ro","ResizeObserver","observe","disconnect"],"mappings":"gEAcM,SAA8BA,GAClC,MAAMC,QACJA,EAAU,IAAGC,IACbA,EAAM,EAACC,kBACPA,EAAoB,GAAEC,WACtBA,EAAa,GACXJ,GAAS,CAAA,EAEPK,EAAUC,EAAAA,OAA8B,OACvCC,EAAWC,GAAgBC,EAAAA,SAAiB,GAoBnD,OAlBAC,EAAAA,iBAAgB,KACd,MAAMC,EAAKN,EAAQO,QACnB,IAAKD,EAAI,OAET,MAAME,EAAS,KACb,MAAMC,EAAQH,EAAGI,YACXC,EAASC,KAAKC,IAAI,EAAGJ,EAAQX,EAAoBC,GACjDe,EAAUlB,EAAUC,EACpBkB,EAAQH,KAAKC,IAAI,EAAGD,KAAKI,MAAML,EAASG,IAC9CX,EAAaY,IAGfP,IACA,MAAMS,EAAK,IAAIC,eAAeV,GAE9B,OADAS,EAAGE,QAAQb,GACJ,IAAYW,EAAGG,eACrB,CAACxB,EAASC,EAAKC,EAAmBC,IAE9B,CAAEC,UAASE,YACpB"}
@@ -0,0 +1,14 @@
1
+ interface UseDynamicLimitTagsProps {
2
+ chipMax?: number;
3
+ gap?: number;
4
+ horizontalPadding?: number;
5
+ reservedPx?: number;
6
+ }
7
+ interface UseDynamicLimitTagsReturn {
8
+ rootRef: React.RefObject<HTMLDivElement | null>;
9
+ limitTags: number;
10
+ }
11
+ declare function useDynamicLimitTags(props?: UseDynamicLimitTagsProps): UseDynamicLimitTagsReturn;
12
+
13
+ export { useDynamicLimitTags };
14
+ export type { UseDynamicLimitTagsProps, UseDynamicLimitTagsReturn };
@@ -0,0 +1,2 @@
1
+ import{useRef as t,useState as r,useLayoutEffect as e}from"react";function n(n){const{chipMax:o=130,gap:c=4,horizontalPadding:i=32,reservedPx:a=0}=n??{},s=t(null),[h,l]=r(1);return e((()=>{const t=s.current;if(!t)return;const r=()=>{const r=t.clientWidth,e=Math.max(0,r-i-a),n=o+c,s=Math.max(1,Math.floor(e/n));l(s)};r();const e=new ResizeObserver(r);return e.observe(t),()=>e.disconnect()}),[o,c,i,a]),{rootRef:s,limitTags:h}}export{n as useDynamicLimitTags};
2
+ //# sourceMappingURL=useDynamicLimitTags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDynamicLimitTags.js","sources":["../../../../../src/components/molecules/Autocomplete/hooks/useDynamicLimitTags.ts"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from 'react';\n\nexport interface UseDynamicLimitTagsProps {\n chipMax?: number; // px\n gap?: number; // px, matches theme gap between tags\n horizontalPadding?: number; // px, inputRoot left+right padding\n reservedPx?: number; // px, start/end adornments (icons) and search input width you want to reserve\n}\n\nexport interface UseDynamicLimitTagsReturn {\n rootRef: React.RefObject<HTMLDivElement | null>;\n limitTags: number;\n}\n\nexport function useDynamicLimitTags(props?: UseDynamicLimitTagsProps): UseDynamicLimitTagsReturn {\n const {\n chipMax = 130,\n gap = 4,\n horizontalPadding = 32, // matches padding: theme.spacing(0.5, 2) → 16px each side\n reservedPx = 0, // tweak if you have more adornments or larger search input\n } = props ?? {};\n\n const rootRef = useRef<HTMLDivElement | null>(null);\n const [limitTags, setLimitTags] = useState<number>(1);\n\n useLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n\n const update = (): void => {\n const width = el.clientWidth;\n const usable = Math.max(0, width - horizontalPadding - reservedPx);\n const perChip = chipMax + gap;\n const count = Math.max(1, Math.floor(usable / perChip));\n setLimitTags(count);\n };\n\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return (): void => ro.disconnect();\n }, [chipMax, gap, horizontalPadding, reservedPx]);\n\n return { rootRef, limitTags };\n}\n"],"names":["useDynamicLimitTags","props","chipMax","gap","horizontalPadding","reservedPx","rootRef","useRef","limitTags","setLimitTags","useState","useLayoutEffect","el","current","update","width","clientWidth","usable","Math","max","perChip","count","floor","ro","ResizeObserver","observe","disconnect"],"mappings":"kEAcM,SAAUA,EAAoBC,GAClC,MAAMC,QACJA,EAAU,IAAGC,IACbA,EAAM,EAACC,kBACPA,EAAoB,GAAEC,WACtBA,EAAa,GACXJ,GAAS,CAAA,EAEPK,EAAUC,EAA8B,OACvCC,EAAWC,GAAgBC,EAAiB,GAoBnD,OAlBAC,GAAgB,KACd,MAAMC,EAAKN,EAAQO,QACnB,IAAKD,EAAI,OAET,MAAME,EAAS,KACb,MAAMC,EAAQH,EAAGI,YACXC,EAASC,KAAKC,IAAI,EAAGJ,EAAQX,EAAoBC,GACjDe,EAAUlB,EAAUC,EACpBkB,EAAQH,KAAKC,IAAI,EAAGD,KAAKI,MAAML,EAASG,IAC9CX,EAAaY,IAGfP,IACA,MAAMS,EAAK,IAAIC,eAAeV,GAE9B,OADAS,EAAGE,QAAQb,GACJ,IAAYW,EAAGG,eACrB,CAACxB,EAASC,EAAKC,EAAmBC,IAE9B,CAAEC,UAASE,YACpB"}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("@mui/material/Autocomplete");module.exports=e;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react/jsx-runtime"),i=require("@mui/material/Autocomplete"),l=require("@mui/material/Box"),n=require("@mui/material/styles"),r=require("@mui/material/Tooltip"),s=require("../../../icons/ArrowDown01/index.cjs.js"),a=require("../../../icons/ArrowUp01/index.cjs.js"),o=require("../../../icons/Cancel/index.cjs.js"),d=require("../../../icons/Search/index.cjs.js"),c=require("../../../utilities/stringUtilities.cjs.js"),p=require("../../atoms/Badge/index.cjs.js"),u=require("../../atoms/CircularProgress/index.cjs.js"),m=require("../../atoms/MenuItem/index.cjs.js"),g=require("../../atoms/TextField/index.cjs.js"),x=require("./hooks/useDynamicLimitTags.cjs.js");const h=i,j=n.styled(h,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({width:e?"100%":"min(364px, 100%)"}))),b=n.styled(l,{shouldForwardProp:e=>!["clickable","disabled","placement"].includes(e)})((({theme:e,clickable:t=!1,disabled:i=!1,placement:l})=>({alignItems:"center",cursor:t?i?"not-allowed":"pointer":"default",display:"flex",justifyContent:"center",padding:0,pointerEvents:t?"auto":"none",..."start"===l&&{paddingRight:e.spacing(1)},..."middle"===l&&{padding:e.spacing(0,1)},"& svg":{color:i?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),y=n.styled(l,{shouldForwardProp:e=>"placement"!==e})((({theme:e,placement:t})=>({alignItems:"center",display:"flex",justifyContent:"center",padding:0,..."start"===t&&{paddingRight:e.spacing(1)},..."middle"===t&&{padding:e.spacing(0,1)}}))),f=({disabled:i=!1,errorText:l,fdKey:n,fullWidth:h=!1,helperText:f,label:T,loading:q=!1,multiple:C=!1,placeholder:I,onChange:P,onInputChange:k,options:v=[],required:A=!1,translations:O,type:w="search",value:E})=>{const[F,W]=e.useState(!1),D="search"===w,L="combobox"===w,{rootRef:S,limitTags:M}=x.useDynamicLimitTags({chipMax:130,gap:4,horizontalPadding:32,reservedPx:D?120:90});e.useEffect((()=>{i&&W(!1)}),[i]);const B=e=>{i||W(void 0===e?e=>!e:e)};return t.jsx(j,{ref:S,clearIcon:t.jsx(o,{size:"md"}),clearText:O.clearTextAriaLabel,disableClearable:i||q,disableCloseOnSelect:C,disabled:i,filterOptions:D?e=>e:void 0,forcePopupIcon:L,freeSolo:D,fullWidth:h,getOptionKey:e=>"string"==typeof e?e:String(e.value),getOptionLabel:e=>"string"==typeof e?e:e.label,isOptionEqualToValue:(e,t)=>null!=t&&("string"==typeof t?e.label===t||String(e.value)===t:e.value===t.value),limitTags:M,loading:q,loadingText:O.loadingText,multiple:C,noOptionsText:O.noOptionsText,onChange:(e,t,i,l)=>{P&&P(e,t,i,l)},onClose:()=>B(!1),onInputChange:(e,t,i)=>{k&&k(e,t,i)},onOpen:()=>B(!0),open:F,openText:O.openPopupAriaLabel,options:v,popupIcon:D?null:t.jsx(b,{clickable:!0,disabled:i,placement:"end",children:F?t.jsx(a,{}):t.jsx(s,{})}),renderInput:e=>t.jsx(g.TextField,{disabled:i,errorText:l,fdKey:n,fullWidth:h,helperText:f,label:T,placeholder:I,required:A,slotProps:{input:{...e.InputProps,endAdornment:t.jsxs(t.Fragment,{children:[q?t.jsx(y,{placement:D?"end":"middle",children:t.jsx(u.CircularProgress,{size:"small"})}):null,e.InputProps.endAdornment]}),startAdornment:t.jsxs(t.Fragment,{children:[D?t.jsx(b,{disabled:i,placement:"start",children:t.jsx(d,{"aria-hidden":"true"})}):null,e.InputProps.startAdornment]})},htmlInput:{...e.inputProps}}}),renderOption:(t,i,l)=>{const{key:n,onClick:r,...s}=t;return C?e.createElement(m.MenuItem,{...s,key:n,checked:l.selected,label:i.label,onCheckedChange:(e,t)=>{r?.(t)},type:"checkbox"}):e.createElement(m.MenuItem,{...s,key:n,label:i.label,onClick:r,selected:l.selected,type:"text"})},renderTags:(e,i)=>e.map(((e,l)=>{const{key:n,onDelete:s,...a}=i({index:l}),o="string"==typeof e?e:e.label,d=c.truncateWithEllipsis(o,13,{includeEllipsisInLimit:!0}),u=d.endsWith("..."),m=n??`tag-${"string"==typeof e?e:e.value}`;return u?t.jsx(r,{arrow:!0,placement:"top",title:o,children:t.jsx("span",{...a,children:t.jsx(p.Badge,{label:d,onDismiss:s})})},m):t.jsx("span",{...a,children:t.jsx(p.Badge,{label:d,onDismiss:s})},m)})),slotProps:{popupIndicator:{onClick:e=>{i||(e.stopPropagation(),B())}}},value:C?Array.isArray(E)?E:null==E?[]:[E]:Array.isArray(E)?E.length>0?E[0]:null:E??null})};exports.Autocomplete=f,exports.default=f;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Autocomplete/index.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport MuiAutocomplete, {\n type AutocompleteChangeDetails,\n type AutocompleteChangeReason,\n type AutocompleteInputChangeReason,\n type AutocompleteProps as MuiAutocompleteProps,\n type AutocompleteRenderGetTagProps,\n type AutocompleteRenderInputParams,\n type AutocompleteRenderOptionState,\n type AutocompleteValue,\n} from '@mui/material/Autocomplete';\nimport Box from '@mui/material/Box';\nimport { styled } from '@mui/material/styles';\n// TODO: Replace with our own Tooltip component\nimport MuiTooltip from '@mui/material/Tooltip';\n\nimport ArrowDown01Icon from '@fd/icons/ArrowDown01';\nimport ArrowUp01Icon from '@fd/icons/ArrowUp01';\nimport CancelIcon from '@fd/icons/Cancel';\nimport SearchIcon from '@fd/icons/Search';\nimport { truncateWithEllipsis } from '@fd/utilities/stringUtilities';\n\n// TODO: Replace with our own Tag component\nimport Badge from '../../atoms/Badge';\nimport CircularProgress from '../../atoms/CircularProgress';\nimport MenuItem from '../../atoms/MenuItem';\nimport TextField, { type TextFieldProps } from '../../atoms/TextField';\nimport { useDynamicLimitTags } from './hooks/useDynamicLimitTags';\n\n// Bind flags to MuiAutocomplete\ntype MuiCustomAutocompleteProps<\n M extends boolean = boolean, // Multiple\n DC extends boolean = boolean, // DisableClearable\n FS extends boolean = boolean, // FreeSolo\n> = MuiAutocompleteProps<AutocompleteOption, M, DC, FS>;\n\n/**\n * Represents an option in the Autocomplete dropdown.\n */\nexport interface AutocompleteOption {\n label: string;\n value: number | string;\n}\n\n/**\n * Props for the Autocomplete component.\n * Supports both single and multiple selection modes with optional search functionality.\n */\nexport interface AutocompleteProps\n extends Omit<TextFieldProps, 'endAdornment' | 'multiline' | 'onChange' | 'options' | 'startAdornment'> {\n /** Shows a loading indicator inside the input (e.g., while fetching). */\n loading?: boolean;\n /** Enables selection of multiple options and shows checkboxes and tags for selected values. */\n multiple?: MuiCustomAutocompleteProps['multiple'];\n /** Called when the selected value(s) change. */\n onChange: MuiCustomAutocompleteProps['onChange'];\n /** Called when the input text changes (typing or programmatic updates). */\n onInputChange?: MuiCustomAutocompleteProps['onInputChange'];\n /** Options to display in the dropdown list. */\n options: AutocompleteOption[];\n /** UI and accessibility labels used by the component. */\n translations: {\n /** Aria-label for the clear button. */\n clearTextAriaLabel: string;\n /** Text shown while loading options. */\n loadingText: string;\n /** Text shown when there are no options to display. */\n noOptionsText: string;\n /** Aria-label for the popup indicator button. */\n openPopupAriaLabel: string;\n };\n /** Visual behavior: 'search' shows a leading search icon; 'combobox' shows a popup button. */\n type?: 'combobox' | 'search';\n /** Controlled value (single option, array for multiple, or null). */\n value: MuiCustomAutocompleteProps['value'];\n}\n\n// Bind flags to MuiAutocomplete, see MuiCustomAutocompleteProps for more details\nconst MuiCustomAutocomplete = MuiAutocomplete<AutocompleteOption, boolean, boolean, boolean>;\nconst StyledAutocomplete = styled(MuiCustomAutocomplete, {\n shouldForwardProp: (prop) => prop !== 'fullWidth',\n})<{ fullWidth?: boolean }>(({ fullWidth = false }) => ({\n width: fullWidth ? '100%' : 'min(364px, 100%)',\n}));\n\nconst StyledAdornment = styled(Box, {\n shouldForwardProp: (prop) => !['clickable', 'disabled', 'placement'].includes(prop as string),\n})<{ clickable?: boolean; error?: boolean; disabled?: boolean; placement: 'end' | 'middle' | 'start' }>(\n ({ theme, clickable = false, disabled = false, placement }) => ({\n alignItems: 'center',\n cursor: clickable ? (disabled ? 'not-allowed' : 'pointer') : 'default',\n display: 'flex',\n justifyContent: 'center',\n padding: 0,\n pointerEvents: clickable ? 'auto' : 'none',\n\n ...(placement === 'start' && { paddingRight: theme.spacing(1) }),\n ...(placement === 'middle' && { padding: theme.spacing(0, 1) }),\n\n '& svg': {\n color: disabled\n ? theme.palette.semantic.icon['icon-disabled']\n : theme.palette.semantic.icon['icon-strong'],\n },\n }),\n);\n\nconst StyledLoadingSpinnerContainer = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'placement',\n})<{ placement?: 'end' | 'middle' | 'start' }>(({ theme, placement }) => ({\n alignItems: 'center',\n display: 'flex',\n justifyContent: 'center',\n padding: 0,\n\n ...(placement === 'start' && { paddingRight: theme.spacing(1) }),\n ...(placement === 'middle' && { padding: theme.spacing(0, 1) }),\n}));\n\n/**\n * A customizable Autocomplete component supporting search and combobox modes.\n * Supports single and multiple selection with dynamic tag rendering and optional loading states.\n *\n * @param props - The component props\n * @returns The rendered Autocomplete component\n */\nexport const Autocomplete = ({\n disabled = false,\n errorText,\n fdKey,\n fullWidth = false,\n helperText,\n label,\n loading = false,\n multiple = false,\n placeholder,\n onChange,\n onInputChange,\n options = [],\n required = false,\n translations,\n type = 'search',\n value,\n}: AutocompleteProps): JSX.Element => {\n const [isOpen, setIsOpen] = useState<boolean>(false);\n\n const isSearch = type === 'search';\n const isCombobox = type === 'combobox';\n\n const { rootRef, limitTags } = useDynamicLimitTags({\n chipMax: 130,\n gap: 4,\n horizontalPadding: 32,\n reservedPx: isSearch ? 120 : 90,\n });\n\n // Close the dropdown (if open) when the component is dynamically disabled\n useEffect(() => {\n if (disabled) {\n setIsOpen(false);\n }\n }, [disabled]);\n\n /**\n * Toggles or sets the dropdown open state.\n * Does nothing when the component is disabled.\n *\n * @param open - Optional boolean to explicitly set open state; if undefined, toggles current state\n */\n const toggleOpen = (open?: boolean): void => {\n if (disabled) {\n return;\n }\n\n if (open !== undefined) {\n setIsOpen(open);\n return;\n }\n\n setIsOpen((prevOpen) => !prevOpen);\n };\n\n const renderSearchIcon = (): JSX.Element => {\n return (\n <StyledAdornment disabled={disabled} placement=\"start\">\n <SearchIcon aria-hidden=\"true\" />\n </StyledAdornment>\n );\n };\n\n const renderPopupIcon = (): JSX.Element => {\n return (\n <StyledAdornment clickable disabled={disabled} placement=\"end\">\n {isOpen ? <ArrowUp01Icon /> : <ArrowDown01Icon />}\n </StyledAdornment>\n );\n };\n\n const renderLoadingSpinner = (): JSX.Element => {\n return (\n <StyledLoadingSpinnerContainer placement={isSearch ? 'end' : 'middle'}>\n <CircularProgress size=\"small\" />\n </StyledLoadingSpinnerContainer>\n );\n };\n\n const renderInputField = (params: AutocompleteRenderInputParams): JSX.Element => (\n <TextField\n disabled={disabled}\n errorText={errorText}\n fdKey={fdKey}\n fullWidth={fullWidth}\n helperText={helperText}\n label={label}\n placeholder={placeholder}\n required={required}\n slotProps={{\n input: {\n ...params.InputProps,\n endAdornment: (\n <>\n {loading ? renderLoadingSpinner() : null}\n {params.InputProps.endAdornment}\n </>\n ),\n startAdornment: (\n <>\n {isSearch ? renderSearchIcon() : null}\n {params.InputProps.startAdornment}\n </>\n ),\n },\n htmlInput: {\n ...params.inputProps,\n },\n }}\n />\n );\n\n const renderMenuOption = (\n optionProps: React.HTMLAttributes<HTMLLIElement> & { key: React.Key },\n option: AutocompleteOption,\n state: AutocompleteRenderOptionState,\n ): JSX.Element => {\n const { key, onClick, ...rest } = optionProps;\n\n if (multiple) {\n return (\n <MenuItem\n {...rest}\n key={key}\n checked={state.selected}\n label={option.label}\n onCheckedChange={(_checked, e) => {\n onClick?.(e as React.MouseEvent<HTMLLIElement, MouseEvent>);\n }}\n type=\"checkbox\"\n />\n );\n }\n\n return (\n <MenuItem\n {...rest}\n key={key}\n label={option.label}\n onClick={onClick}\n selected={state.selected}\n type=\"text\"\n />\n );\n };\n\n const renderSelectedTags = (\n selected: AutocompleteOption[],\n getTagProps: AutocompleteRenderGetTagProps,\n ): React.ReactNode =>\n selected.map((tag, index) => {\n const { key, onDelete, ...tagProps } = getTagProps({ index });\n const rawLabel = typeof tag === 'string' ? tag : tag.label;\n const label = truncateWithEllipsis(rawLabel, 13, { includeEllipsisInLimit: true });\n const isTruncated = label.endsWith('...');\n const tagKey = key ?? `tag-${typeof tag === 'string' ? tag : tag.value}`;\n\n if (isTruncated) {\n return (\n <MuiTooltip key={tagKey} arrow placement=\"top\" title={rawLabel}>\n <span {...tagProps}>\n <Badge label={label} onDismiss={onDelete} />\n </span>\n </MuiTooltip>\n );\n }\n\n return (\n <span key={tagKey} {...tagProps}>\n <Badge label={label} onDismiss={onDelete} />\n </span>\n );\n });\n\n const handlePopupIndicatorClick = (event: React.MouseEvent): void => {\n if (disabled) {\n return;\n }\n\n event.stopPropagation();\n toggleOpen();\n };\n\n const handleChange = (\n event: React.SyntheticEvent,\n value: AutocompleteValue<AutocompleteOption, boolean, boolean, boolean>,\n reason: AutocompleteChangeReason,\n details?: AutocompleteChangeDetails<AutocompleteOption>,\n ): void => {\n if (!onChange) {\n return;\n }\n onChange(event, value, reason, details);\n };\n\n const handleInputChange = (\n event: React.SyntheticEvent,\n value: string,\n reason: AutocompleteInputChangeReason,\n ): void => {\n if (!onInputChange) {\n return;\n }\n onInputChange(event, value, reason);\n };\n\n /**\n * Returns all options without filtering for search mode.\n * Disables MUI's built-in client-side filtering when type is 'search'.\n */\n const disableClientFilter = (opts: AutocompleteOption[]): AutocompleteOption[] => opts;\n\n /**\n * Extracts the display label from an option.\n * Supports both object options and freeSolo string values.\n */\n const getOptionLabel = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : option.label;\n };\n\n /**\n * Provides a stable unique key for each option to optimize DOM reconciliation.\n */\n const getOptionKey = (option: AutocompleteOption | string): string => {\n return typeof option === 'string' ? option : String(option.value);\n };\n\n /**\n * Determines equality between an option and the current value.\n * Handles both freeSolo string values and object options to prevent selection glitches.\n */\n const getIsOptionEqualToValue = (a: AutocompleteOption, b: AutocompleteOption): boolean => {\n if (b === null || b === undefined) {\n return false;\n }\n return typeof b === 'string' ? a.label === b || String(a.value) === b : a.value === b.value;\n };\n\n /**\n * Normalizes the value prop for MUI Autocomplete.\n * Handles both single and multiple selection modes, ensuring the value\n * format matches the mode (array for multiple, single value/null for single).\n *\n * @returns Normalized value compatible with MUI Autocomplete\n */\n const getValue = (): AutocompleteProps['value'] => {\n // Multiple value selection\n if (multiple) {\n if (Array.isArray(value)) return value;\n if (value === null || value === undefined) return [];\n return [value as AutocompleteOption];\n }\n\n // Single value selection\n if (Array.isArray(value)) return value.length > 0 ? value[0] : null;\n return value ?? null;\n };\n\n return (\n <StyledAutocomplete\n ref={rootRef}\n clearIcon={<CancelIcon size=\"md\" />}\n clearText={translations.clearTextAriaLabel}\n disableClearable={disabled || loading}\n disableCloseOnSelect={multiple}\n disabled={disabled}\n filterOptions={isSearch ? disableClientFilter : undefined}\n forcePopupIcon={isCombobox}\n freeSolo={isSearch}\n fullWidth={fullWidth}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n isOptionEqualToValue={getIsOptionEqualToValue}\n limitTags={limitTags}\n loading={loading}\n loadingText={translations.loadingText}\n multiple={multiple}\n noOptionsText={translations.noOptionsText}\n onChange={handleChange}\n onClose={() => toggleOpen(false)}\n onInputChange={handleInputChange}\n onOpen={() => toggleOpen(true)}\n open={isOpen}\n openText={translations.openPopupAriaLabel}\n options={options}\n popupIcon={isSearch ? null : renderPopupIcon()}\n renderInput={renderInputField}\n renderOption={renderMenuOption}\n renderTags={renderSelectedTags}\n slotProps={{\n popupIndicator: {\n onClick: handlePopupIndicatorClick,\n },\n }}\n value={getValue()}\n />\n );\n};\n\nexport default Autocomplete;\n"],"names":["MuiCustomAutocomplete","StyledAutocomplete","styled","shouldForwardProp","prop","fullWidth","width","StyledAdornment","Box","includes","theme","clickable","disabled","placement","alignItems","cursor","display","justifyContent","padding","pointerEvents","paddingRight","spacing","color","palette","semantic","icon","StyledLoadingSpinnerContainer","Autocomplete","errorText","fdKey","helperText","label","loading","multiple","placeholder","onChange","onInputChange","options","required","translations","type","value","isOpen","setIsOpen","useState","isSearch","isCombobox","rootRef","limitTags","useDynamicLimitTags","chipMax","gap","horizontalPadding","reservedPx","useEffect","toggleOpen","open","undefined","prevOpen","_jsx","ref","clearIcon","CancelIcon","size","clearText","clearTextAriaLabel","disableClearable","disableCloseOnSelect","filterOptions","opts","forcePopupIcon","freeSolo","getOptionKey","option","String","getOptionLabel","isOptionEqualToValue","a","b","loadingText","noOptionsText","event","reason","details","onClose","onOpen","openText","openPopupAriaLabel","popupIcon","children","ArrowUp01Icon","ArrowDown01Icon","renderInput","params","TextField","slotProps","input","InputProps","endAdornment","_jsxs","_Fragment","CircularProgress","startAdornment","SearchIcon","htmlInput","inputProps","renderOption","optionProps","state","key","onClick","rest","_createElement","MenuItem","checked","selected","onCheckedChange","_checked","e","renderTags","getTagProps","map","tag","index","onDelete","tagProps","rawLabel","truncateWithEllipsis","includeEllipsisInLimit","isTruncated","endsWith","tagKey","MuiTooltip","arrow","title","Badge","onDismiss","popupIndicator","stopPropagation","Array","isArray","length"],"mappings":"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"}
@@ -1,2 +1,55 @@
1
- import Autocomplete from '@mui/material/Autocomplete';
2
- export { AutocompleteInputChangeReason, default } from '@mui/material/Autocomplete';
1
+ import { AutocompleteProps as AutocompleteProps$1 } from '@mui/material/Autocomplete';
2
+ import { TextFieldProps } from '../../atoms/TextField/index.js';
3
+
4
+ type MuiCustomAutocompleteProps<M extends boolean = boolean, // Multiple
5
+ DC extends boolean = boolean, // DisableClearable
6
+ FS extends boolean = boolean> = AutocompleteProps$1<AutocompleteOption, M, DC, FS>;
7
+ /**
8
+ * Represents an option in the Autocomplete dropdown.
9
+ */
10
+ interface AutocompleteOption {
11
+ label: string;
12
+ value: number | string;
13
+ }
14
+ /**
15
+ * Props for the Autocomplete component.
16
+ * Supports both single and multiple selection modes with optional search functionality.
17
+ */
18
+ interface AutocompleteProps extends Omit<TextFieldProps, 'endAdornment' | 'multiline' | 'onChange' | 'options' | 'startAdornment'> {
19
+ /** Shows a loading indicator inside the input (e.g., while fetching). */
20
+ loading?: boolean;
21
+ /** Enables selection of multiple options and shows checkboxes and tags for selected values. */
22
+ multiple?: MuiCustomAutocompleteProps['multiple'];
23
+ /** Called when the selected value(s) change. */
24
+ onChange: MuiCustomAutocompleteProps['onChange'];
25
+ /** Called when the input text changes (typing or programmatic updates). */
26
+ onInputChange?: MuiCustomAutocompleteProps['onInputChange'];
27
+ /** Options to display in the dropdown list. */
28
+ options: AutocompleteOption[];
29
+ /** UI and accessibility labels used by the component. */
30
+ translations: {
31
+ /** Aria-label for the clear button. */
32
+ clearTextAriaLabel: string;
33
+ /** Text shown while loading options. */
34
+ loadingText: string;
35
+ /** Text shown when there are no options to display. */
36
+ noOptionsText: string;
37
+ /** Aria-label for the popup indicator button. */
38
+ openPopupAriaLabel: string;
39
+ };
40
+ /** Visual behavior: 'search' shows a leading search icon; 'combobox' shows a popup button. */
41
+ type?: 'combobox' | 'search';
42
+ /** Controlled value (single option, array for multiple, or null). */
43
+ value: MuiCustomAutocompleteProps['value'];
44
+ }
45
+ /**
46
+ * A customizable Autocomplete component supporting search and combobox modes.
47
+ * Supports single and multiple selection with dynamic tag rendering and optional loading states.
48
+ *
49
+ * @param props - The component props
50
+ * @returns The rendered Autocomplete component
51
+ */
52
+ declare const Autocomplete: ({ disabled, errorText, fdKey, fullWidth, helperText, label, loading, multiple, placeholder, onChange, onInputChange, options, required, translations, type, value, }: AutocompleteProps) => JSX.Element;
53
+
54
+ export { Autocomplete, Autocomplete as default };
55
+ export type { AutocompleteOption, AutocompleteProps };
@@ -1,2 +1,2 @@
1
- import m from"@mui/material/Autocomplete";export{default}from"@mui/material/Autocomplete";
1
+ import{useState as e,useEffect as t,createElement as i}from"react";import{jsx as n,jsxs as l,Fragment as o}from"react/jsx-runtime";import r from"@mui/material/Autocomplete";import a from"@mui/material/Box";import{styled as s}from"@mui/material/styles";import d from"@mui/material/Tooltip";import p from"../../../icons/ArrowDown01/index.js";import m from"../../../icons/ArrowUp01/index.js";import c from"../../../icons/Cancel/index.js";import u from"../../../icons/Search/index.js";import{truncateWithEllipsis as g}from"../../../utilities/stringUtilities.js";import{Badge as h}from"../../atoms/Badge/index.js";import{CircularProgress as f}from"../../atoms/CircularProgress/index.js";import{MenuItem as x}from"../../atoms/MenuItem/index.js";import{TextField as b}from"../../atoms/TextField/index.js";import{useDynamicLimitTags as y}from"./hooks/useDynamicLimitTags.js";const T=s(r,{shouldForwardProp:e=>"fullWidth"!==e})((({fullWidth:e=!1})=>({width:e?"100%":"min(364px, 100%)"}))),C=s(a,{shouldForwardProp:e=>!["clickable","disabled","placement"].includes(e)})((({theme:e,clickable:t=!1,disabled:i=!1,placement:n})=>({alignItems:"center",cursor:t?i?"not-allowed":"pointer":"default",display:"flex",justifyContent:"center",padding:0,pointerEvents:t?"auto":"none",..."start"===n&&{paddingRight:e.spacing(1)},..."middle"===n&&{padding:e.spacing(0,1)},"& svg":{color:i?e.palette.semantic.icon["icon-disabled"]:e.palette.semantic.icon["icon-strong"]}}))),I=s(a,{shouldForwardProp:e=>"placement"!==e})((({theme:e,placement:t})=>({alignItems:"center",display:"flex",justifyContent:"center",padding:0,..."start"===t&&{paddingRight:e.spacing(1)},..."middle"===t&&{padding:e.spacing(0,1)}}))),P=({disabled:r=!1,errorText:a,fdKey:s,fullWidth:P=!1,helperText:k,label:j,loading:A=!1,multiple:v=!1,placeholder:w,onChange:O,onInputChange:W,options:D=[],required:L=!1,translations:S,type:F="search",value:q})=>{const[z,E]=e(!1),K="search"===F,R="combobox"===F,{rootRef:B,limitTags:M}=y({chipMax:130,gap:4,horizontalPadding:32,reservedPx:K?120:90});t((()=>{r&&E(!1)}),[r]);const U=e=>{r||E(void 0===e?e=>!e:e)};return n(T,{ref:B,clearIcon:n(c,{size:"md"}),clearText:S.clearTextAriaLabel,disableClearable:r||A,disableCloseOnSelect:v,disabled:r,filterOptions:K?e=>e:void 0,forcePopupIcon:R,freeSolo:K,fullWidth:P,getOptionKey:e=>"string"==typeof e?e:String(e.value),getOptionLabel:e=>"string"==typeof e?e:e.label,isOptionEqualToValue:(e,t)=>null!=t&&("string"==typeof t?e.label===t||String(e.value)===t:e.value===t.value),limitTags:M,loading:A,loadingText:S.loadingText,multiple:v,noOptionsText:S.noOptionsText,onChange:(e,t,i,n)=>{O&&O(e,t,i,n)},onClose:()=>U(!1),onInputChange:(e,t,i)=>{W&&W(e,t,i)},onOpen:()=>U(!0),open:z,openText:S.openPopupAriaLabel,options:D,popupIcon:K?null:n(C,{clickable:!0,disabled:r,placement:"end",children:n(z?m:p,{})}),renderInput:e=>n(b,{disabled:r,errorText:a,fdKey:s,fullWidth:P,helperText:k,label:j,placeholder:w,required:L,slotProps:{input:{...e.InputProps,endAdornment:l(o,{children:[A?n(I,{placement:K?"end":"middle",children:n(f,{size:"small"})}):null,e.InputProps.endAdornment]}),startAdornment:l(o,{children:[K?n(C,{disabled:r,placement:"start",children:n(u,{"aria-hidden":"true"})}):null,e.InputProps.startAdornment]})},htmlInput:{...e.inputProps}}}),renderOption:(e,t,n)=>{const{key:l,onClick:o,...r}=e;return i(x,v?{...r,key:l,checked:n.selected,label:t.label,onCheckedChange:(e,t)=>{o?.(t)},type:"checkbox"}:{...r,key:l,label:t.label,onClick:o,selected:n.selected,type:"text"})},renderTags:(e,t)=>e.map(((e,i)=>{const{key:l,onDelete:o,...r}=t({index:i}),a="string"==typeof e?e:e.label,s=g(a,13,{includeEllipsisInLimit:!0}),p=s.endsWith("..."),m=l??`tag-${"string"==typeof e?e:e.value}`;return p?n(d,{arrow:!0,placement:"top",title:a,children:n("span",{...r,children:n(h,{label:s,onDismiss:o})})},m):n("span",{...r,children:n(h,{label:s,onDismiss:o})},m)})),slotProps:{popupIndicator:{onClick:e=>{r||(e.stopPropagation(),U())}}},value:v?Array.isArray(q)?q:null==q?[]:[q]:Array.isArray(q)?q.length>0?q[0]:null:q??null})};export{P as Autocomplete,P as default};
2
2
  //# sourceMappingURL=index.js.map