@flipdish/portal-library 3.7.2 → 4.0.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.
- package/dist/components/FDErrorBoundary/index.cjs.js.map +1 -1
- package/dist/components/FDErrorBoundary/index.js.map +1 -1
- package/dist/components/Form/FormItemLayout/index.cjs.js.map +1 -1
- package/dist/components/Form/FormItemLayout/index.js.map +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.cjs.js +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.cjs.js.map +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.d.ts +4 -4
- package/dist/components/Form/GenericAutocompleteField/index.js +1 -1
- package/dist/components/Form/GenericAutocompleteField/index.js.map +1 -1
- package/dist/components/Form/GenericFormContainer/index.cjs.js +1 -1
- package/dist/components/Form/GenericFormContainer/index.cjs.js.map +1 -1
- package/dist/components/Form/GenericFormContainer/index.d.ts +3 -3
- package/dist/components/Form/GenericFormContainer/index.js +1 -1
- package/dist/components/Form/GenericFormContainer/index.js.map +1 -1
- package/dist/components/Form/GenericTextField/index.cjs.js.map +1 -1
- package/dist/components/Form/GenericTextField/index.js.map +1 -1
- package/dist/components/Form/PaginatedAutocompleteField/index.cjs.js +1 -1
- package/dist/components/Form/PaginatedAutocompleteField/index.cjs.js.map +1 -1
- package/dist/components/Form/PaginatedAutocompleteField/index.js +1 -1
- package/dist/components/Form/PaginatedAutocompleteField/index.js.map +1 -1
- package/dist/components/GenericDatePickerField/GenericDateFieldBase.cjs.js.map +1 -1
- package/dist/components/GenericDatePickerField/GenericDateFieldBase.js.map +1 -1
- package/dist/components/GenericRadioButtons/index.cjs.js +1 -1
- package/dist/components/GenericRadioButtons/index.cjs.js.map +1 -1
- package/dist/components/GenericRadioButtons/index.d.ts +3 -3
- package/dist/components/GenericRadioButtons/index.js +1 -1
- package/dist/components/GenericRadioButtons/index.js.map +1 -1
- package/dist/components/GenericTable/HighlightScrollbar.cjs.js.map +1 -1
- package/dist/components/GenericTable/HighlightScrollbar.js.map +1 -1
- package/dist/components/GenericTable/index.cjs.js +1 -1
- package/dist/components/GenericTable/index.cjs.js.map +1 -1
- package/dist/components/GenericTable/index.js +1 -1
- package/dist/components/GenericTable/index.js.map +1 -1
- package/dist/components/GenericTableBody/index.cjs.js +1 -1
- package/dist/components/GenericTableBody/index.cjs.js.map +1 -1
- package/dist/components/GenericTableBody/index.d.ts +9 -9
- package/dist/components/GenericTableBody/index.js +1 -1
- package/dist/components/GenericTableBody/index.js.map +1 -1
- package/dist/components/GenericTableBodyRow/index.cjs.js +1 -1
- package/dist/components/GenericTableBodyRow/index.cjs.js.map +1 -1
- package/dist/components/GenericTableBodyRow/index.d.ts +2 -2
- package/dist/components/GenericTableBodyRow/index.js +1 -1
- package/dist/components/GenericTableBodyRow/index.js.map +1 -1
- package/dist/components/ListItemLinkButton/index.cjs.js +1 -1
- package/dist/components/ListItemLinkButton/index.cjs.js.map +1 -1
- package/dist/components/ListItemLinkButton/index.js +1 -1
- package/dist/components/ListItemLinkButton/index.js.map +1 -1
- package/dist/components/NoResults/index.cjs.js.map +1 -1
- package/dist/components/NoResults/index.js.map +1 -1
- package/dist/components/PageLayout/DocumentTitle.cjs.js.map +1 -1
- package/dist/components/PageLayout/DocumentTitle.d.ts +1 -1
- package/dist/components/PageLayout/DocumentTitle.js.map +1 -1
- package/dist/components/PageLayout/FullWidthContainer.cjs.js.map +1 -1
- package/dist/components/PageLayout/FullWidthContainer.js.map +1 -1
- package/dist/components/PageLayout/GlobalSpacingStyles.cjs.js.map +1 -1
- package/dist/components/PageLayout/GlobalSpacingStyles.js.map +1 -1
- package/dist/components/PageLayout/index.cjs.js.map +1 -1
- package/dist/components/PageLayout/index.js.map +1 -1
- package/dist/components/PortalMock/index.cjs.js.map +1 -1
- package/dist/components/PortalMock/index.js.map +1 -1
- package/dist/components/Spacer/index.cjs.js.map +1 -1
- package/dist/components/Spacer/index.js.map +1 -1
- package/dist/components/atoms/Badge/index.cjs.js +1 -1
- package/dist/components/atoms/Badge/index.cjs.js.map +1 -1
- package/dist/components/atoms/Badge/index.js +1 -1
- package/dist/components/atoms/Badge/index.js.map +1 -1
- package/dist/components/atoms/Button/buttonThemeOverrides.cjs.js +2 -0
- package/dist/components/atoms/Button/buttonThemeOverrides.cjs.js.map +1 -0
- package/dist/components/atoms/Button/buttonThemeOverrides.d.ts +21 -0
- package/dist/components/atoms/Button/buttonThemeOverrides.js +2 -0
- package/dist/components/atoms/Button/buttonThemeOverrides.js.map +1 -0
- package/dist/components/atoms/Button/getButtonStyles.cjs.js +2 -0
- package/dist/components/atoms/Button/getButtonStyles.cjs.js.map +1 -0
- package/dist/components/atoms/Button/getButtonStyles.d.ts +15 -0
- package/dist/components/atoms/Button/getButtonStyles.js +2 -0
- package/dist/components/atoms/Button/getButtonStyles.js.map +1 -0
- package/dist/components/atoms/Button/index.cjs.js +2 -0
- package/dist/components/atoms/Button/index.cjs.js.map +1 -0
- package/dist/components/atoms/Button/index.d.ts +26 -0
- package/dist/components/atoms/Button/index.js +2 -0
- package/dist/components/atoms/Button/index.js.map +1 -0
- package/dist/components/atoms/IconContainer/index.cjs.js.map +1 -1
- package/dist/components/molecules/Alert/index.cjs.js +1 -1
- package/dist/components/molecules/Alert/index.cjs.js.map +1 -1
- package/dist/components/molecules/Alert/index.d.ts +1 -1
- package/dist/components/molecules/Alert/index.js +1 -1
- package/dist/components/molecules/Alert/index.js.map +1 -1
- package/dist/components/molecules/Modal/index.cjs.js.map +1 -1
- package/dist/components/molecules/Modal/index.js.map +1 -1
- package/dist/custom-hooks/useMicroFrontendAttributes.cjs.js +1 -1
- package/dist/custom-hooks/useMicroFrontendAttributes.cjs.js.map +1 -1
- package/dist/custom-hooks/useMicroFrontendAttributes.d.ts +4 -4
- package/dist/custom-hooks/useMicroFrontendAttributes.js +1 -1
- package/dist/custom-hooks/useMicroFrontendAttributes.js.map +1 -1
- package/dist/custom-hooks/useRenderValidText.cjs.js.map +1 -1
- package/dist/custom-hooks/useRenderValidText.d.ts +3 -3
- package/dist/custom-hooks/useRenderValidText.js.map +1 -1
- package/dist/custom-hooks/useToasts.cjs.js.map +1 -1
- package/dist/custom-hooks/useToasts.js.map +1 -1
- package/dist/icons/helpers/withSvgIcon.cjs.js.map +1 -1
- package/dist/icons/helpers/withSvgIcon.js.map +1 -1
- package/dist/themes/ThemeProvider.cjs.js.map +1 -1
- package/dist/themes/flipdishPublicTheme.cjs.js +1 -1
- package/dist/themes/flipdishPublicTheme.cjs.js.map +1 -1
- package/dist/themes/flipdishPublicTheme.js +1 -1
- package/dist/themes/flipdishPublicTheme.js.map +1 -1
- package/dist/themes/theme.d.ts +2 -2
- package/dist/themes/tokens/colours/colours-stories-utils.cjs.js +1 -1
- package/dist/themes/tokens/colours/colours-stories-utils.cjs.js.map +1 -1
- package/dist/themes/tokens/colours/colours-stories-utils.js +1 -1
- package/dist/themes/tokens/colours/colours-stories-utils.js.map +1 -1
- package/dist/themes/tokens/colours/primitives.cjs.js +1 -1
- package/dist/themes/tokens/colours/primitives.cjs.js.map +1 -1
- package/dist/themes/tokens/colours/primitives.js +1 -1
- package/dist/themes/tokens/colours/primitives.js.map +1 -1
- package/dist/themes/tokens/colours/semantic.cjs.js +1 -1
- package/dist/themes/tokens/colours/semantic.cjs.js.map +1 -1
- package/dist/themes/tokens/colours/semantic.d.ts +223 -4
- package/dist/themes/tokens/colours/semantic.js +1 -1
- package/dist/themes/tokens/colours/semantic.js.map +1 -1
- package/dist/themes/tokens/colours/types.d.ts +14 -14
- package/dist/themes/typography.cjs.js.map +1 -1
- package/dist/themes/typography.d.ts +31 -2
- package/dist/themes/typography.js.map +1 -1
- package/dist/utilities/formValidation.cjs.js +1 -1
- package/dist/utilities/formValidation.cjs.js.map +1 -1
- package/dist/utilities/formValidation.d.ts +1 -1
- package/dist/utilities/formValidation.js.map +1 -1
- package/dist/utilities/genericUtilities.cjs.js.map +1 -1
- package/dist/utilities/genericUtilities.js.map +1 -1
- package/dist/utilities/renderUtilities.cjs.js.map +1 -1
- package/dist/utilities/renderUtilities.js.map +1 -1
- package/package.json +4 -3
- package/dist/components/Button/index.cjs.js +0 -2
- package/dist/components/Button/index.cjs.js.map +0 -1
- package/dist/components/Button/index.d.ts +0 -6
- package/dist/components/Button/index.js +0 -2
- package/dist/components/Button/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/IconContainer/index.tsx"],"sourcesContent":["import * as React from 'react';\nimport Box from '@mui/material/Box';\nimport { styled, type Theme } from '@mui/material/styles';\n\nexport type IconContainerTones = 'neutral' | 'brand' | 'destructive' | 'warning' | 'success' | 'information';\nexport type IconContainerStyle = 'filled' | 'stroked';\n\nexport interface IconContainerProps {\n /** Icon element to display in the container */\n icon: React.ReactNode;\n /** Visual tone of the container */\n tone?: IconContainerTones;\n /** Visual style of the container */\n style?: IconContainerStyle;\n /** Accessible description of the icon (for screen readers) */\n ariaLabel?: string;\n /** Additional class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n}\n\n/** Color mapping for different tones and styles */\nconst COLORS = {\n background: {\n filled: {\n brand: (theme: Theme) => theme.palette.semantic.fill['fill-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.fill['fill-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.fill['fill-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.fill['fill-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.fill['fill-information-weak'],\n neutral: (theme: Theme) => theme.palette.semantic.fill['fill-weak'],\n },\n stroked: {\n brand: () => 'transparent',\n destructive: () => 'transparent',\n warning: () => 'transparent',\n success: () => 'transparent',\n information: () => 'transparent',\n neutral: () => 'transparent',\n },\n },\n border: {\n filled: {\n brand: () => 'transparent',\n destructive: () => 'transparent',\n warning: () => 'transparent',\n success: () => 'transparent',\n information: () => 'transparent',\n neutral: () => 'transparent',\n },\n stroked: {\n brand: (theme: Theme) => theme.palette.semantic.stroke['stroke-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.stroke['stroke-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.stroke['stroke-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.stroke['stroke-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.stroke['stroke-information-weak'],\n neutral: (theme: Theme) => theme.palette.semantic.stroke['stroke-weak'],\n },\n },\n icon: {\n brand: (theme: Theme) => theme.palette.semantic.icon['icon-primary'],\n destructive: (theme: Theme) => theme.palette.semantic.icon['icon-error'],\n warning: (theme: Theme) => theme.palette.semantic.icon['icon-warning'],\n success: (theme: Theme) => theme.palette.semantic.icon['icon-success'],\n information: (theme: Theme) => theme.palette.semantic.icon['icon-information'],\n neutral: (theme: Theme) => theme.palette.semantic.icon['icon-strong'],\n },\n};\n\nconst getBackgroundColor = (theme: Theme, tone: IconContainerTones, style: IconContainerStyle): string => {\n return COLORS.background[style][tone](theme);\n};\n\nconst getBorderColor = (theme: Theme, tone: IconContainerTones, style: IconContainerStyle): string => {\n return COLORS.border[style][tone](theme);\n};\n\nconst getIconColor = (theme: Theme, tone: IconContainerTones): string => {\n return COLORS.icon[tone](theme);\n};\n\ninterface StyledBoxProps {\n tone: IconContainerTones;\n containerStyle: IconContainerStyle;\n}\n\nconst StyledBox = styled(Box, {\n shouldForwardProp: (prop) => !['tone', 'containerStyle'].includes(prop as string),\n})<StyledBoxProps>(({ theme, tone, containerStyle }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '48px',\n height: '48px',\n borderRadius: '50%',\n backgroundColor: getBackgroundColor(theme, tone, containerStyle),\n border: containerStyle === 'stroked' ? '1px solid' : 'none',\n borderColor: getBorderColor(theme, tone, containerStyle),\n boxSizing: 'border-box',\n color: getIconColor(theme, tone),\n}));\n\n/**\n * IconContainer component is used to make icons appear larger and more prominent while \ngiving them a consistent shape.\n *\n * React.memo is used to optimize performance by preventing unnecessary re-renders\n * when the component's props haven't changed, which is beneficial for components\n * that may be used frequently throughout the application.\n */\nconst IconContainer = React.memo(\n ({ icon, tone = 'neutral', style = 'filled', ariaLabel, className, 'data-testid': dataTestId }: IconContainerProps) => {\n // Only set aria-hidden if no ariaLabel is provided\n const ariaProps = ariaLabel ? { 'aria-label': ariaLabel, role: 'graphics-symbol' } : { 'aria-hidden': true };\n\n return (\n <StyledBox tone={tone} containerStyle={style} className={className} data-testid={dataTestId} {...ariaProps}>\n {icon}\n </StyledBox>\n );\n },\n);\n\nIconContainer.displayName = 'IconContainer';\n\nexport default IconContainer;\n"],"names":["COLORS","background","filled","brand","theme","palette","semantic","fill","destructive","warning","success","information","neutral","stroked","border","stroke","icon","getBackgroundColor","tone","style","getBorderColor","getIconColor","StyledBox","styled","Box","shouldForwardProp","prop","includes","containerStyle","display","alignItems","justifyContent","width","height","borderRadius","backgroundColor","borderColor","boxSizing","color","IconContainer","React","memo","ariaLabel","className","dataTestId","ariaProps","role","_jsx","children","displayName"],"mappings":"kZAuBA,MAAMA,EAAS,CACXC,WAAY,CACRC,OAAQ,CACJC,MAAQC,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,qBACrDC,YAAcJ,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,mBAC3DE,QAAUL,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,qBACvDG,QAAUN,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,qBACvDI,YAAcP,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,yBAC3DK,QAAUR,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,cAE3DM,QAAS,CACLV,MAAO,IAAM,cACbK,YAAa,IAAM,cACnBC,QAAS,IAAM,cACfC,QAAS,IAAM,cACfC,YAAa,IAAM,cACnBC,QAAS,IAAM,gBAGvBE,OAAQ,CACJZ,OAAQ,CACJC,MAAO,IAAM,cACbK,YAAa,IAAM,cACnBC,QAAS,IAAM,cACfC,QAAS,IAAM,cACfC,YAAa,IAAM,cACnBC,QAAS,IAAM,eAEnBC,QAAS,CACLV,MAAQC,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,uBACvDP,YAAcJ,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,qBAC7DN,QAAUL,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,uBACzDL,QAAUN,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,uBACzDJ,YAAcP,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,2BAC7DH,QAAUR,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,iBAGjEC,KAAM,CACFb,MAAQC,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,gBACrDR,YAAcJ,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,cAC3DP,QAAUL,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,gBACvDN,QAAUN,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,gBACvDL,YAAcP,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,oBAC3DJ,QAAUR,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,iBAIzDC,EAAqB,CAACb,EAAcc,EAA0BC,IACzDnB,EAAOC,WAAWkB,GAAOD,GAAMd,GAGpCgB,EAAiB,CAAChB,EAAcc,EAA0BC,IACrDnB,EAAOc,OAAOK,GAAOD,GAAMd,GAGhCiB,EAAe,CAACjB,EAAcc,IACzBlB,EAAOgB,KAAKE,GAAMd,GAQvBkB,EAAYC,EAAMA,OAACC,EAAK,CAC1BC,kBAAoBC,IAAU,CAAC,OAAQ,kBAAkBC,SAASD,IADpDH,EAEC,EAAGnB,QAAOc,OAAMU,qBAAsB,CACrDC,QAAS,OACTC,WAAY,SACZC,eAAgB,SAChBC,MAAO,OACPC,OAAQ,OACRC,aAAc,MACdC,gBAAiBlB,EAAmBb,EAAOc,EAAMU,GACjDd,OAA2B,YAAnBc,EAA+B,YAAc,OACrDQ,YAAahB,EAAehB,EAAOc,EAAMU,GACzCS,UAAW,aACXC,MAAOjB,EAAajB,EAAOc,OAWzBqB,EAAgBC,EAAMC,MACxB,EAAGzB,OAAME,OAAO,UAAWC,QAAQ,SAAUuB,YAAWC,YAAW,cAAeC,MAE9E,MAAMC,EAAYH,EAAY,CAAE,aAAcA,EAAWI,KAAM,mBAAsB,CAAE,eAAe,GAEtG,OACIC,EAAAA,IAACzB,EAAS,CAACJ,KAAMA,EAAMU,eAAgBT,EAAOwB,UAAWA,EAAS,cAAeC,KAAgBC,EAC5FG,SAAAhC,
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/IconContainer/index.tsx"],"sourcesContent":["import * as React from 'react';\nimport Box from '@mui/material/Box';\nimport { styled, type Theme } from '@mui/material/styles';\n\nexport type IconContainerTones = 'neutral' | 'brand' | 'destructive' | 'warning' | 'success' | 'information';\nexport type IconContainerStyle = 'filled' | 'stroked';\n\nexport interface IconContainerProps {\n /** Icon element to display in the container */\n icon: React.ReactNode;\n /** Visual tone of the container */\n tone?: IconContainerTones;\n /** Visual style of the container */\n style?: IconContainerStyle;\n /** Accessible description of the icon (for screen readers) */\n ariaLabel?: string;\n /** Additional class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n}\n\n/** Color mapping for different tones and styles */\nconst COLORS = {\n background: {\n filled: {\n brand: (theme: Theme) => theme.palette.semantic.fill['fill-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.fill['fill-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.fill['fill-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.fill['fill-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.fill['fill-information-weak'],\n neutral: (theme: Theme) => theme.palette.semantic.fill['fill-weak'],\n },\n stroked: {\n brand: () => 'transparent',\n destructive: () => 'transparent',\n warning: () => 'transparent',\n success: () => 'transparent',\n information: () => 'transparent',\n neutral: () => 'transparent',\n },\n },\n border: {\n filled: {\n brand: () => 'transparent',\n destructive: () => 'transparent',\n warning: () => 'transparent',\n success: () => 'transparent',\n information: () => 'transparent',\n neutral: () => 'transparent',\n },\n stroked: {\n brand: (theme: Theme) => theme.palette.semantic.stroke['stroke-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.stroke['stroke-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.stroke['stroke-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.stroke['stroke-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.stroke['stroke-information-weak'],\n neutral: (theme: Theme) => theme.palette.semantic.stroke['stroke-weak'],\n },\n },\n icon: {\n brand: (theme: Theme) => theme.palette.semantic.icon['icon-primary'],\n destructive: (theme: Theme) => theme.palette.semantic.icon['icon-error'],\n warning: (theme: Theme) => theme.palette.semantic.icon['icon-warning'],\n success: (theme: Theme) => theme.palette.semantic.icon['icon-success'],\n information: (theme: Theme) => theme.palette.semantic.icon['icon-information'],\n neutral: (theme: Theme) => theme.palette.semantic.icon['icon-strong'],\n },\n};\n\nconst getBackgroundColor = (theme: Theme, tone: IconContainerTones, style: IconContainerStyle): string => {\n return COLORS.background[style][tone](theme);\n};\n\nconst getBorderColor = (theme: Theme, tone: IconContainerTones, style: IconContainerStyle): string => {\n return COLORS.border[style][tone](theme);\n};\n\nconst getIconColor = (theme: Theme, tone: IconContainerTones): string => {\n return COLORS.icon[tone](theme);\n};\n\ninterface StyledBoxProps {\n tone: IconContainerTones;\n containerStyle: IconContainerStyle;\n}\n\nconst StyledBox = styled(Box, {\n shouldForwardProp: (prop) => !['tone', 'containerStyle'].includes(prop as string),\n})<StyledBoxProps>(({ theme, tone, containerStyle }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '48px',\n height: '48px',\n borderRadius: '50%',\n backgroundColor: getBackgroundColor(theme, tone, containerStyle),\n border: containerStyle === 'stroked' ? '1px solid' : 'none',\n borderColor: getBorderColor(theme, tone, containerStyle),\n boxSizing: 'border-box',\n color: getIconColor(theme, tone),\n}));\n\n/**\n * IconContainer component is used to make icons appear larger and more prominent while \ngiving them a consistent shape.\n *\n * React.memo is used to optimize performance by preventing unnecessary re-renders\n * when the component's props haven't changed, which is beneficial for components\n * that may be used frequently throughout the application.\n */\nconst IconContainer = React.memo(\n ({ icon, tone = 'neutral', style = 'filled', ariaLabel, className, 'data-testid': dataTestId }: IconContainerProps) => {\n // Only set aria-hidden if no ariaLabel is provided\n const ariaProps = ariaLabel ? { 'aria-label': ariaLabel, role: 'graphics-symbol' } : { 'aria-hidden': true };\n\n return (\n <StyledBox tone={tone} containerStyle={style} className={className} data-testid={dataTestId} {...ariaProps}>\n {icon}\n </StyledBox>\n );\n },\n);\n\nIconContainer.displayName = 'IconContainer';\n\nexport default IconContainer;\n"],"names":["COLORS","background","filled","brand","theme","palette","semantic","fill","destructive","warning","success","information","neutral","stroked","border","stroke","icon","getBackgroundColor","tone","style","getBorderColor","getIconColor","StyledBox","styled","Box","shouldForwardProp","prop","includes","containerStyle","display","alignItems","justifyContent","width","height","borderRadius","backgroundColor","borderColor","boxSizing","color","IconContainer","React","memo","ariaLabel","className","dataTestId","ariaProps","role","_jsx","children","displayName"],"mappings":"kZAuBA,MAAMA,EAAS,CACXC,WAAY,CACRC,OAAQ,CACJC,MAAQC,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,qBACrDC,YAAcJ,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,mBAC3DE,QAAUL,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,qBACvDG,QAAUN,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,qBACvDI,YAAcP,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,yBAC3DK,QAAUR,GAAiBA,EAAMC,QAAQC,SAASC,KAAK,cAE3DM,QAAS,CACLV,MAAO,IAAM,cACbK,YAAa,IAAM,cACnBC,QAAS,IAAM,cACfC,QAAS,IAAM,cACfC,YAAa,IAAM,cACnBC,QAAS,IAAM,gBAGvBE,OAAQ,CACJZ,OAAQ,CACJC,MAAO,IAAM,cACbK,YAAa,IAAM,cACnBC,QAAS,IAAM,cACfC,QAAS,IAAM,cACfC,YAAa,IAAM,cACnBC,QAAS,IAAM,eAEnBC,QAAS,CACLV,MAAQC,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,uBACvDP,YAAcJ,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,qBAC7DN,QAAUL,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,uBACzDL,QAAUN,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,uBACzDJ,YAAcP,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,2BAC7DH,QAAUR,GAAiBA,EAAMC,QAAQC,SAASS,OAAO,iBAGjEC,KAAM,CACFb,MAAQC,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,gBACrDR,YAAcJ,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,cAC3DP,QAAUL,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,gBACvDN,QAAUN,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,gBACvDL,YAAcP,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,oBAC3DJ,QAAUR,GAAiBA,EAAMC,QAAQC,SAASU,KAAK,iBAIzDC,EAAqB,CAACb,EAAcc,EAA0BC,IACzDnB,EAAOC,WAAWkB,GAAOD,GAAMd,GAGpCgB,EAAiB,CAAChB,EAAcc,EAA0BC,IACrDnB,EAAOc,OAAOK,GAAOD,GAAMd,GAGhCiB,EAAe,CAACjB,EAAcc,IACzBlB,EAAOgB,KAAKE,GAAMd,GAQvBkB,EAAYC,EAAMA,OAACC,EAAK,CAC1BC,kBAAoBC,IAAU,CAAC,OAAQ,kBAAkBC,SAASD,IADpDH,EAEC,EAAGnB,QAAOc,OAAMU,qBAAsB,CACrDC,QAAS,OACTC,WAAY,SACZC,eAAgB,SAChBC,MAAO,OACPC,OAAQ,OACRC,aAAc,MACdC,gBAAiBlB,EAAmBb,EAAOc,EAAMU,GACjDd,OAA2B,YAAnBc,EAA+B,YAAc,OACrDQ,YAAahB,EAAehB,EAAOc,EAAMU,GACzCS,UAAW,aACXC,MAAOjB,EAAajB,EAAOc,OAWzBqB,EAAgBC,EAAMC,MACxB,EAAGzB,OAAME,OAAO,UAAWC,QAAQ,SAAUuB,YAAWC,YAAW,cAAeC,MAE9E,MAAMC,EAAYH,EAAY,CAAE,aAAcA,EAAWI,KAAM,mBAAsB,CAAE,eAAe,GAEtG,OACIC,EAAAA,IAACzB,EAAS,CAACJ,KAAMA,EAAMU,eAAgBT,EAAOwB,UAAWA,EAAS,cAAeC,KAAgBC,EAC5FG,SAAAhC,OAMjBuB,EAAcU,YAAc"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("@mui/material/Alert"),r=require("@mui/material/AlertTitle"),i=require("@mui/material/Box"),n=require("@mui/material/styles"),s=require("../../../icons/Alert/index.cjs.js"),l=require("../../../icons/CancelCircle/index.cjs.js"),
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("@mui/material/Alert"),r=require("@mui/material/AlertTitle"),i=require("@mui/material/Box"),n=require("@mui/material/styles"),s=require("../../../icons/Alert/index.cjs.js"),l=require("../../../icons/CancelCircle/index.cjs.js"),o=require("../../../icons/CheckmarkCircle/index.cjs.js"),c=require("../../../icons/Diamond/index.cjs.js"),m=require("../../../icons/InformationCircle/index.cjs.js"),d=require("../../atoms/Button/index.cjs.js");const u={neutral:t=>e.jsx(c,{color:t.palette.semantic.icon["icon-strong"]}),brand:t=>e.jsx(c,{color:t.palette.semantic.icon["icon-primary"]}),destructive:t=>e.jsx(l,{color:t.palette.semantic.icon["icon-error"]}),warning:t=>e.jsx(s,{color:t.palette.semantic.icon["icon-warning"]}),information:t=>e.jsx(m,{color:t.palette.semantic.icon["icon-information"]}),"neutral-inverse":t=>e.jsx(c,{color:t.palette.semantic.icon["icon-inverse"]}),"brand-inverse":t=>e.jsx(c,{color:t.palette.semantic.icon["icon-inverse"]}),success:t=>e.jsx(o,{color:t.palette.semantic.icon["icon-success"]})},x={background:{neutral:e=>e.palette.semantic.fill["fill-weak"],brand:e=>e.palette.semantic.fill["fill-primary-weak"],destructive:e=>e.palette.semantic.fill["fill-error-weak"],warning:e=>e.palette.semantic.fill["fill-warning-weak"],success:e=>e.palette.semantic.fill["fill-success-weak"],information:e=>e.palette.semantic.fill["fill-information-weak"],"neutral-inverse":e=>e.palette.semantic.background["background-inverse"],"brand-inverse":e=>e.palette.semantic.fill["fill-primary-strong"]},border:{neutral:e=>e.palette.semantic.stroke["stroke-weak"],brand:e=>e.palette.semantic.stroke["stroke-primary-weak"],destructive:e=>e.palette.semantic.stroke["stroke-error-weak"],warning:e=>e.palette.semantic.stroke["stroke-warning-weak"],success:e=>e.palette.semantic.stroke["stroke-success-weak"],information:e=>e.palette.semantic.stroke["stroke-information-weak"],"neutral-inverse":()=>"transparant","brand-inverse":()=>"transparant"},header:{neutral:e=>e.palette.semantic.text["text-strong"],brand:e=>e.palette.semantic.text["text-strong"],destructive:e=>e.palette.semantic.text["text-strong"],warning:e=>e.palette.semantic.text["text-strong"],success:e=>e.palette.semantic.text["text-strong"],information:e=>e.palette.semantic.text["text-strong"],"neutral-inverse":e=>e.palette.semantic.text["text-inverse-strong"],"brand-inverse":e=>e.palette.semantic.text["text-inverse-strong"]},text:{neutral:e=>e.palette.semantic.text["text-weak"],brand:e=>e.palette.semantic.text["text-weak"],destructive:e=>e.palette.semantic.text["text-weak"],warning:e=>e.palette.semantic.text["text-weak"],success:e=>e.palette.semantic.text["text-weak"],information:e=>e.palette.semantic.text["text-weak"],"neutral-inverse":e=>e.palette.semantic.text["text-inverse-weak"],"brand-inverse":e=>e.palette.semantic.text["text-inverse-weak"]}},p=(e,t)=>u[t](e),k=(e,t)=>x.background[t](e),w=(e,t)=>x.border[t](e),b=(e,t)=>x.header[t](e),f=(e,t)=>x.text[t](e),j=n.styled(i)((()=>({marginTop:"16px"}))),g=n.styled(a,{shouldForwardProp:e=>!["tone"].includes(e)})((({theme:e,tone:t})=>({backgroundColor:k(e,t),border:"1px solid",borderColor:w(e,t),color:f(e,t)}))),v=t.memo((({title:t,description:a,tone:s="neutral",onClose:l,className:o,"data-testid":c,action:m})=>{const u=n.useTheme();return e.jsxs(g,{"aria-describedby":`alert-description-${c??"default"}`,"aria-labelledby":`alert-title-${c??"default"}`,className:o,"data-testid":c,icon:p(u,s),role:"alert",tone:s,onClose:l,children:[e.jsx(r,{color:b(u,s),id:`alert-title-${c??"default"}`,children:t}),e.jsx(i,{id:`alert-description-${c??"default"}`,children:a}),(()=>{if(!m)return null;const a=m["data-testid"]??`action-button-${m.label.replace(/\s+/g,"-").toLowerCase()}`;return e.jsx(j,{children:e.jsx(d.Button,{"aria-label":`${m.label} - ${t}`,"data-testid":a,fdKey:m.label,size:"small",variant:m.type??"primary",onClick:m.onClick,children:m.label})})})()]})}));v.displayName="Alert",module.exports=v;
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Alert/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nimport { memo } from 'react';\n\nimport MuiAlert from '@mui/material/Alert';\nimport MuiAlertTitle from '@mui/material/AlertTitle';\nimport Box from '@mui/material/Box';\nimport { styled, type Theme, useTheme } from '@mui/material/styles';\n\nimport AlertIcon from '../../../icons/Alert';\nimport CancelCircleIcon from '../../../icons/CancelCircle';\nimport CheckmarkCircleIcon from '../../../icons/CheckmarkCircle';\nimport DiamondIcon from '../../../icons/Diamond';\nimport InformationCircleIcon from '../../../icons/InformationCircle';\nimport Button, { type ButtonType } from '../../Button';\n\n/** Visual tone of the alert */\nexport type AlertTones =\n | 'brand-inverse'\n | 'brand'\n | 'destructive'\n | 'information'\n | 'neutral-inverse'\n | 'neutral'\n | 'success'\n | 'warning';\n\n/** Props for the Alert component */\nexport interface AlertProps {\n /** Main heading text of the alert */\n title: string;\n /** Detailed description text of the alert */\n description: string;\n /** Visual tone of the alert */\n tone?: AlertTones;\n /** Callback function when the alert is closed */\n onClose?: () => void;\n /** Action button configuration */\n action?: {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n 'data-testid'?: string;\n };\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n}\n\nconst ICONS = {\n neutral: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-strong']} />,\n brand: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-primary']} />,\n destructive: (theme: Theme) => <CancelCircleIcon color={theme.palette.semantic.icon['icon-error']} />,\n warning: (theme: Theme) => <AlertIcon color={theme.palette.semantic.icon['icon-warning']} />,\n information: (theme: Theme) => (\n <InformationCircleIcon color={theme.palette.semantic.icon['icon-information']} />\n ),\n 'neutral-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n 'brand-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n success: (theme: Theme) => <CheckmarkCircleIcon color={theme.palette.semantic.icon['icon-success']} />,\n};\n\nconst COLOURS = {\n background: {\n neutral: (theme: Theme) => theme.palette.semantic.fill['fill-weak'],\n brand: (theme: Theme) => theme.palette.semantic.fill['fill-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.fill['fill-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.fill['fill-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.fill['fill-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.fill['fill-information-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.background['background-inverse'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.fill['fill-primary-strong'],\n },\n border: {\n neutral: (theme: Theme) => theme.palette.semantic.stroke['stroke-weak'],\n brand: (theme: Theme) => theme.palette.semantic.stroke['stroke-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.stroke['stroke-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.stroke['stroke-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.stroke['stroke-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.stroke['stroke-information-weak'],\n 'neutral-inverse': () => 'transparant',\n 'brand-inverse': () => 'transparant',\n },\n header: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n success: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n information: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n },\n text: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n success: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n information: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n },\n};\n\nconst getIcon = (theme: Theme, tone: AlertTones): JSX.Element => {\n return ICONS[tone](theme);\n};\n\nconst getBackgroundColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.background[tone](theme);\n};\n\nconst getBorderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.border[tone](theme);\n};\n\nconst getHeaderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.header[tone](theme);\n};\n\nconst getTextColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.text[tone](theme);\n};\n\nconst getButtonVariant = (type: ButtonType) => {\n switch (type) {\n case 'primary':\n return 'contained';\n case 'secondary':\n return 'outlined';\n default:\n return 'text';\n }\n};\n\ninterface StyledAlertProps {\n tone: AlertTones;\n}\n\nconst StyledActionContainer = styled(Box)(() => ({\n marginTop: '16px',\n}));\n\nconst StyledAlert = styled(MuiAlert, {\n shouldForwardProp: (prop) => !['tone'].includes(prop as string),\n})<StyledAlertProps>(({ theme, tone }) => ({\n backgroundColor: getBackgroundColour(theme, tone),\n border: '1px solid',\n borderColor: getBorderColour(theme, tone),\n color: getTextColour(theme, tone),\n}));\n\n/**\n * Alert component is used to display important messages or notifications to users.\n * It supports different visual tones to convey different semantic meanings and can include\n * an optional action button and close button.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed, which is beneficial for components\n * that may be used frequently throughout the application.\n */\nconst Alert = memo(\n ({\n title,\n description,\n tone = 'neutral',\n onClose,\n className,\n 'data-testid': dataTestId,\n action,\n }: AlertProps) => {\n const theme = useTheme();\n\n const renderAction = () => {\n if (action) {\n const actionTestId =\n action['data-testid'] ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n return (\n <StyledActionContainer>\n <Button\n aria-label={`${action.label} - ${title}`}\n data-testid={actionTestId}\n size=\"small\"\n variant={getButtonVariant(action.type ?? 'primary')}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n </StyledActionContainer>\n );\n }\n };\n\n return (\n <StyledAlert\n aria-describedby={`alert-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`alert-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n icon={getIcon(theme, tone)}\n role=\"alert\"\n tone={tone}\n onClose={onClose}\n >\n <MuiAlertTitle color={getHeaderColour(theme, tone)} id={`alert-title-${dataTestId ?? 'default'}`}>\n {title}\n </MuiAlertTitle>\n <Box id={`alert-description-${dataTestId ?? 'default'}`}>{description}</Box>\n {renderAction()}\n </StyledAlert>\n );\n },\n);\n\nAlert.displayName = 'Alert';\n\nexport default Alert;\n"],"names":["ICONS","neutral","theme","_jsx","jsx","DiamondIcon","color","palette","semantic","icon","brand","destructive","CancelCircleIcon","warning","AlertIcon","information","InformationCircleIcon","success","CheckmarkCircleIcon","COLOURS","background","fill","border","stroke","header","text","getIcon","tone","getBackgroundColour","getBorderColour","getHeaderColour","getTextColour","getButtonVariant","type","StyledActionContainer","styled","Box","marginTop","StyledAlert","MuiAlert","shouldForwardProp","prop","includes","backgroundColor","borderColor","Alert","memo","title","description","onClose","className","dataTestId","action","useTheme","_jsxs","jsxs","role","children","MuiAlertTitle","id","actionTestId","label","replace","toLowerCase","Button","size","variant","onClick","renderAction","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Alert/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nimport { memo } from 'react';\n\nimport MuiAlert from '@mui/material/Alert';\nimport MuiAlertTitle from '@mui/material/AlertTitle';\nimport Box from '@mui/material/Box';\nimport { styled, type Theme, useTheme } from '@mui/material/styles';\n\nimport AlertIcon from '../../../icons/Alert';\nimport CancelCircleIcon from '../../../icons/CancelCircle';\nimport CheckmarkCircleIcon from '../../../icons/CheckmarkCircle';\nimport DiamondIcon from '../../../icons/Diamond';\nimport InformationCircleIcon from '../../../icons/InformationCircle';\nimport Button from '../../atoms/Button';\nimport type { ButtonType } from '../../atoms/Button/getButtonStyles';\n\n/** Visual tone of the alert */\nexport type AlertTones =\n | 'brand-inverse'\n | 'brand'\n | 'destructive'\n | 'information'\n | 'neutral-inverse'\n | 'neutral'\n | 'success'\n | 'warning';\n\n/** Props for the Alert component */\nexport interface AlertProps {\n /** Main heading text of the alert */\n title: string;\n /** Detailed description text of the alert */\n description: string;\n /** Visual tone of the alert */\n tone?: AlertTones;\n /** Callback function when the alert is closed */\n onClose?: () => void;\n /** Action button configuration */\n action?: {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n 'data-testid'?: string;\n };\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n}\n\nconst ICONS = {\n neutral: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-strong']} />,\n brand: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-primary']} />,\n destructive: (theme: Theme) => <CancelCircleIcon color={theme.palette.semantic.icon['icon-error']} />,\n warning: (theme: Theme) => <AlertIcon color={theme.palette.semantic.icon['icon-warning']} />,\n information: (theme: Theme) => (\n <InformationCircleIcon color={theme.palette.semantic.icon['icon-information']} />\n ),\n 'neutral-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n 'brand-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n success: (theme: Theme) => <CheckmarkCircleIcon color={theme.palette.semantic.icon['icon-success']} />,\n};\n\nconst COLOURS = {\n background: {\n neutral: (theme: Theme) => theme.palette.semantic.fill['fill-weak'],\n brand: (theme: Theme) => theme.palette.semantic.fill['fill-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.fill['fill-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.fill['fill-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.fill['fill-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.fill['fill-information-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.background['background-inverse'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.fill['fill-primary-strong'],\n },\n border: {\n neutral: (theme: Theme) => theme.palette.semantic.stroke['stroke-weak'],\n brand: (theme: Theme) => theme.palette.semantic.stroke['stroke-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.stroke['stroke-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.stroke['stroke-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.stroke['stroke-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.stroke['stroke-information-weak'],\n 'neutral-inverse': () => 'transparant',\n 'brand-inverse': () => 'transparant',\n },\n header: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n success: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n information: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n },\n text: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n success: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n information: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n },\n};\n\nconst getIcon = (theme: Theme, tone: AlertTones): JSX.Element => {\n return ICONS[tone](theme);\n};\n\nconst getBackgroundColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.background[tone](theme);\n};\n\nconst getBorderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.border[tone](theme);\n};\n\nconst getHeaderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.header[tone](theme);\n};\n\nconst getTextColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.text[tone](theme);\n};\n\ninterface StyledAlertProps {\n tone: AlertTones;\n}\n\nconst StyledActionContainer = styled(Box)(() => ({\n marginTop: '16px',\n}));\n\nconst StyledAlert = styled(MuiAlert, {\n shouldForwardProp: (prop) => !['tone'].includes(prop as string),\n})<StyledAlertProps>(({ theme, tone }) => ({\n backgroundColor: getBackgroundColour(theme, tone),\n border: '1px solid',\n borderColor: getBorderColour(theme, tone),\n color: getTextColour(theme, tone),\n}));\n\n/**\n * Alert component is used to display important messages or notifications to users.\n * It supports different visual tones to convey different semantic meanings and can include\n * an optional action button and close button.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed, which is beneficial for components\n * that may be used frequently throughout the application.\n */\nconst Alert = memo(\n ({\n title,\n description,\n tone = 'neutral',\n onClose,\n className,\n 'data-testid': dataTestId,\n action,\n }: AlertProps) => {\n const theme = useTheme();\n\n const renderAction = (): JSX.Element | null => {\n if (!action) {\n return null;\n }\n\n const actionTestId =\n action['data-testid'] ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <StyledActionContainer>\n <Button\n aria-label={`${action.label} - ${title}`}\n data-testid={actionTestId}\n fdKey={action.label}\n size=\"small\"\n variant={action.type ?? 'primary'}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n </StyledActionContainer>\n );\n };\n\n return (\n <StyledAlert\n aria-describedby={`alert-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`alert-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n icon={getIcon(theme, tone)}\n role=\"alert\"\n tone={tone}\n onClose={onClose}\n >\n <MuiAlertTitle color={getHeaderColour(theme, tone)} id={`alert-title-${dataTestId ?? 'default'}`}>\n {title}\n </MuiAlertTitle>\n <Box id={`alert-description-${dataTestId ?? 'default'}`}>{description}</Box>\n {renderAction()}\n </StyledAlert>\n );\n },\n);\n\nAlert.displayName = 'Alert';\n\nexport default Alert;\n"],"names":["ICONS","neutral","theme","_jsx","jsx","DiamondIcon","color","palette","semantic","icon","brand","destructive","CancelCircleIcon","warning","AlertIcon","information","InformationCircleIcon","success","CheckmarkCircleIcon","COLOURS","background","fill","border","stroke","header","text","getIcon","tone","getBackgroundColour","getBorderColour","getHeaderColour","getTextColour","StyledActionContainer","styled","Box","marginTop","StyledAlert","MuiAlert","shouldForwardProp","prop","includes","backgroundColor","borderColor","Alert","memo","title","description","onClose","className","dataTestId","action","useTheme","_jsxs","jsxs","role","children","MuiAlertTitle","id","actionTestId","label","replace","toLowerCase","Button","fdKey","size","variant","type","onClick","renderAction","displayName"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import { ButtonType } from '../../Button/
|
|
3
|
+
import { ButtonType } from '../../atoms/Button/getButtonStyles.js';
|
|
4
4
|
|
|
5
5
|
/** Visual tone of the alert */
|
|
6
6
|
type AlertTones = 'brand-inverse' | 'brand' | 'destructive' | 'information' | 'neutral-inverse' | 'neutral' | 'success' | 'warning';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as e,jsx as t}from"react/jsx-runtime";import{memo as a}from"react";import r from"@mui/material/Alert";import i from"@mui/material/AlertTitle";import n from"@mui/material/Box";import{styled as o,useTheme as
|
|
1
|
+
import{jsxs as e,jsx as t}from"react/jsx-runtime";import{memo as a}from"react";import r from"@mui/material/Alert";import i from"@mui/material/AlertTitle";import n from"@mui/material/Box";import{styled as o,useTheme as l}from"@mui/material/styles";import s from"../../../icons/Alert/index.js";import c from"../../../icons/CancelCircle/index.js";import m from"../../../icons/CheckmarkCircle/index.js";import p from"../../../icons/Diamond/index.js";import d from"../../../icons/InformationCircle/index.js";import{Button as u}from"../../atoms/Button/index.js";const x={neutral:e=>t(p,{color:e.palette.semantic.icon["icon-strong"]}),brand:e=>t(p,{color:e.palette.semantic.icon["icon-primary"]}),destructive:e=>t(c,{color:e.palette.semantic.icon["icon-error"]}),warning:e=>t(s,{color:e.palette.semantic.icon["icon-warning"]}),information:e=>t(d,{color:e.palette.semantic.icon["icon-information"]}),"neutral-inverse":e=>t(p,{color:e.palette.semantic.icon["icon-inverse"]}),"brand-inverse":e=>t(p,{color:e.palette.semantic.icon["icon-inverse"]}),success:e=>t(m,{color:e.palette.semantic.icon["icon-success"]})},f={background:{neutral:e=>e.palette.semantic.fill["fill-weak"],brand:e=>e.palette.semantic.fill["fill-primary-weak"],destructive:e=>e.palette.semantic.fill["fill-error-weak"],warning:e=>e.palette.semantic.fill["fill-warning-weak"],success:e=>e.palette.semantic.fill["fill-success-weak"],information:e=>e.palette.semantic.fill["fill-information-weak"],"neutral-inverse":e=>e.palette.semantic.background["background-inverse"],"brand-inverse":e=>e.palette.semantic.fill["fill-primary-strong"]},border:{neutral:e=>e.palette.semantic.stroke["stroke-weak"],brand:e=>e.palette.semantic.stroke["stroke-primary-weak"],destructive:e=>e.palette.semantic.stroke["stroke-error-weak"],warning:e=>e.palette.semantic.stroke["stroke-warning-weak"],success:e=>e.palette.semantic.stroke["stroke-success-weak"],information:e=>e.palette.semantic.stroke["stroke-information-weak"],"neutral-inverse":()=>"transparant","brand-inverse":()=>"transparant"},header:{neutral:e=>e.palette.semantic.text["text-strong"],brand:e=>e.palette.semantic.text["text-strong"],destructive:e=>e.palette.semantic.text["text-strong"],warning:e=>e.palette.semantic.text["text-strong"],success:e=>e.palette.semantic.text["text-strong"],information:e=>e.palette.semantic.text["text-strong"],"neutral-inverse":e=>e.palette.semantic.text["text-inverse-strong"],"brand-inverse":e=>e.palette.semantic.text["text-inverse-strong"]},text:{neutral:e=>e.palette.semantic.text["text-weak"],brand:e=>e.palette.semantic.text["text-weak"],destructive:e=>e.palette.semantic.text["text-weak"],warning:e=>e.palette.semantic.text["text-weak"],success:e=>e.palette.semantic.text["text-weak"],information:e=>e.palette.semantic.text["text-weak"],"neutral-inverse":e=>e.palette.semantic.text["text-inverse-weak"],"brand-inverse":e=>e.palette.semantic.text["text-inverse-weak"]}},k=(e,t)=>x[t](e),w=(e,t)=>f.background[t](e),b=(e,t)=>f.border[t](e),g=(e,t)=>f.header[t](e),v=(e,t)=>f.text[t](e),C=o(n)((()=>({marginTop:"16px"}))),y=o(r,{shouldForwardProp:e=>!["tone"].includes(e)})((({theme:e,tone:t})=>({backgroundColor:w(e,t),border:"1px solid",borderColor:b(e,t),color:v(e,t)}))),h=a((({title:a,description:r,tone:o="neutral",onClose:s,className:c,"data-testid":m,action:p})=>{const d=l();return e(y,{"aria-describedby":`alert-description-${m??"default"}`,"aria-labelledby":`alert-title-${m??"default"}`,className:c,"data-testid":m,icon:k(d,o),role:"alert",tone:o,onClose:s,children:[t(i,{color:g(d,o),id:`alert-title-${m??"default"}`,children:a}),t(n,{id:`alert-description-${m??"default"}`,children:r}),(()=>{if(!p)return null;const e=p["data-testid"]??`action-button-${p.label.replace(/\s+/g,"-").toLowerCase()}`;return t(C,{children:t(u,{"aria-label":`${p.label} - ${a}`,"data-testid":e,fdKey:p.label,size:"small",variant:p.type??"primary",onClick:p.onClick,children:p.label})})})()]})}));h.displayName="Alert";export{h as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/Alert/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nimport { memo } from 'react';\n\nimport MuiAlert from '@mui/material/Alert';\nimport MuiAlertTitle from '@mui/material/AlertTitle';\nimport Box from '@mui/material/Box';\nimport { styled, type Theme, useTheme } from '@mui/material/styles';\n\nimport AlertIcon from '../../../icons/Alert';\nimport CancelCircleIcon from '../../../icons/CancelCircle';\nimport CheckmarkCircleIcon from '../../../icons/CheckmarkCircle';\nimport DiamondIcon from '../../../icons/Diamond';\nimport InformationCircleIcon from '../../../icons/InformationCircle';\nimport Button, { type ButtonType } from '../../Button';\n\n/** Visual tone of the alert */\nexport type AlertTones =\n | 'brand-inverse'\n | 'brand'\n | 'destructive'\n | 'information'\n | 'neutral-inverse'\n | 'neutral'\n | 'success'\n | 'warning';\n\n/** Props for the Alert component */\nexport interface AlertProps {\n /** Main heading text of the alert */\n title: string;\n /** Detailed description text of the alert */\n description: string;\n /** Visual tone of the alert */\n tone?: AlertTones;\n /** Callback function when the alert is closed */\n onClose?: () => void;\n /** Action button configuration */\n action?: {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n 'data-testid'?: string;\n };\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n}\n\nconst ICONS = {\n neutral: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-strong']} />,\n brand: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-primary']} />,\n destructive: (theme: Theme) => <CancelCircleIcon color={theme.palette.semantic.icon['icon-error']} />,\n warning: (theme: Theme) => <AlertIcon color={theme.palette.semantic.icon['icon-warning']} />,\n information: (theme: Theme) => (\n <InformationCircleIcon color={theme.palette.semantic.icon['icon-information']} />\n ),\n 'neutral-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n 'brand-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n success: (theme: Theme) => <CheckmarkCircleIcon color={theme.palette.semantic.icon['icon-success']} />,\n};\n\nconst COLOURS = {\n background: {\n neutral: (theme: Theme) => theme.palette.semantic.fill['fill-weak'],\n brand: (theme: Theme) => theme.palette.semantic.fill['fill-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.fill['fill-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.fill['fill-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.fill['fill-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.fill['fill-information-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.background['background-inverse'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.fill['fill-primary-strong'],\n },\n border: {\n neutral: (theme: Theme) => theme.palette.semantic.stroke['stroke-weak'],\n brand: (theme: Theme) => theme.palette.semantic.stroke['stroke-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.stroke['stroke-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.stroke['stroke-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.stroke['stroke-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.stroke['stroke-information-weak'],\n 'neutral-inverse': () => 'transparant',\n 'brand-inverse': () => 'transparant',\n },\n header: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n success: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n information: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n },\n text: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n success: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n information: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n },\n};\n\nconst getIcon = (theme: Theme, tone: AlertTones): JSX.Element => {\n return ICONS[tone](theme);\n};\n\nconst getBackgroundColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.background[tone](theme);\n};\n\nconst getBorderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.border[tone](theme);\n};\n\nconst getHeaderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.header[tone](theme);\n};\n\nconst getTextColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.text[tone](theme);\n};\n\nconst getButtonVariant = (type: ButtonType) => {\n switch (type) {\n case 'primary':\n return 'contained';\n case 'secondary':\n return 'outlined';\n default:\n return 'text';\n }\n};\n\ninterface StyledAlertProps {\n tone: AlertTones;\n}\n\nconst StyledActionContainer = styled(Box)(() => ({\n marginTop: '16px',\n}));\n\nconst StyledAlert = styled(MuiAlert, {\n shouldForwardProp: (prop) => !['tone'].includes(prop as string),\n})<StyledAlertProps>(({ theme, tone }) => ({\n backgroundColor: getBackgroundColour(theme, tone),\n border: '1px solid',\n borderColor: getBorderColour(theme, tone),\n color: getTextColour(theme, tone),\n}));\n\n/**\n * Alert component is used to display important messages or notifications to users.\n * It supports different visual tones to convey different semantic meanings and can include\n * an optional action button and close button.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed, which is beneficial for components\n * that may be used frequently throughout the application.\n */\nconst Alert = memo(\n ({\n title,\n description,\n tone = 'neutral',\n onClose,\n className,\n 'data-testid': dataTestId,\n action,\n }: AlertProps) => {\n const theme = useTheme();\n\n const renderAction = () => {\n if (action) {\n const actionTestId =\n action['data-testid'] ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n return (\n <StyledActionContainer>\n <Button\n aria-label={`${action.label} - ${title}`}\n data-testid={actionTestId}\n size=\"small\"\n variant={getButtonVariant(action.type ?? 'primary')}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n </StyledActionContainer>\n );\n }\n };\n\n return (\n <StyledAlert\n aria-describedby={`alert-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`alert-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n icon={getIcon(theme, tone)}\n role=\"alert\"\n tone={tone}\n onClose={onClose}\n >\n <MuiAlertTitle color={getHeaderColour(theme, tone)} id={`alert-title-${dataTestId ?? 'default'}`}>\n {title}\n </MuiAlertTitle>\n <Box id={`alert-description-${dataTestId ?? 'default'}`}>{description}</Box>\n {renderAction()}\n </StyledAlert>\n );\n },\n);\n\nAlert.displayName = 'Alert';\n\nexport default Alert;\n"],"names":["ICONS","neutral","theme","_jsx","DiamondIcon","color","palette","semantic","icon","brand","destructive","CancelCircleIcon","warning","AlertIcon","information","InformationCircleIcon","success","CheckmarkCircleIcon","COLOURS","background","fill","border","stroke","header","text","getIcon","tone","getBackgroundColour","getBorderColour","getHeaderColour","getTextColour","getButtonVariant","type","StyledActionContainer","styled","Box","marginTop","StyledAlert","MuiAlert","shouldForwardProp","prop","includes","backgroundColor","borderColor","Alert","memo","title","description","onClose","className","dataTestId","action","useTheme","_jsxs","role","children","MuiAlertTitle","id","actionTestId","label","replace","toLowerCase","Button","size","variant","onClick","renderAction","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/Alert/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nimport { memo } from 'react';\n\nimport MuiAlert from '@mui/material/Alert';\nimport MuiAlertTitle from '@mui/material/AlertTitle';\nimport Box from '@mui/material/Box';\nimport { styled, type Theme, useTheme } from '@mui/material/styles';\n\nimport AlertIcon from '../../../icons/Alert';\nimport CancelCircleIcon from '../../../icons/CancelCircle';\nimport CheckmarkCircleIcon from '../../../icons/CheckmarkCircle';\nimport DiamondIcon from '../../../icons/Diamond';\nimport InformationCircleIcon from '../../../icons/InformationCircle';\nimport Button from '../../atoms/Button';\nimport type { ButtonType } from '../../atoms/Button/getButtonStyles';\n\n/** Visual tone of the alert */\nexport type AlertTones =\n | 'brand-inverse'\n | 'brand'\n | 'destructive'\n | 'information'\n | 'neutral-inverse'\n | 'neutral'\n | 'success'\n | 'warning';\n\n/** Props for the Alert component */\nexport interface AlertProps {\n /** Main heading text of the alert */\n title: string;\n /** Detailed description text of the alert */\n description: string;\n /** Visual tone of the alert */\n tone?: AlertTones;\n /** Callback function when the alert is closed */\n onClose?: () => void;\n /** Action button configuration */\n action?: {\n /** Text label for the action button */\n label: string;\n /** Visual style of the action button */\n type?: ButtonType;\n /** Callback function when the action button is clicked */\n onClick: () => void;\n /** Test ID for the action button */\n 'data-testid'?: string;\n };\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n}\n\nconst ICONS = {\n neutral: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-strong']} />,\n brand: (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-primary']} />,\n destructive: (theme: Theme) => <CancelCircleIcon color={theme.palette.semantic.icon['icon-error']} />,\n warning: (theme: Theme) => <AlertIcon color={theme.palette.semantic.icon['icon-warning']} />,\n information: (theme: Theme) => (\n <InformationCircleIcon color={theme.palette.semantic.icon['icon-information']} />\n ),\n 'neutral-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n 'brand-inverse': (theme: Theme) => <DiamondIcon color={theme.palette.semantic.icon['icon-inverse']} />,\n success: (theme: Theme) => <CheckmarkCircleIcon color={theme.palette.semantic.icon['icon-success']} />,\n};\n\nconst COLOURS = {\n background: {\n neutral: (theme: Theme) => theme.palette.semantic.fill['fill-weak'],\n brand: (theme: Theme) => theme.palette.semantic.fill['fill-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.fill['fill-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.fill['fill-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.fill['fill-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.fill['fill-information-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.background['background-inverse'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.fill['fill-primary-strong'],\n },\n border: {\n neutral: (theme: Theme) => theme.palette.semantic.stroke['stroke-weak'],\n brand: (theme: Theme) => theme.palette.semantic.stroke['stroke-primary-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.stroke['stroke-error-weak'],\n warning: (theme: Theme) => theme.palette.semantic.stroke['stroke-warning-weak'],\n success: (theme: Theme) => theme.palette.semantic.stroke['stroke-success-weak'],\n information: (theme: Theme) => theme.palette.semantic.stroke['stroke-information-weak'],\n 'neutral-inverse': () => 'transparant',\n 'brand-inverse': () => 'transparant',\n },\n header: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n success: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n information: (theme: Theme) => theme.palette.semantic.text['text-strong'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-strong'],\n },\n text: {\n neutral: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n brand: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n destructive: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n warning: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n success: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n information: (theme: Theme) => theme.palette.semantic.text['text-weak'],\n 'neutral-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n 'brand-inverse': (theme: Theme) => theme.palette.semantic.text['text-inverse-weak'],\n },\n};\n\nconst getIcon = (theme: Theme, tone: AlertTones): JSX.Element => {\n return ICONS[tone](theme);\n};\n\nconst getBackgroundColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.background[tone](theme);\n};\n\nconst getBorderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.border[tone](theme);\n};\n\nconst getHeaderColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.header[tone](theme);\n};\n\nconst getTextColour = (theme: Theme, tone: AlertTones): string => {\n return COLOURS.text[tone](theme);\n};\n\ninterface StyledAlertProps {\n tone: AlertTones;\n}\n\nconst StyledActionContainer = styled(Box)(() => ({\n marginTop: '16px',\n}));\n\nconst StyledAlert = styled(MuiAlert, {\n shouldForwardProp: (prop) => !['tone'].includes(prop as string),\n})<StyledAlertProps>(({ theme, tone }) => ({\n backgroundColor: getBackgroundColour(theme, tone),\n border: '1px solid',\n borderColor: getBorderColour(theme, tone),\n color: getTextColour(theme, tone),\n}));\n\n/**\n * Alert component is used to display important messages or notifications to users.\n * It supports different visual tones to convey different semantic meanings and can include\n * an optional action button and close button.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed, which is beneficial for components\n * that may be used frequently throughout the application.\n */\nconst Alert = memo(\n ({\n title,\n description,\n tone = 'neutral',\n onClose,\n className,\n 'data-testid': dataTestId,\n action,\n }: AlertProps) => {\n const theme = useTheme();\n\n const renderAction = (): JSX.Element | null => {\n if (!action) {\n return null;\n }\n\n const actionTestId =\n action['data-testid'] ?? `action-button-${action.label.replace(/\\s+/g, '-').toLowerCase()}`;\n\n return (\n <StyledActionContainer>\n <Button\n aria-label={`${action.label} - ${title}`}\n data-testid={actionTestId}\n fdKey={action.label}\n size=\"small\"\n variant={action.type ?? 'primary'}\n onClick={action.onClick}\n >\n {action.label}\n </Button>\n </StyledActionContainer>\n );\n };\n\n return (\n <StyledAlert\n aria-describedby={`alert-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`alert-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n icon={getIcon(theme, tone)}\n role=\"alert\"\n tone={tone}\n onClose={onClose}\n >\n <MuiAlertTitle color={getHeaderColour(theme, tone)} id={`alert-title-${dataTestId ?? 'default'}`}>\n {title}\n </MuiAlertTitle>\n <Box id={`alert-description-${dataTestId ?? 'default'}`}>{description}</Box>\n {renderAction()}\n </StyledAlert>\n );\n },\n);\n\nAlert.displayName = 'Alert';\n\nexport default Alert;\n"],"names":["ICONS","neutral","theme","_jsx","DiamondIcon","color","palette","semantic","icon","brand","destructive","CancelCircleIcon","warning","AlertIcon","information","InformationCircleIcon","success","CheckmarkCircleIcon","COLOURS","background","fill","border","stroke","header","text","getIcon","tone","getBackgroundColour","getBorderColour","getHeaderColour","getTextColour","StyledActionContainer","styled","Box","marginTop","StyledAlert","MuiAlert","shouldForwardProp","prop","includes","backgroundColor","borderColor","Alert","memo","title","description","onClose","className","dataTestId","action","useTheme","_jsxs","role","children","MuiAlertTitle","id","actionTestId","label","replace","toLowerCase","Button","fdKey","size","variant","type","onClick","renderAction","displayName"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Modal/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Button, { type ButtonProps } from '@mui/material/Button';\nimport MuiModal from '@mui/material/Modal';\nimport Stack from '@mui/material/Stack';\nimport { styled, useTheme } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport { breakpointValues } from '../../../themes/tokens/breakpoints/breakpoints';\nimport IconContainer, { type IconContainerTones } from '../../atoms/IconContainer';\nimport Spacer from '../../Spacer';\n\n/** Visual tone of the modal */\nexport type ModalTones = 'default' | 'destructive';\n\n/** Size variants for the modal */\nexport type ModalSizes = 'large' | 'small';\n\n/** Action button configuration for Modal */\nexport interface ModalAction extends Omit<ButtonProps, 'color' | 'fullWidth'> {\n /** Label text for the button */\n label: string;\n /** Optional unique identifier for the button */\n id?: string;\n}\n\n/** Props for the Modal component */\nexport interface ModalProps {\n /** Whether the modal is open */\n open: boolean;\n /** Callback function when the modal is closed */\n onClose: () => void;\n /** Visual tone of the modal */\n tone?: ModalTones;\n /** Size variant of the modal */\n size?: ModalSizes;\n /** Main heading text of the modal */\n title?: string;\n /** Detailed description text of the modal */\n description?: string;\n /** Property element to display - can be an image URL (string) or an icon component (ReactNode) */\n property?: React.ReactNode | string;\n /** Array of action buttons to display */\n actions?: ModalAction[];\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n /** Content to display in the modal */\n children?: React.ReactNode;\n}\n\nconst COLOURS = {\n iconContainer: {\n default: (): IconContainerTones => 'neutral',\n destructive: (): IconContainerTones => 'destructive',\n },\n button: {\n default: (): ButtonProps['color'] => 'primary',\n destructive: (): ButtonProps['color'] => 'error',\n },\n};\n\nconst getIconContainerTone = (tone: ModalTones): IconContainerTones => {\n return COLOURS.iconContainer[tone]();\n};\n\nconst getButtonTone = (tone: ModalTones): ButtonProps['color'] => {\n return COLOURS.button[tone]();\n};\n\ninterface StyledModalBoxProps {\n tone: ModalTones;\n size: ModalSizes;\n}\n\nconst StyledModalBox = styled(Box, {\n shouldForwardProp: (prop) => !['tone', 'size'].includes(prop as string),\n})<StyledModalBoxProps>(({ theme, size }) => ({\n position: 'absolute',\n backgroundColor: theme.palette.semantic.background['background-overlay'],\n border: 'none',\n borderRadius: theme.radius['radius-16'],\n padding: theme.spacing(4),\n boxShadow: '0px 1px 6px 0px rgba(0, 0, 0, 0.10), 0px 8px 16px 0px rgba(0, 0, 0, 0.15)', // TODO: Pull shadow from tokens when setup\n outline: 'none',\n maxHeight: '90vh',\n overflowY: 'auto',\n\n // Desktop styles (default)\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n maxWidth: size === 'large' ? '700px' : '500px',\n width: `calc(100% - ${theme.spacing(4)})`,\n\n // Tablet & Mobile styles\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n // Small size at bottom of screen\n ...(size === 'small' && {\n maxWidth: `calc(100% - ${theme.spacing(4)})`,\n width: `calc(100% - ${theme.spacing(4)})`,\n top: 'auto',\n bottom: theme.spacing(2),\n left: theme.spacing(2),\n right: theme.spacing(2),\n transform: 'none',\n maxHeight: '70vh',\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n\n // Large size takes full screen\n ...(size === 'large' && {\n height: `calc(100% - ${theme.spacing(4)})`,\n maxHeight: `calc(100% - ${theme.spacing(4)})`,\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n },\n}));\n\nconst StyledImage = styled('img')(({ theme }) => ({\n width: '100%',\n height: 'auto',\n borderRadius: theme.radius['radius-8'],\n}));\n\nconst StyledButtonStack = styled(Stack)({\n justifyContent: 'flex-start',\n alignItems: 'center',\n});\n\nconst StyledContentContainer = styled(Box)(({ theme }) => ({\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n minHeight: 'min-content',\n paddingBottom: theme.spacing(3),\n },\n}));\n\n/**\n * Modal component is used to display content that temporarily blocks interaction with the main view.\n * It creates a focused mode for completing tasks or viewing important information without leaving the current page.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed.\n */\nconst Modal = memo(\n ({\n open,\n onClose,\n tone = 'default',\n size = 'large',\n title,\n description,\n property,\n actions = [],\n className,\n 'data-testid': dataTestId,\n children,\n }: ModalProps) => {\n const theme = useTheme();\n const isTabletOrMobile = useMediaQuery(theme.breakpoints.down(breakpointValues.tablet));\n\n const isImageUrl = typeof property === 'string';\n const showButtonSection = actions.length > 0;\n const buttonTone = getButtonTone(tone);\n\n return (\n <MuiModal\n aria-describedby={`modal-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`modal-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n open={open}\n onClose={onClose}\n >\n <StyledModalBox size={size} tone={tone}>\n <StyledContentContainer>\n {property && (\n <>\n {isImageUrl ? (\n <StyledImage alt={title ?? 'Modal image'} src={property} />\n ) : (\n <IconContainer icon={property} style=\"filled\" tone={getIconContainerTone(tone)} />\n )}\n <Spacer size={16} variant=\"horizontal\" />\n </>\n )}\n {title && (\n <Typography component=\"h2\" id={`modal-title-${dataTestId ?? 'default'}`} variant=\"h3Strong\">\n {title}\n </Typography>\n )}\n {title && description && <Spacer size={8} variant=\"horizontal\" />}\n {description && (\n <Typography\n color={theme.palette.semantic.text['text-weak']}\n id={`modal-description-${dataTestId ?? 'default'}`}\n variant=\"b1Weak\"\n >\n {description}\n </Typography>\n )}\n {children && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n {children}\n </>\n )}\n </StyledContentContainer>\n {showButtonSection && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n <StyledButtonStack direction={isTabletOrMobile ? 'column' : 'row'} spacing={2}>\n {actions.map((action) => {\n const { label, id, ...buttonProps } = action;\n return (\n <Button\n key={id || `modal-action-${label.replace(/\\s+/g, '-').toLowerCase()}`}\n color={buttonTone}\n fullWidth={isTabletOrMobile}\n {...buttonProps}\n >\n {label}\n </Button>\n );\n })}\n </StyledButtonStack>\n </>\n )}\n </StyledModalBox>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\nexport default Modal;\n"],"names":["COLOURS","iconContainer","default","destructive","button","getIconContainerTone","tone","StyledModalBox","styled","Box","shouldForwardProp","prop","includes","theme","size","position","backgroundColor","palette","semantic","background","border","borderRadius","radius","padding","spacing","boxShadow","outline","maxHeight","overflowY","top","left","transform","maxWidth","width","breakpoints","down","breakpointValues","tablet","bottom","right","display","flexDirection","height","StyledImage","StyledButtonStack","Stack","justifyContent","alignItems","StyledContentContainer","flexGrow","minHeight","paddingBottom","Modal","memo","open","onClose","title","description","property","actions","className","dataTestId","children","useTheme","isTabletOrMobile","useMediaQuery","isImageUrl","showButtonSection","length","buttonTone","getButtonTone","_jsx","jsx","MuiModal","_jsxs","jsxs","_Fragment","alt","src","IconContainer","icon","style","Spacer","variant","Typography","component","id","color","text","Fragment","direction","map","action","label","buttonProps","Button","fullWidth","replace","toLowerCase","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/molecules/Modal/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Button, { type ButtonProps } from '@mui/material/Button';\nimport MuiModal from '@mui/material/Modal';\nimport Stack from '@mui/material/Stack';\nimport { styled, useTheme } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport { breakpointValues } from '../../../themes/tokens/breakpoints/breakpoints';\nimport IconContainer, { type IconContainerTones } from '../../atoms/IconContainer';\nimport Spacer from '../../Spacer';\n\n/** Visual tone of the modal */\nexport type ModalTones = 'default' | 'destructive';\n\n/** Size variants for the modal */\nexport type ModalSizes = 'large' | 'small';\n\n/** Action button configuration for Modal */\nexport interface ModalAction extends Omit<ButtonProps, 'color' | 'fullWidth'> {\n /** Label text for the button */\n label: string;\n /** Optional unique identifier for the button */\n id?: string;\n}\n\n/** Props for the Modal component */\nexport interface ModalProps {\n /** Whether the modal is open */\n open: boolean;\n /** Callback function when the modal is closed */\n onClose: () => void;\n /** Visual tone of the modal */\n tone?: ModalTones;\n /** Size variant of the modal */\n size?: ModalSizes;\n /** Main heading text of the modal */\n title?: string;\n /** Detailed description text of the modal */\n description?: string;\n /** Property element to display - can be an image URL (string) or an icon component (ReactNode) */\n property?: React.ReactNode | string;\n /** Array of action buttons to display */\n actions?: ModalAction[];\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n /** Content to display in the modal */\n children?: React.ReactNode;\n}\n\nconst COLOURS = {\n iconContainer: {\n default: (): IconContainerTones => 'neutral',\n destructive: (): IconContainerTones => 'destructive',\n },\n button: {\n default: (): ButtonProps['color'] => 'primary',\n destructive: (): ButtonProps['color'] => 'error',\n },\n};\n\nconst getIconContainerTone = (tone: ModalTones): IconContainerTones => {\n return COLOURS.iconContainer[tone]();\n};\n\nconst getButtonTone = (tone: ModalTones): ButtonProps['color'] => {\n return COLOURS.button[tone]();\n};\n\ninterface StyledModalBoxProps {\n tone: ModalTones;\n size: ModalSizes;\n}\n\nconst StyledModalBox = styled(Box, {\n shouldForwardProp: (prop) => !['tone', 'size'].includes(prop as string),\n})<StyledModalBoxProps>(({ theme, size }) => ({\n position: 'absolute',\n backgroundColor: theme.palette.semantic.background['background-overlay'],\n border: 'none',\n borderRadius: theme.radius['radius-16'],\n padding: theme.spacing(4),\n boxShadow: '0px 1px 6px 0px rgba(0, 0, 0, 0.10), 0px 8px 16px 0px rgba(0, 0, 0, 0.15)', // TODO: Pull shadow from tokens when setup\n outline: 'none',\n maxHeight: '90vh',\n overflowY: 'auto',\n\n // Desktop styles (default)\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n maxWidth: size === 'large' ? '700px' : '500px',\n width: `calc(100% - ${theme.spacing(4)})`,\n\n // Tablet & Mobile styles\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n // Small size at bottom of screen\n ...(size === 'small' && {\n maxWidth: `calc(100% - ${theme.spacing(4)})`,\n width: `calc(100% - ${theme.spacing(4)})`,\n top: 'auto',\n bottom: theme.spacing(2),\n left: theme.spacing(2),\n right: theme.spacing(2),\n transform: 'none',\n maxHeight: '70vh',\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n\n // Large size takes full screen\n ...(size === 'large' && {\n height: `calc(100% - ${theme.spacing(4)})`,\n maxHeight: `calc(100% - ${theme.spacing(4)})`,\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n },\n}));\n\nconst StyledImage = styled('img')(({ theme }) => ({\n width: '100%',\n height: 'auto',\n borderRadius: theme.radius['radius-8'],\n}));\n\nconst StyledButtonStack = styled(Stack)({\n justifyContent: 'flex-start',\n alignItems: 'center',\n});\n\nconst StyledContentContainer = styled(Box)(({ theme }) => ({\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n minHeight: 'min-content',\n paddingBottom: theme.spacing(3),\n },\n}));\n\n/**\n * Modal component is used to display content that temporarily blocks interaction with the main view.\n * It creates a focused mode for completing tasks or viewing important information without leaving the current page.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed.\n */\nconst Modal = memo(\n ({\n open,\n onClose,\n tone = 'default',\n size = 'large',\n title,\n description,\n property,\n actions = [],\n className,\n 'data-testid': dataTestId,\n children,\n }: ModalProps) => {\n const theme = useTheme();\n const isTabletOrMobile = useMediaQuery(theme.breakpoints.down(breakpointValues.tablet));\n\n const isImageUrl = typeof property === 'string';\n const showButtonSection = actions.length > 0;\n const buttonTone = getButtonTone(tone);\n\n return (\n <MuiModal\n aria-describedby={`modal-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`modal-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n open={open}\n onClose={onClose}\n >\n <StyledModalBox size={size} tone={tone}>\n <StyledContentContainer>\n {property && (\n <>\n {isImageUrl ? (\n <StyledImage alt={title ?? 'Modal image'} src={property} />\n ) : (\n <IconContainer icon={property} style=\"filled\" tone={getIconContainerTone(tone)} />\n )}\n <Spacer size={16} variant=\"horizontal\" />\n </>\n )}\n {title && (\n <Typography component=\"h2\" id={`modal-title-${dataTestId ?? 'default'}`} variant=\"h3Strong\">\n {title}\n </Typography>\n )}\n {title && description && <Spacer size={8} variant=\"horizontal\" />}\n {description && (\n <Typography\n color={theme.palette.semantic.text['text-weak']}\n id={`modal-description-${dataTestId ?? 'default'}`}\n variant=\"b1Weak\"\n >\n {description}\n </Typography>\n )}\n {children && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n {children}\n </>\n )}\n </StyledContentContainer>\n {showButtonSection && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n <StyledButtonStack direction={isTabletOrMobile ? 'column' : 'row'} spacing={2}>\n {actions.map((action) => {\n const { label, id, ...buttonProps } = action;\n return (\n <Button\n key={id || `modal-action-${label.replace(/\\s+/g, '-').toLowerCase()}`}\n color={buttonTone}\n fullWidth={isTabletOrMobile}\n {...buttonProps}\n >\n {label}\n </Button>\n );\n })}\n </StyledButtonStack>\n </>\n )}\n </StyledModalBox>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\nexport default Modal;\n"],"names":["COLOURS","iconContainer","default","destructive","button","getIconContainerTone","tone","StyledModalBox","styled","Box","shouldForwardProp","prop","includes","theme","size","position","backgroundColor","palette","semantic","background","border","borderRadius","radius","padding","spacing","boxShadow","outline","maxHeight","overflowY","top","left","transform","maxWidth","width","breakpoints","down","breakpointValues","tablet","bottom","right","display","flexDirection","height","StyledImage","StyledButtonStack","Stack","justifyContent","alignItems","StyledContentContainer","flexGrow","minHeight","paddingBottom","Modal","memo","open","onClose","title","description","property","actions","className","dataTestId","children","useTheme","isTabletOrMobile","useMediaQuery","isImageUrl","showButtonSection","length","buttonTone","getButtonTone","_jsx","jsx","MuiModal","_jsxs","jsxs","_Fragment","alt","src","IconContainer","icon","style","Spacer","variant","Typography","component","id","color","text","Fragment","direction","map","action","label","buttonProps","Button","fullWidth","replace","toLowerCase","displayName"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/Modal/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Button, { type ButtonProps } from '@mui/material/Button';\nimport MuiModal from '@mui/material/Modal';\nimport Stack from '@mui/material/Stack';\nimport { styled, useTheme } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport { breakpointValues } from '../../../themes/tokens/breakpoints/breakpoints';\nimport IconContainer, { type IconContainerTones } from '../../atoms/IconContainer';\nimport Spacer from '../../Spacer';\n\n/** Visual tone of the modal */\nexport type ModalTones = 'default' | 'destructive';\n\n/** Size variants for the modal */\nexport type ModalSizes = 'large' | 'small';\n\n/** Action button configuration for Modal */\nexport interface ModalAction extends Omit<ButtonProps, 'color' | 'fullWidth'> {\n /** Label text for the button */\n label: string;\n /** Optional unique identifier for the button */\n id?: string;\n}\n\n/** Props for the Modal component */\nexport interface ModalProps {\n /** Whether the modal is open */\n open: boolean;\n /** Callback function when the modal is closed */\n onClose: () => void;\n /** Visual tone of the modal */\n tone?: ModalTones;\n /** Size variant of the modal */\n size?: ModalSizes;\n /** Main heading text of the modal */\n title?: string;\n /** Detailed description text of the modal */\n description?: string;\n /** Property element to display - can be an image URL (string) or an icon component (ReactNode) */\n property?: React.ReactNode | string;\n /** Array of action buttons to display */\n actions?: ModalAction[];\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n /** Content to display in the modal */\n children?: React.ReactNode;\n}\n\nconst COLOURS = {\n iconContainer: {\n default: (): IconContainerTones => 'neutral',\n destructive: (): IconContainerTones => 'destructive',\n },\n button: {\n default: (): ButtonProps['color'] => 'primary',\n destructive: (): ButtonProps['color'] => 'error',\n },\n};\n\nconst getIconContainerTone = (tone: ModalTones): IconContainerTones => {\n return COLOURS.iconContainer[tone]();\n};\n\nconst getButtonTone = (tone: ModalTones): ButtonProps['color'] => {\n return COLOURS.button[tone]();\n};\n\ninterface StyledModalBoxProps {\n tone: ModalTones;\n size: ModalSizes;\n}\n\nconst StyledModalBox = styled(Box, {\n shouldForwardProp: (prop) => !['tone', 'size'].includes(prop as string),\n})<StyledModalBoxProps>(({ theme, size }) => ({\n position: 'absolute',\n backgroundColor: theme.palette.semantic.background['background-overlay'],\n border: 'none',\n borderRadius: theme.radius['radius-16'],\n padding: theme.spacing(4),\n boxShadow: '0px 1px 6px 0px rgba(0, 0, 0, 0.10), 0px 8px 16px 0px rgba(0, 0, 0, 0.15)', // TODO: Pull shadow from tokens when setup\n outline: 'none',\n maxHeight: '90vh',\n overflowY: 'auto',\n\n // Desktop styles (default)\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n maxWidth: size === 'large' ? '700px' : '500px',\n width: `calc(100% - ${theme.spacing(4)})`,\n\n // Tablet & Mobile styles\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n // Small size at bottom of screen\n ...(size === 'small' && {\n maxWidth: `calc(100% - ${theme.spacing(4)})`,\n width: `calc(100% - ${theme.spacing(4)})`,\n top: 'auto',\n bottom: theme.spacing(2),\n left: theme.spacing(2),\n right: theme.spacing(2),\n transform: 'none',\n maxHeight: '70vh',\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n\n // Large size takes full screen\n ...(size === 'large' && {\n height: `calc(100% - ${theme.spacing(4)})`,\n maxHeight: `calc(100% - ${theme.spacing(4)})`,\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n },\n}));\n\nconst StyledImage = styled('img')(({ theme }) => ({\n width: '100%',\n height: 'auto',\n borderRadius: theme.radius['radius-8'],\n}));\n\nconst StyledButtonStack = styled(Stack)({\n justifyContent: 'flex-start',\n alignItems: 'center',\n});\n\nconst StyledContentContainer = styled(Box)(({ theme }) => ({\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n minHeight: 'min-content',\n paddingBottom: theme.spacing(3),\n },\n}));\n\n/**\n * Modal component is used to display content that temporarily blocks interaction with the main view.\n * It creates a focused mode for completing tasks or viewing important information without leaving the current page.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed.\n */\nconst Modal = memo(\n ({\n open,\n onClose,\n tone = 'default',\n size = 'large',\n title,\n description,\n property,\n actions = [],\n className,\n 'data-testid': dataTestId,\n children,\n }: ModalProps) => {\n const theme = useTheme();\n const isTabletOrMobile = useMediaQuery(theme.breakpoints.down(breakpointValues.tablet));\n\n const isImageUrl = typeof property === 'string';\n const showButtonSection = actions.length > 0;\n const buttonTone = getButtonTone(tone);\n\n return (\n <MuiModal\n aria-describedby={`modal-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`modal-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n open={open}\n onClose={onClose}\n >\n <StyledModalBox size={size} tone={tone}>\n <StyledContentContainer>\n {property && (\n <>\n {isImageUrl ? (\n <StyledImage alt={title ?? 'Modal image'} src={property} />\n ) : (\n <IconContainer icon={property} style=\"filled\" tone={getIconContainerTone(tone)} />\n )}\n <Spacer size={16} variant=\"horizontal\" />\n </>\n )}\n {title && (\n <Typography component=\"h2\" id={`modal-title-${dataTestId ?? 'default'}`} variant=\"h3Strong\">\n {title}\n </Typography>\n )}\n {title && description && <Spacer size={8} variant=\"horizontal\" />}\n {description && (\n <Typography\n color={theme.palette.semantic.text['text-weak']}\n id={`modal-description-${dataTestId ?? 'default'}`}\n variant=\"b1Weak\"\n >\n {description}\n </Typography>\n )}\n {children && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n {children}\n </>\n )}\n </StyledContentContainer>\n {showButtonSection && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n <StyledButtonStack direction={isTabletOrMobile ? 'column' : 'row'} spacing={2}>\n {actions.map((action) => {\n const { label, id, ...buttonProps } = action;\n return (\n <Button\n key={id || `modal-action-${label.replace(/\\s+/g, '-').toLowerCase()}`}\n color={buttonTone}\n fullWidth={isTabletOrMobile}\n {...buttonProps}\n >\n {label}\n </Button>\n );\n })}\n </StyledButtonStack>\n </>\n )}\n </StyledModalBox>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\nexport default Modal;\n"],"names":["COLOURS","iconContainer","default","destructive","button","getIconContainerTone","tone","StyledModalBox","styled","Box","shouldForwardProp","prop","includes","theme","size","position","backgroundColor","palette","semantic","background","border","borderRadius","radius","padding","spacing","boxShadow","outline","maxHeight","overflowY","top","left","transform","maxWidth","width","breakpoints","down","breakpointValues","tablet","bottom","right","display","flexDirection","height","StyledImage","StyledButtonStack","Stack","justifyContent","alignItems","StyledContentContainer","flexGrow","minHeight","paddingBottom","Modal","memo","open","onClose","title","description","property","actions","className","dataTestId","children","useTheme","isTabletOrMobile","useMediaQuery","isImageUrl","showButtonSection","length","buttonTone","getButtonTone","_jsx","MuiModal","_jsxs","_Fragment","alt","src","IconContainer","icon","style","Spacer","variant","Typography","component","id","color","text","direction","map","action","label","buttonProps","Button","fullWidth","replace","toLowerCase","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/molecules/Modal/index.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/explicit-function-return-type */\nimport { memo } from 'react';\n\nimport Box from '@mui/material/Box';\nimport Button, { type ButtonProps } from '@mui/material/Button';\nimport MuiModal from '@mui/material/Modal';\nimport Stack from '@mui/material/Stack';\nimport { styled, useTheme } from '@mui/material/styles';\nimport Typography from '@mui/material/Typography';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport { breakpointValues } from '../../../themes/tokens/breakpoints/breakpoints';\nimport IconContainer, { type IconContainerTones } from '../../atoms/IconContainer';\nimport Spacer from '../../Spacer';\n\n/** Visual tone of the modal */\nexport type ModalTones = 'default' | 'destructive';\n\n/** Size variants for the modal */\nexport type ModalSizes = 'large' | 'small';\n\n/** Action button configuration for Modal */\nexport interface ModalAction extends Omit<ButtonProps, 'color' | 'fullWidth'> {\n /** Label text for the button */\n label: string;\n /** Optional unique identifier for the button */\n id?: string;\n}\n\n/** Props for the Modal component */\nexport interface ModalProps {\n /** Whether the modal is open */\n open: boolean;\n /** Callback function when the modal is closed */\n onClose: () => void;\n /** Visual tone of the modal */\n tone?: ModalTones;\n /** Size variant of the modal */\n size?: ModalSizes;\n /** Main heading text of the modal */\n title?: string;\n /** Detailed description text of the modal */\n description?: string;\n /** Property element to display - can be an image URL (string) or an icon component (ReactNode) */\n property?: React.ReactNode | string;\n /** Array of action buttons to display */\n actions?: ModalAction[];\n /** Additional CSS class names */\n className?: string;\n /** Test ID for testing and automation */\n 'data-testid'?: string;\n /** Content to display in the modal */\n children?: React.ReactNode;\n}\n\nconst COLOURS = {\n iconContainer: {\n default: (): IconContainerTones => 'neutral',\n destructive: (): IconContainerTones => 'destructive',\n },\n button: {\n default: (): ButtonProps['color'] => 'primary',\n destructive: (): ButtonProps['color'] => 'error',\n },\n};\n\nconst getIconContainerTone = (tone: ModalTones): IconContainerTones => {\n return COLOURS.iconContainer[tone]();\n};\n\nconst getButtonTone = (tone: ModalTones): ButtonProps['color'] => {\n return COLOURS.button[tone]();\n};\n\ninterface StyledModalBoxProps {\n tone: ModalTones;\n size: ModalSizes;\n}\n\nconst StyledModalBox = styled(Box, {\n shouldForwardProp: (prop) => !['tone', 'size'].includes(prop as string),\n})<StyledModalBoxProps>(({ theme, size }) => ({\n position: 'absolute',\n backgroundColor: theme.palette.semantic.background['background-overlay'],\n border: 'none',\n borderRadius: theme.radius['radius-16'],\n padding: theme.spacing(4),\n boxShadow: '0px 1px 6px 0px rgba(0, 0, 0, 0.10), 0px 8px 16px 0px rgba(0, 0, 0, 0.15)', // TODO: Pull shadow from tokens when setup\n outline: 'none',\n maxHeight: '90vh',\n overflowY: 'auto',\n\n // Desktop styles (default)\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n maxWidth: size === 'large' ? '700px' : '500px',\n width: `calc(100% - ${theme.spacing(4)})`,\n\n // Tablet & Mobile styles\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n // Small size at bottom of screen\n ...(size === 'small' && {\n maxWidth: `calc(100% - ${theme.spacing(4)})`,\n width: `calc(100% - ${theme.spacing(4)})`,\n top: 'auto',\n bottom: theme.spacing(2),\n left: theme.spacing(2),\n right: theme.spacing(2),\n transform: 'none',\n maxHeight: '70vh',\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n\n // Large size takes full screen\n ...(size === 'large' && {\n height: `calc(100% - ${theme.spacing(4)})`,\n maxHeight: `calc(100% - ${theme.spacing(4)})`,\n overflowY: 'auto',\n // Flex layout to push buttons to bottom when content is small\n display: 'flex',\n flexDirection: 'column',\n }),\n },\n}));\n\nconst StyledImage = styled('img')(({ theme }) => ({\n width: '100%',\n height: 'auto',\n borderRadius: theme.radius['radius-8'],\n}));\n\nconst StyledButtonStack = styled(Stack)({\n justifyContent: 'flex-start',\n alignItems: 'center',\n});\n\nconst StyledContentContainer = styled(Box)(({ theme }) => ({\n [theme.breakpoints.down(breakpointValues.tablet)]: {\n flexGrow: 1,\n display: 'flex',\n flexDirection: 'column',\n minHeight: 'min-content',\n paddingBottom: theme.spacing(3),\n },\n}));\n\n/**\n * Modal component is used to display content that temporarily blocks interaction with the main view.\n * It creates a focused mode for completing tasks or viewing important information without leaving the current page.\n *\n * The component is wrapped with React.memo to optimize performance by preventing unnecessary\n * re-renders when the component's props haven't changed.\n */\nconst Modal = memo(\n ({\n open,\n onClose,\n tone = 'default',\n size = 'large',\n title,\n description,\n property,\n actions = [],\n className,\n 'data-testid': dataTestId,\n children,\n }: ModalProps) => {\n const theme = useTheme();\n const isTabletOrMobile = useMediaQuery(theme.breakpoints.down(breakpointValues.tablet));\n\n const isImageUrl = typeof property === 'string';\n const showButtonSection = actions.length > 0;\n const buttonTone = getButtonTone(tone);\n\n return (\n <MuiModal\n aria-describedby={`modal-description-${dataTestId ?? 'default'}`}\n aria-labelledby={`modal-title-${dataTestId ?? 'default'}`}\n className={className}\n data-testid={dataTestId}\n open={open}\n onClose={onClose}\n >\n <StyledModalBox size={size} tone={tone}>\n <StyledContentContainer>\n {property && (\n <>\n {isImageUrl ? (\n <StyledImage alt={title ?? 'Modal image'} src={property} />\n ) : (\n <IconContainer icon={property} style=\"filled\" tone={getIconContainerTone(tone)} />\n )}\n <Spacer size={16} variant=\"horizontal\" />\n </>\n )}\n {title && (\n <Typography component=\"h2\" id={`modal-title-${dataTestId ?? 'default'}`} variant=\"h3Strong\">\n {title}\n </Typography>\n )}\n {title && description && <Spacer size={8} variant=\"horizontal\" />}\n {description && (\n <Typography\n color={theme.palette.semantic.text['text-weak']}\n id={`modal-description-${dataTestId ?? 'default'}`}\n variant=\"b1Weak\"\n >\n {description}\n </Typography>\n )}\n {children && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n {children}\n </>\n )}\n </StyledContentContainer>\n {showButtonSection && (\n <>\n <Spacer size={24} variant=\"horizontal\" />\n <StyledButtonStack direction={isTabletOrMobile ? 'column' : 'row'} spacing={2}>\n {actions.map((action) => {\n const { label, id, ...buttonProps } = action;\n return (\n <Button\n key={id || `modal-action-${label.replace(/\\s+/g, '-').toLowerCase()}`}\n color={buttonTone}\n fullWidth={isTabletOrMobile}\n {...buttonProps}\n >\n {label}\n </Button>\n );\n })}\n </StyledButtonStack>\n </>\n )}\n </StyledModalBox>\n </MuiModal>\n );\n },\n);\n\nModal.displayName = 'Modal';\n\nexport default Modal;\n"],"names":["COLOURS","iconContainer","default","destructive","button","getIconContainerTone","tone","StyledModalBox","styled","Box","shouldForwardProp","prop","includes","theme","size","position","backgroundColor","palette","semantic","background","border","borderRadius","radius","padding","spacing","boxShadow","outline","maxHeight","overflowY","top","left","transform","maxWidth","width","breakpoints","down","breakpointValues","tablet","bottom","right","display","flexDirection","height","StyledImage","StyledButtonStack","Stack","justifyContent","alignItems","StyledContentContainer","flexGrow","minHeight","paddingBottom","Modal","memo","open","onClose","title","description","property","actions","className","dataTestId","children","useTheme","isTabletOrMobile","useMediaQuery","isImageUrl","showButtonSection","length","buttonTone","getButtonTone","_jsx","MuiModal","_jsxs","_Fragment","alt","src","IconContainer","icon","style","Spacer","variant","Typography","component","id","color","text","direction","map","action","label","buttonProps","Button","fullWidth","replace","toLowerCase","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var t=require("react");const e=["orgId","appId",{key:"isFlipdishStaff",type:"boolean"}],n=(t,e)=>t||"boolean"===e?"boolean"===e?"true"===t:"number"===e?Number(t):t:null,
|
|
1
|
+
"use strict";var t=require("react");const e=["orgId","appId",{key:"isFlipdishStaff",type:"boolean"}],n=(t,e)=>t||"boolean"===e?"boolean"===e?"true"===t:"number"===e?Number(t):t:null,r=t=>[...e.map((t=>"string"==typeof t?t:t.key)),...t.map((t=>"string"==typeof t?t:t.key))];module.exports=(o=[])=>{const[s,i]=t.useState((()=>(t=>{const e=r(t),n={};return e.forEach((t=>{const e="string"==typeof t?t:t.key;n[e]=null})),n})(o)));return t.useEffect((()=>{const t=document.getElementById("flipdish-micro-frontend");if(!t)return void console.warn("Micro-frontend div not found");const s=r(o),u=[...e,...o],c=()=>{i((e=>{const r={...e};let o=!1;return s.forEach((e=>{const{value:s,key:i}=((t,e,r)=>{const o=((t,e)=>e.find((e=>"string"==typeof e?e===t:e.key===t)))(t,r),s=(t=>t&&"string"!=typeof t&&"type"in t?t.type??"string":"string")(o),i="string"==typeof t?t:t.key,u=(void 0)[`VITE_${i.toUpperCase()}_OVERRIDE`],c=`data-${i}`,a=e.getAttribute(c);return{value:n(u?u.toString():a,s),key:i}})(e,t,u);r[i]!==s&&(r[i]=s,o=!0)})),o?r:e}))};c();const a=new MutationObserver(c);return a.observe(t,{attributes:!0}),()=>a.disconnect()}),[o]),s};
|
|
2
2
|
//# sourceMappingURL=useMicroFrontendAttributes.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMicroFrontendAttributes.cjs.js","sources":["../../src/custom-hooks/useMicroFrontendAttributes.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype KeyType = '
|
|
1
|
+
{"version":3,"file":"useMicroFrontendAttributes.cjs.js","sources":["../../src/custom-hooks/useMicroFrontendAttributes.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype KeyType = 'boolean' | 'number' | 'string';\n\ninterface KeyConfig {\n key: string;\n type?: KeyType; // type is optional, defaults to 'string'\n}\n\nconst ALWAYS_RETURN_KEYS: (KeyConfig | string)[] = [\n 'orgId',\n 'appId',\n { key: 'isFlipdishStaff', type: 'boolean' },\n] as const;\n\ntype AlwaysReturnKeys = (typeof ALWAYS_RETURN_KEYS)[number] extends KeyConfig\n ? (typeof ALWAYS_RETURN_KEYS)[number]['key']\n : (typeof ALWAYS_RETURN_KEYS)[number];\n\ntype ExtractKey<T> = T extends KeyConfig ? T['key'] : T;\n\ntype AttributeValue = boolean | number | string | null;\n\n// Utility functions moved outside\ntype KeyArg<T> = AlwaysReturnKeys | T | string;\nconst getKeyConfig = <T extends KeyConfig | string>(key: KeyArg<T>, allConfigs: (KeyConfig | string)[]) => {\n return allConfigs.find((config) => (typeof config === 'string' ? config === key : config.key === key));\n};\n\nconst getValueType = (keyConfig: KeyConfig | string | undefined): KeyType => {\n return keyConfig && typeof keyConfig !== 'string' && 'type' in keyConfig\n ? (keyConfig.type ?? 'string')\n : 'string';\n};\n\nconst parseValue = (value: string | null, type: KeyType): AttributeValue => {\n if (!value && type !== 'boolean') return null;\n if (type === 'boolean') return value === 'true';\n if (type === 'number') return Number(value);\n return value;\n};\n\nconst getAllKeys = <T extends KeyConfig | string>(\n customKeys: (KeyConfig | T)[],\n): (AlwaysReturnKeys | T | string)[] => {\n return [\n ...ALWAYS_RETURN_KEYS.map((key) => (typeof key === 'string' ? key : key.key)),\n ...customKeys.map((key) => (typeof key === 'string' ? key : key.key)),\n ];\n};\n\nconst getInitialState = <T extends KeyConfig | string>(\n customKeys: (KeyConfig | T)[],\n): Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue> => {\n const allKeys = getAllKeys(customKeys);\n const initialState = {} as Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue>;\n allKeys.forEach((key) => {\n const typedKey = (typeof key === 'string' ? key : key.key) as ExtractKey<AlwaysReturnKeys | T>;\n initialState[typedKey] = null;\n });\n return initialState;\n};\n\nconst processAttribute = <T extends KeyConfig | string>(\n key: AlwaysReturnKeys | T | string,\n microFrontendDiv: HTMLElement,\n allConfigs: (KeyConfig | string)[],\n): { value: AttributeValue; key: ExtractKey<AlwaysReturnKeys | T> } => {\n const keyConfig = getKeyConfig(key, allConfigs);\n const type = getValueType(keyConfig);\n const keyString = typeof key === 'string' ? key : key.key;\n\n const envVar = import.meta.env[`VITE_${keyString.toUpperCase()}_OVERRIDE`] as string | null | undefined;\n const attributeKey = `data-${keyString}`;\n const domValue = microFrontendDiv.getAttribute(attributeKey);\n\n const value = envVar ? parseValue(envVar.toString(), type) : parseValue(domValue, type);\n return { value, key: keyString as ExtractKey<AlwaysReturnKeys | T> };\n};\n\n/**\n * Custom hook to manage micro-frontend attributes.\n *\n * This hook initializes and updates a set of attributes based on a combination of predefined keys (ALWAYS_RETURN_KEYS)\n * and custom keys provided as arguments. The attributes are fetched from environment variables or DOM attributes\n * and are updated dynamically using a MutationObserver.\n *\n * @template T - The type of custom keys, which can be either a string or a KeyConfig object.\n *\n * @param {Array<T | KeyConfig>} [customKeys=[]] - An array of custom keys or KeyConfig objects to be included in the attributes.\n *\n * @returns {Record<ExtractKey<AlwaysReturnKeys | T>, string | boolean | number | null>} - A record of attributes with their values.\n *\n * @example\n * const attributes = useMicroFrontendAttributes(['customKey1', { key: 'customKey2', type: 'boolean' }]);\n * console.log(attributes);\n */\nconst useMicroFrontendAttributes = <T extends KeyConfig | string>(\n customKeys: (KeyConfig | T)[] = [],\n): Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue> => {\n const [attributes, setAttributes] = useState(() => getInitialState(customKeys));\n\n useEffect(() => {\n const microFrontendDiv = document.getElementById('flipdish-micro-frontend');\n if (!microFrontendDiv) {\n console.warn('Micro-frontend div not found');\n return;\n }\n\n const allKeys = getAllKeys(customKeys);\n const allConfigs = [...ALWAYS_RETURN_KEYS, ...customKeys];\n\n const updateValues = () => {\n setAttributes((prev) => {\n const newAttributes = { ...prev };\n let isChanged = false;\n\n allKeys.forEach((key) => {\n const { value, key: typedKey } = processAttribute(key, microFrontendDiv, allConfigs);\n if (newAttributes[typedKey] !== value) {\n newAttributes[typedKey] = value;\n isChanged = true;\n }\n });\n\n return isChanged ? newAttributes : prev;\n });\n };\n\n updateValues();\n\n const observer = new MutationObserver(updateValues);\n observer.observe(microFrontendDiv, { attributes: true });\n\n return () => observer.disconnect();\n }, [customKeys]);\n\n return attributes;\n};\n\nexport default useMicroFrontendAttributes;\n"],"names":["ALWAYS_RETURN_KEYS","key","type","parseValue","value","Number","getAllKeys","customKeys","map","attributes","setAttributes","useState","allKeys","initialState","forEach","typedKey","getInitialState","useEffect","microFrontendDiv","document","getElementById","console","warn","allConfigs","updateValues","prev","newAttributes","isChanged","keyConfig","find","config","getKeyConfig","getValueType","keyString","envVar","undefined","toUpperCase","attributeKey","domValue","getAttribute","toString","processAttribute","observer","MutationObserver","observe","disconnect"],"mappings":"oCASA,MAAMA,EAA6C,CACjD,QACA,QACA,CAAEC,IAAK,kBAAmBC,KAAM,YAuB5BC,EAAa,CAACC,EAAsBF,IACnCE,GAAkB,YAATF,EACD,YAATA,EAAqC,SAAVE,EAClB,WAATF,EAA0BG,OAAOD,GAC9BA,EAHkC,KAMrCE,EACJC,GAEO,IACFP,EAAmBQ,KAAKP,GAAwB,iBAARA,EAAmBA,EAAMA,EAAIA,SACrEM,EAAWC,KAAKP,GAAwB,iBAARA,EAAmBA,EAAMA,EAAIA,sBAkDjC,CACjCM,EAAgC,MAEhC,MAAOE,EAAYC,GAAiBC,EAAQA,UAAC,IAjDvB,CACtBJ,IAEA,MAAMK,EAAUN,EAAWC,GACrBM,EAAe,CAA8D,EAKnF,OAJAD,EAAQE,SAASb,IACf,MAAMc,EAA2B,iBAARd,EAAmBA,EAAMA,EAAIA,IACtDY,EAAaE,GAAY,QAEpBF,GAwC4CG,CAAgBT,KAqCnE,OAnCAU,EAAAA,WAAU,KACR,MAAMC,EAAmBC,SAASC,eAAe,2BACjD,IAAKF,EAEH,YADAG,QAAQC,KAAK,gCAIf,MAAMV,EAAUN,EAAWC,GACrBgB,EAAa,IAAIvB,KAAuBO,GAExCiB,EAAe,KACnBd,GAAee,IACb,MAAMC,EAAgB,IAAKD,GAC3B,IAAIE,GAAY,EAUhB,OARAf,EAAQE,SAASb,IACf,MAAMG,MAAEA,EAAOH,IAAKc,GAvDL,EACvBd,EACAiB,EACAK,KAEA,MAAMK,EA3Ca,EAA+B3B,EAAgBsB,IAC3DA,EAAWM,MAAMC,GAA8B,iBAAXA,EAAsBA,IAAW7B,EAAM6B,EAAO7B,MAAQA,IA0C/E8B,CAAa9B,EAAKsB,GAC9BrB,EAxCa,CAAC0B,GACbA,GAAkC,iBAAdA,GAA0B,SAAUA,EAC1DA,EAAU1B,MAAQ,SACnB,SAqCS8B,CAAaJ,GACpBK,EAA2B,iBAARhC,EAAmBA,EAAMA,EAAIA,IAEhDiC,QAASC,GAAgB,QAAQF,EAAUG,0BAC3CC,EAAe,QAAQJ,IACvBK,EAAWpB,EAAiBqB,aAAaF,GAG/C,MAAO,CAAEjC,MADcD,EAAT+B,EAAoBA,EAAOM,WAA+BF,EAAnBpC,GACrCD,IAAKgC,IAyCoBQ,CAAiBxC,EAAKiB,EAAkBK,GACrEG,EAAcX,KAAcX,IAC9BsB,EAAcX,GAAYX,EAC1BuB,GAAY,MAITA,EAAYD,EAAgBD,MAIvCD,IAEA,MAAMkB,EAAW,IAAIC,iBAAiBnB,GAGtC,OAFAkB,EAASE,QAAQ1B,EAAkB,CAAET,YAAY,IAE1C,IAAMiC,EAASG,eACrB,CAACtC,IAEGE"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
type KeyType = '
|
|
1
|
+
type KeyType = 'boolean' | 'number' | 'string';
|
|
2
2
|
interface KeyConfig {
|
|
3
3
|
key: string;
|
|
4
4
|
type?: KeyType;
|
|
5
5
|
}
|
|
6
|
-
declare const ALWAYS_RETURN_KEYS: (
|
|
6
|
+
declare const ALWAYS_RETURN_KEYS: (KeyConfig | string)[];
|
|
7
7
|
type AlwaysReturnKeys = (typeof ALWAYS_RETURN_KEYS)[number] extends KeyConfig ? (typeof ALWAYS_RETURN_KEYS)[number]['key'] : (typeof ALWAYS_RETURN_KEYS)[number];
|
|
8
8
|
type ExtractKey<T> = T extends KeyConfig ? T['key'] : T;
|
|
9
|
-
type AttributeValue =
|
|
9
|
+
type AttributeValue = boolean | number | string | null;
|
|
10
10
|
/**
|
|
11
11
|
* Custom hook to manage micro-frontend attributes.
|
|
12
12
|
*
|
|
@@ -24,6 +24,6 @@ type AttributeValue = string | boolean | number | null;
|
|
|
24
24
|
* const attributes = useMicroFrontendAttributes(['customKey1', { key: 'customKey2', type: 'boolean' }]);
|
|
25
25
|
* console.log(attributes);
|
|
26
26
|
*/
|
|
27
|
-
declare const useMicroFrontendAttributes: <T extends string | KeyConfig>(customKeys?: (
|
|
27
|
+
declare const useMicroFrontendAttributes: <T extends string | KeyConfig>(customKeys?: (KeyConfig | T)[]) => Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue>;
|
|
28
28
|
|
|
29
29
|
export { useMicroFrontendAttributes as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useState as t,useEffect as e}from"react";const n=["orgId","appId",{key:"isFlipdishStaff",type:"boolean"}],o=(t,e)=>t||"boolean"===e?"boolean"===e?"true"===t:"number"===e?Number(t):t:null,r=t=>[...n.map((t=>"string"==typeof t?t:t.key)),...t.map((t=>"string"==typeof t?t:t.key))],s=(s=[])=>{const[i,a]=t((()=>(t=>{const e=r(t),n={};return e.forEach((t=>{const e="string"==typeof t?t:t.key;n[e]=null})),n})(s)));return e((()=>{const t=document.getElementById("flipdish-micro-frontend");if(!t)return void console.warn("Micro-frontend div not found");const e=r(s),i=[...n,...s],p=()=>{a((n=>{const r={...n};let s=!1;return e.forEach((e=>{const{value:n,key:a}=((t,e,n)=>{const r=((t,e)=>e.find((e=>"string"==typeof e?e===t:e.key===t)))(t,n),s=(t=>t&&"string"!=typeof t&&"type"in t?t.type:"string")(r),i="string"==typeof t?t:t.key,a=import.meta.env[`VITE_${i.toUpperCase()}_OVERRIDE`],p=`data-${i}`,c=e.getAttribute(p);return{value:o(a?a.toString():c,s),key:i}})(e,t,i);r[a]!==n&&(r[a]=n,s=!0)})),s?r:n}))};p();const c=new MutationObserver(p);return c.observe(t,{attributes:!0}),()=>c.disconnect()}),[s]),i};export{s as default};
|
|
1
|
+
import{useState as t,useEffect as e}from"react";const n=["orgId","appId",{key:"isFlipdishStaff",type:"boolean"}],o=(t,e)=>t||"boolean"===e?"boolean"===e?"true"===t:"number"===e?Number(t):t:null,r=t=>[...n.map((t=>"string"==typeof t?t:t.key)),...t.map((t=>"string"==typeof t?t:t.key))],s=(s=[])=>{const[i,a]=t((()=>(t=>{const e=r(t),n={};return e.forEach((t=>{const e="string"==typeof t?t:t.key;n[e]=null})),n})(s)));return e((()=>{const t=document.getElementById("flipdish-micro-frontend");if(!t)return void console.warn("Micro-frontend div not found");const e=r(s),i=[...n,...s],p=()=>{a((n=>{const r={...n};let s=!1;return e.forEach((e=>{const{value:n,key:a}=((t,e,n)=>{const r=((t,e)=>e.find((e=>"string"==typeof e?e===t:e.key===t)))(t,n),s=(t=>t&&"string"!=typeof t&&"type"in t?t.type??"string":"string")(r),i="string"==typeof t?t:t.key,a=import.meta.env[`VITE_${i.toUpperCase()}_OVERRIDE`],p=`data-${i}`,c=e.getAttribute(p);return{value:o(a?a.toString():c,s),key:i}})(e,t,i);r[a]!==n&&(r[a]=n,s=!0)})),s?r:n}))};p();const c=new MutationObserver(p);return c.observe(t,{attributes:!0}),()=>c.disconnect()}),[s]),i};export{s as default};
|
|
2
2
|
//# sourceMappingURL=useMicroFrontendAttributes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMicroFrontendAttributes.js","sources":["../../src/custom-hooks/useMicroFrontendAttributes.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype KeyType = '
|
|
1
|
+
{"version":3,"file":"useMicroFrontendAttributes.js","sources":["../../src/custom-hooks/useMicroFrontendAttributes.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype KeyType = 'boolean' | 'number' | 'string';\n\ninterface KeyConfig {\n key: string;\n type?: KeyType; // type is optional, defaults to 'string'\n}\n\nconst ALWAYS_RETURN_KEYS: (KeyConfig | string)[] = [\n 'orgId',\n 'appId',\n { key: 'isFlipdishStaff', type: 'boolean' },\n] as const;\n\ntype AlwaysReturnKeys = (typeof ALWAYS_RETURN_KEYS)[number] extends KeyConfig\n ? (typeof ALWAYS_RETURN_KEYS)[number]['key']\n : (typeof ALWAYS_RETURN_KEYS)[number];\n\ntype ExtractKey<T> = T extends KeyConfig ? T['key'] : T;\n\ntype AttributeValue = boolean | number | string | null;\n\n// Utility functions moved outside\ntype KeyArg<T> = AlwaysReturnKeys | T | string;\nconst getKeyConfig = <T extends KeyConfig | string>(key: KeyArg<T>, allConfigs: (KeyConfig | string)[]) => {\n return allConfigs.find((config) => (typeof config === 'string' ? config === key : config.key === key));\n};\n\nconst getValueType = (keyConfig: KeyConfig | string | undefined): KeyType => {\n return keyConfig && typeof keyConfig !== 'string' && 'type' in keyConfig\n ? (keyConfig.type ?? 'string')\n : 'string';\n};\n\nconst parseValue = (value: string | null, type: KeyType): AttributeValue => {\n if (!value && type !== 'boolean') return null;\n if (type === 'boolean') return value === 'true';\n if (type === 'number') return Number(value);\n return value;\n};\n\nconst getAllKeys = <T extends KeyConfig | string>(\n customKeys: (KeyConfig | T)[],\n): (AlwaysReturnKeys | T | string)[] => {\n return [\n ...ALWAYS_RETURN_KEYS.map((key) => (typeof key === 'string' ? key : key.key)),\n ...customKeys.map((key) => (typeof key === 'string' ? key : key.key)),\n ];\n};\n\nconst getInitialState = <T extends KeyConfig | string>(\n customKeys: (KeyConfig | T)[],\n): Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue> => {\n const allKeys = getAllKeys(customKeys);\n const initialState = {} as Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue>;\n allKeys.forEach((key) => {\n const typedKey = (typeof key === 'string' ? key : key.key) as ExtractKey<AlwaysReturnKeys | T>;\n initialState[typedKey] = null;\n });\n return initialState;\n};\n\nconst processAttribute = <T extends KeyConfig | string>(\n key: AlwaysReturnKeys | T | string,\n microFrontendDiv: HTMLElement,\n allConfigs: (KeyConfig | string)[],\n): { value: AttributeValue; key: ExtractKey<AlwaysReturnKeys | T> } => {\n const keyConfig = getKeyConfig(key, allConfigs);\n const type = getValueType(keyConfig);\n const keyString = typeof key === 'string' ? key : key.key;\n\n const envVar = import.meta.env[`VITE_${keyString.toUpperCase()}_OVERRIDE`] as string | null | undefined;\n const attributeKey = `data-${keyString}`;\n const domValue = microFrontendDiv.getAttribute(attributeKey);\n\n const value = envVar ? parseValue(envVar.toString(), type) : parseValue(domValue, type);\n return { value, key: keyString as ExtractKey<AlwaysReturnKeys | T> };\n};\n\n/**\n * Custom hook to manage micro-frontend attributes.\n *\n * This hook initializes and updates a set of attributes based on a combination of predefined keys (ALWAYS_RETURN_KEYS)\n * and custom keys provided as arguments. The attributes are fetched from environment variables or DOM attributes\n * and are updated dynamically using a MutationObserver.\n *\n * @template T - The type of custom keys, which can be either a string or a KeyConfig object.\n *\n * @param {Array<T | KeyConfig>} [customKeys=[]] - An array of custom keys or KeyConfig objects to be included in the attributes.\n *\n * @returns {Record<ExtractKey<AlwaysReturnKeys | T>, string | boolean | number | null>} - A record of attributes with their values.\n *\n * @example\n * const attributes = useMicroFrontendAttributes(['customKey1', { key: 'customKey2', type: 'boolean' }]);\n * console.log(attributes);\n */\nconst useMicroFrontendAttributes = <T extends KeyConfig | string>(\n customKeys: (KeyConfig | T)[] = [],\n): Record<ExtractKey<AlwaysReturnKeys | T>, AttributeValue> => {\n const [attributes, setAttributes] = useState(() => getInitialState(customKeys));\n\n useEffect(() => {\n const microFrontendDiv = document.getElementById('flipdish-micro-frontend');\n if (!microFrontendDiv) {\n console.warn('Micro-frontend div not found');\n return;\n }\n\n const allKeys = getAllKeys(customKeys);\n const allConfigs = [...ALWAYS_RETURN_KEYS, ...customKeys];\n\n const updateValues = () => {\n setAttributes((prev) => {\n const newAttributes = { ...prev };\n let isChanged = false;\n\n allKeys.forEach((key) => {\n const { value, key: typedKey } = processAttribute(key, microFrontendDiv, allConfigs);\n if (newAttributes[typedKey] !== value) {\n newAttributes[typedKey] = value;\n isChanged = true;\n }\n });\n\n return isChanged ? newAttributes : prev;\n });\n };\n\n updateValues();\n\n const observer = new MutationObserver(updateValues);\n observer.observe(microFrontendDiv, { attributes: true });\n\n return () => observer.disconnect();\n }, [customKeys]);\n\n return attributes;\n};\n\nexport default useMicroFrontendAttributes;\n"],"names":["ALWAYS_RETURN_KEYS","key","type","parseValue","value","Number","getAllKeys","customKeys","map","useMicroFrontendAttributes","attributes","setAttributes","useState","allKeys","initialState","forEach","typedKey","getInitialState","useEffect","microFrontendDiv","document","getElementById","console","warn","allConfigs","updateValues","prev","newAttributes","isChanged","keyConfig","find","config","getKeyConfig","getValueType","keyString","envVar","env","toUpperCase","attributeKey","domValue","getAttribute","toString","processAttribute","observer","MutationObserver","observe","disconnect"],"mappings":"gDASA,MAAMA,EAA6C,CACjD,QACA,QACA,CAAEC,IAAK,kBAAmBC,KAAM,YAuB5BC,EAAa,CAACC,EAAsBF,IACnCE,GAAkB,YAATF,EACD,YAATA,EAAqC,SAAVE,EAClB,WAATF,EAA0BG,OAAOD,GAC9BA,EAHkC,KAMrCE,EACJC,GAEO,IACFP,EAAmBQ,KAAKP,GAAwB,iBAARA,EAAmBA,EAAMA,EAAIA,SACrEM,EAAWC,KAAKP,GAAwB,iBAARA,EAAmBA,EAAMA,EAAIA,OAkD9DQ,EAA6B,CACjCF,EAAgC,MAEhC,MAAOG,EAAYC,GAAiBC,GAAS,IAjDvB,CACtBL,IAEA,MAAMM,EAAUP,EAAWC,GACrBO,EAAe,CAA8D,EAKnF,OAJAD,EAAQE,SAASd,IACf,MAAMe,EAA2B,iBAARf,EAAmBA,EAAMA,EAAIA,IACtDa,EAAaE,GAAY,QAEpBF,GAwC4CG,CAAgBV,KAqCnE,OAnCAW,GAAU,KACR,MAAMC,EAAmBC,SAASC,eAAe,2BACjD,IAAKF,EAEH,YADAG,QAAQC,KAAK,gCAIf,MAAMV,EAAUP,EAAWC,GACrBiB,EAAa,IAAIxB,KAAuBO,GAExCkB,EAAe,KACnBd,GAAee,IACb,MAAMC,EAAgB,IAAKD,GAC3B,IAAIE,GAAY,EAUhB,OARAf,EAAQE,SAASd,IACf,MAAMG,MAAEA,EAAOH,IAAKe,GAvDL,EACvBf,EACAkB,EACAK,KAEA,MAAMK,EA3Ca,EAA+B5B,EAAgBuB,IAC3DA,EAAWM,MAAMC,GAA8B,iBAAXA,EAAsBA,IAAW9B,EAAM8B,EAAO9B,MAAQA,IA0C/E+B,CAAa/B,EAAKuB,GAC9BtB,EAxCa,CAAC2B,GACbA,GAAkC,iBAAdA,GAA0B,SAAUA,EAC1DA,EAAU3B,MAAQ,SACnB,SAqCS+B,CAAaJ,GACpBK,EAA2B,iBAARjC,EAAmBA,EAAMA,EAAIA,IAEhDkC,cAAqBC,IAAI,QAAQF,EAAUG,0BAC3CC,EAAe,QAAQJ,IACvBK,EAAWpB,EAAiBqB,aAAaF,GAG/C,MAAO,CAAElC,MADcD,EAATgC,EAAoBA,EAAOM,WAA+BF,EAAnBrC,GACrCD,IAAKiC,IAyCoBQ,CAAiBzC,EAAKkB,EAAkBK,GACrEG,EAAcX,KAAcZ,IAC9BuB,EAAcX,GAAYZ,EAC1BwB,GAAY,MAITA,EAAYD,EAAgBD,MAIvCD,IAEA,MAAMkB,EAAW,IAAIC,iBAAiBnB,GAGtC,OAFAkB,EAASE,QAAQ1B,EAAkB,CAAET,YAAY,IAE1C,IAAMiC,EAASG,eACrB,CAACvC,IAEGG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRenderValidText.cjs.js","sources":["../../src/custom-hooks/useRenderValidText.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\
|
|
1
|
+
{"version":3,"file":"useRenderValidText.cjs.js","sources":["../../src/custom-hooks/useRenderValidText.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ninterface ValidationState {\n fieldError?: string;\n showError?: boolean;\n touched: boolean;\n value?: string;\n}\n\ntype ValidationElement = JSX.Element | string | undefined;\n\n/**\n * @description Custom hook for rendering validation text in form fields\n * @description Handles different validation states with separate methods for better clarity\n */\nconst useRenderValidText = (\n { fieldError, showError, touched, value }: ValidationState,\n validText: string,\n) => {\n const [validTextElement, setValidTextElement] = useState<ValidationElement>('');\n\n const renderValidState = (): ValidationElement => {\n return <span style={{ color: '#1dc798' }}>{validText}</span>;\n };\n\n const renderErrorState = (): ValidationElement => {\n return fieldError;\n };\n\n const renderEmptyState = (): ValidationElement => {\n return '';\n };\n\n const determineValidationState = (): ValidationElement => {\n if (!showError && touched && value) {\n return renderValidState();\n }\n\n if (showError) {\n return renderErrorState();\n }\n\n return renderEmptyState();\n };\n\n useEffect(() => {\n setValidTextElement(determineValidationState());\n }, [fieldError, value, showError, touched]);\n\n return validTextElement;\n};\n\nexport default useRenderValidText;\n"],"names":["fieldError","showError","touched","value","validText","validTextElement","setValidTextElement","useState","determineValidationState","_jsx","jsx","style","color","children","useEffect"],"mappings":"kFAe2B,EACvBA,aAAYC,YAAWC,UAASC,SAClCC,KAEA,MAAOC,EAAkBC,GAAuBC,EAAAA,SAA4B,IActEC,EAA2B,KAC1BP,GAAaC,GAAWC,EAZtBM,EAAAC,IAAA,OAAA,CAAMC,MAAO,CAAEC,MAAO,WAAWC,SAAGT,IAgBvCH,EAZGD,EAIA,GAmBT,OAJAc,EAAAA,WAAU,KACRR,EAAoBE,OACnB,CAACR,EAAYG,EAAOF,EAAWC,IAE3BG"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
interface ValidationState {
|
|
2
2
|
fieldError?: string;
|
|
3
3
|
showError?: boolean;
|
|
4
4
|
touched: boolean;
|
|
5
|
-
value
|
|
6
|
-
}
|
|
5
|
+
value?: string;
|
|
6
|
+
}
|
|
7
7
|
type ValidationElement = JSX.Element | string | undefined;
|
|
8
8
|
/**
|
|
9
9
|
* @description Custom hook for rendering validation text in form fields
|