@flipdish/portal-library 7.9.1 → 7.10.1
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/atoms/BreadCrumbs/index.cjs.js.map +1 -1
- package/dist/components/atoms/BreadCrumbs/index.js.map +1 -1
- package/dist/components/atoms/Link/index.cjs.js +1 -1
- package/dist/components/atoms/Link/index.cjs.js.map +1 -1
- package/dist/components/atoms/Link/index.d.ts +2 -2
- package/dist/components/atoms/Link/index.js +1 -1
- package/dist/components/atoms/Link/index.js.map +1 -1
- package/dist/components/organisms/AssetManager/LibraryTabContent/index.cjs.js +2 -0
- package/dist/components/organisms/AssetManager/LibraryTabContent/index.cjs.js.map +1 -0
- package/dist/components/organisms/AssetManager/LibraryTabContent/index.d.ts +31 -0
- package/dist/components/organisms/AssetManager/LibraryTabContent/index.js +2 -0
- package/dist/components/organisms/AssetManager/LibraryTabContent/index.js.map +1 -0
- package/dist/components/organisms/AssetManager/UploadTabContent/index.cjs.js +2 -0
- package/dist/components/organisms/AssetManager/UploadTabContent/index.cjs.js.map +1 -0
- package/dist/components/organisms/AssetManager/UploadTabContent/index.d.ts +27 -0
- package/dist/components/organisms/AssetManager/UploadTabContent/index.js +2 -0
- package/dist/components/organisms/AssetManager/UploadTabContent/index.js.map +1 -0
- package/dist/components/organisms/AssetManager/hooks/useAssets.cjs.js +1 -1
- package/dist/components/organisms/AssetManager/hooks/useAssets.cjs.js.map +1 -1
- package/dist/components/organisms/AssetManager/hooks/useAssets.js +1 -1
- package/dist/components/organisms/AssetManager/hooks/useAssets.js.map +1 -1
- package/dist/components/organisms/AssetManager/index.cjs.js +1 -1
- package/dist/components/organisms/AssetManager/index.cjs.js.map +1 -1
- package/dist/components/organisms/AssetManager/index.js +1 -1
- package/dist/components/organisms/AssetManager/index.js.map +1 -1
- package/dist/components/organisms/FileUpload/index.cjs.js +1 -1
- package/dist/components/organisms/FileUpload/index.cjs.js.map +1 -1
- package/dist/components/organisms/FileUpload/index.js +1 -1
- package/dist/components/organisms/FileUpload/index.js.map +1 -1
- package/dist/components/organisms/Heading/Heading.cjs.js.map +1 -1
- package/dist/components/organisms/Heading/Heading.js.map +1 -1
- package/dist/utilities/fileUtils.cjs.js +2 -0
- package/dist/utilities/fileUtils.cjs.js.map +1 -0
- package/dist/utilities/fileUtils.d.ts +3 -0
- package/dist/utilities/fileUtils.js +2 -0
- package/dist/utilities/fileUtils.js.map +1 -0
- package/dist/utilities/timeUtilities.cjs.js +2 -0
- package/dist/utilities/timeUtilities.cjs.js.map +1 -0
- package/dist/utilities/timeUtilities.d.ts +7 -0
- package/dist/utilities/timeUtilities.js +2 -0
- package/dist/utilities/timeUtilities.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/BreadCrumbs/index.tsx"],"sourcesContent":["import { memo, useState } from 'react';\n\nimport BreadcrumbsMUI from '@mui/material/Breadcrumbs';\nimport { styled, useTheme } from '@mui/material/styles';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport Link from '@fd/components/atoms/Link';\nimport ArrowLeft02Icon from '@fd/icons/ArrowLeft02';\nimport { typography } from '@fd/themes/typography';\n\nexport interface BreadcrumbItem {\n label: string;\n href?: string;\n}\n\nexport type BreadCrumbsType = 'collapsed' | 'default';\n\nexport interface BreadCrumbsProps {\n items: BreadcrumbItem[];\n type?: BreadCrumbsType;\n className?: string;\n 'data-testid'?: string;\n ariaLabel?: string;\n ariaLabelEllipsis?: string;\n}\n\nconst StyledBreadcrumbs = styled(BreadcrumbsMUI)(({ theme }) => ({\n '& .MuiBreadcrumbs-separator': {\n color: theme.palette.semantic.text['text-weak'],\n marginLeft: theme.spacing(1),\n marginRight: theme.spacing(1),\n },\n}));\n\nconst StyledEllipsisButton = styled('button')(({ theme }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n background: 'none',\n border: 'none',\n color: theme.palette.semantic.text['text-weak'],\n cursor: 'pointer',\n padding: theme.spacing(0.5),\n borderRadius: theme.radius?.['radius-4'] || '4px',\n transition: 'background-color 0.2s ease-in-out',\n fontFamily: typography.b1Weak.fontFamily,\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n fontWeight: typography.b1Weak.fontWeight,\n letterSpacing: typography.b1Weak.letterSpacing,\n\n '&:hover': {\n backgroundColor: theme.palette.semantic.fill['fill-hover'],\n },\n\n '&:focus-visible': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledCurrentPage = styled('span')(({ theme }) => ({\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n color: theme.palette.semantic.text['text-weak'],\n fontWeight: typography.b1Weak.fontWeight,\n fontFamily: typography.b1Weak.fontFamily,\n letterSpacing: typography.b1Weak.letterSpacing,\n}));\n\nconst BreadCrumbs = memo(\n ({\n items,\n type = 'default',\n className,\n 'data-testid': dataTestId,\n ariaLabel,\n ariaLabelEllipsis,\n }: BreadCrumbsProps) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const theme = useTheme();\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('tablet'));\n\n if (!items?.length) {\n return null;\n }\n\n const shouldCollapse
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/BreadCrumbs/index.tsx"],"sourcesContent":["import { memo, useState } from 'react';\n\nimport BreadcrumbsMUI from '@mui/material/Breadcrumbs';\nimport { styled, useTheme } from '@mui/material/styles';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport Link from '@fd/components/atoms/Link';\nimport ArrowLeft02Icon from '@fd/icons/ArrowLeft02';\nimport { typography } from '@fd/themes/typography';\n\nexport interface BreadcrumbItem {\n label: string;\n href?: string;\n}\n\nexport type BreadCrumbsType = 'collapsed' | 'default';\n\nexport interface BreadCrumbsProps {\n items: BreadcrumbItem[];\n type?: BreadCrumbsType;\n className?: string;\n 'data-testid'?: string;\n ariaLabel?: string;\n ariaLabelEllipsis?: string;\n}\n\nconst StyledBreadcrumbs = styled(BreadcrumbsMUI)(({ theme }) => ({\n '& .MuiBreadcrumbs-separator': {\n color: theme.palette.semantic.text['text-weak'],\n marginLeft: theme.spacing(1),\n marginRight: theme.spacing(1),\n },\n}));\n\nconst StyledEllipsisButton = styled('button')(({ theme }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n background: 'none',\n border: 'none',\n color: theme.palette.semantic.text['text-weak'],\n cursor: 'pointer',\n padding: theme.spacing(0.5),\n borderRadius: theme.radius?.['radius-4'] || '4px',\n transition: 'background-color 0.2s ease-in-out',\n fontFamily: typography.b1Weak.fontFamily,\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n fontWeight: typography.b1Weak.fontWeight,\n letterSpacing: typography.b1Weak.letterSpacing,\n\n '&:hover': {\n backgroundColor: theme.palette.semantic.fill['fill-hover'],\n },\n\n '&:focus-visible': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledCurrentPage = styled('span')(({ theme }) => ({\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n color: theme.palette.semantic.text['text-weak'],\n fontWeight: typography.b1Weak.fontWeight,\n fontFamily: typography.b1Weak.fontFamily,\n letterSpacing: typography.b1Weak.letterSpacing,\n}));\n\nconst BreadCrumbs = memo(\n ({\n items,\n type = 'default',\n className,\n 'data-testid': dataTestId,\n ariaLabel,\n ariaLabelEllipsis,\n }: BreadCrumbsProps) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const theme = useTheme();\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('tablet'));\n\n if (!items?.length) {\n return null;\n }\n\n const shouldCollapse =\n (type === 'collapsed' || (type === 'default' && isSmallScreen)) && items.length > 2 && !isExpanded;\n\n // Build breadcrumb items array\n const breadcrumbItems: React.ReactNode[] = [];\n\n if (shouldCollapse) {\n const firstItem = items[0];\n const lastItem = items[items.length - 1];\n if (!firstItem || !lastItem) {\n return null;\n }\n // First item\n breadcrumbItems.push(\n <Link\n key={`first-${firstItem.label}-${firstItem.href || ''}`}\n fdKey={`breadcrumb-${firstItem.label}`}\n href={firstItem.href}\n iconLeft={<ArrowLeft02Icon size=\"sm\" />}\n size=\"body\"\n tone=\"Neutral Weak\"\n underline={false}\n weight=\"regular\"\n >\n {firstItem.label}\n </Link>,\n );\n\n // Ellipsis\n breadcrumbItems.push(\n <StyledEllipsisButton\n key=\"ellipsis\"\n aria-label={ariaLabelEllipsis ?? undefined}\n onClick={() => setIsExpanded(true)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setIsExpanded(true);\n }\n }}\n type=\"button\"\n >\n ...\n </StyledEllipsisButton>,\n );\n\n // Last item\n breadcrumbItems.push(\n <StyledCurrentPage key={`current-${lastItem.label}-${lastItem.href || ''}`} aria-current=\"page\">\n {lastItem.label}\n </StyledCurrentPage>,\n );\n } else {\n // Default/expanded mode: show all items\n const allItems = items.map((item, index) => {\n const isFirst = index === 0;\n const isLast = index === items.length - 1;\n\n if (isLast) {\n return (\n <StyledCurrentPage key={`current-${item.label}-${item.href || ''}`} aria-current=\"page\">\n {item.label}\n </StyledCurrentPage>\n );\n }\n if (isFirst) {\n return (\n <Link\n key={`first-${item.label}-${item.href || ''}`}\n fdKey={`breadcrumb-${item.label}`}\n href={item.href}\n iconLeft={<ArrowLeft02Icon size=\"sm\" />}\n size=\"body\"\n tone=\"Neutral Weak\"\n underline={false}\n weight=\"regular\"\n >\n {item.label}\n </Link>\n );\n }\n return (\n <Link\n key={`middle-${item.label}-${item.href || ''}`}\n fdKey={`breadcrumb-${item.label}`}\n href={item.href}\n size=\"body\"\n tone=\"Neutral Weak\"\n underline={false}\n weight=\"regular\"\n >\n {item.label}\n </Link>\n );\n });\n breadcrumbItems.push(...allItems);\n }\n\n return (\n <StyledBreadcrumbs\n aria-label={ariaLabel ?? undefined}\n className={className}\n data-testid={dataTestId}\n separator=\"/\"\n >\n {breadcrumbItems}\n </StyledBreadcrumbs>\n );\n },\n);\n\nBreadCrumbs.displayName = 'BreadCrumbs';\n\nexport default BreadCrumbs;\n"],"names":["StyledBreadcrumbs","styled","BreadcrumbsMUI","theme","color","palette","semantic","text","marginLeft","spacing","marginRight","StyledEllipsisButton","display","alignItems","background","border","cursor","padding","borderRadius","radius","transition","fontFamily","typography","b1Weak","fontSize","lineHeight","fontWeight","letterSpacing","backgroundColor","fill","outline","stroke","outlineOffset","StyledCurrentPage","BreadCrumbs","memo","items","type","className","dataTestId","ariaLabel","ariaLabelEllipsis","isExpanded","setIsExpanded","useState","useTheme","isSmallScreen","useMediaQuery","breakpoints","down","length","breadcrumbItems","firstItem","lastItem","push","_jsx","Link","fdKey","label","href","iconLeft","ArrowLeft02Icon","size","tone","underline","weight","undefined","onClick","onKeyDown","e","key","preventDefault","children","allItems","map","item","index","isFirst","separator","displayName"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/atoms/BreadCrumbs/index.tsx"],"sourcesContent":["import { memo, useState } from 'react';\n\nimport BreadcrumbsMUI from '@mui/material/Breadcrumbs';\nimport { styled, useTheme } from '@mui/material/styles';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport Link from '@fd/components/atoms/Link';\nimport ArrowLeft02Icon from '@fd/icons/ArrowLeft02';\nimport { typography } from '@fd/themes/typography';\n\nexport interface BreadcrumbItem {\n label: string;\n href?: string;\n}\n\nexport type BreadCrumbsType = 'collapsed' | 'default';\n\nexport interface BreadCrumbsProps {\n items: BreadcrumbItem[];\n type?: BreadCrumbsType;\n className?: string;\n 'data-testid'?: string;\n ariaLabel?: string;\n ariaLabelEllipsis?: string;\n}\n\nconst StyledBreadcrumbs = styled(BreadcrumbsMUI)(({ theme }) => ({\n '& .MuiBreadcrumbs-separator': {\n color: theme.palette.semantic.text['text-weak'],\n marginLeft: theme.spacing(1),\n marginRight: theme.spacing(1),\n },\n}));\n\nconst StyledEllipsisButton = styled('button')(({ theme }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n background: 'none',\n border: 'none',\n color: theme.palette.semantic.text['text-weak'],\n cursor: 'pointer',\n padding: theme.spacing(0.5),\n borderRadius: theme.radius?.['radius-4'] || '4px',\n transition: 'background-color 0.2s ease-in-out',\n fontFamily: typography.b1Weak.fontFamily,\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n fontWeight: typography.b1Weak.fontWeight,\n letterSpacing: typography.b1Weak.letterSpacing,\n\n '&:hover': {\n backgroundColor: theme.palette.semantic.fill['fill-hover'],\n },\n\n '&:focus-visible': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledCurrentPage = styled('span')(({ theme }) => ({\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n color: theme.palette.semantic.text['text-weak'],\n fontWeight: typography.b1Weak.fontWeight,\n fontFamily: typography.b1Weak.fontFamily,\n letterSpacing: typography.b1Weak.letterSpacing,\n}));\n\nconst BreadCrumbs = memo(\n ({\n items,\n type = 'default',\n className,\n 'data-testid': dataTestId,\n ariaLabel,\n ariaLabelEllipsis,\n }: BreadCrumbsProps) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const theme = useTheme();\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('tablet'));\n\n if (!items?.length) {\n return null;\n }\n\n const shouldCollapse
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/atoms/BreadCrumbs/index.tsx"],"sourcesContent":["import { memo, useState } from 'react';\n\nimport BreadcrumbsMUI from '@mui/material/Breadcrumbs';\nimport { styled, useTheme } from '@mui/material/styles';\nimport useMediaQuery from '@mui/material/useMediaQuery';\n\nimport Link from '@fd/components/atoms/Link';\nimport ArrowLeft02Icon from '@fd/icons/ArrowLeft02';\nimport { typography } from '@fd/themes/typography';\n\nexport interface BreadcrumbItem {\n label: string;\n href?: string;\n}\n\nexport type BreadCrumbsType = 'collapsed' | 'default';\n\nexport interface BreadCrumbsProps {\n items: BreadcrumbItem[];\n type?: BreadCrumbsType;\n className?: string;\n 'data-testid'?: string;\n ariaLabel?: string;\n ariaLabelEllipsis?: string;\n}\n\nconst StyledBreadcrumbs = styled(BreadcrumbsMUI)(({ theme }) => ({\n '& .MuiBreadcrumbs-separator': {\n color: theme.palette.semantic.text['text-weak'],\n marginLeft: theme.spacing(1),\n marginRight: theme.spacing(1),\n },\n}));\n\nconst StyledEllipsisButton = styled('button')(({ theme }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n background: 'none',\n border: 'none',\n color: theme.palette.semantic.text['text-weak'],\n cursor: 'pointer',\n padding: theme.spacing(0.5),\n borderRadius: theme.radius?.['radius-4'] || '4px',\n transition: 'background-color 0.2s ease-in-out',\n fontFamily: typography.b1Weak.fontFamily,\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n fontWeight: typography.b1Weak.fontWeight,\n letterSpacing: typography.b1Weak.letterSpacing,\n\n '&:hover': {\n backgroundColor: theme.palette.semantic.fill['fill-hover'],\n },\n\n '&:focus-visible': {\n outline: `2px solid ${theme.palette.semantic.stroke['stroke-focus']}`,\n outlineOffset: '2px',\n },\n}));\n\nconst StyledCurrentPage = styled('span')(({ theme }) => ({\n fontSize: typography.b1Weak.fontSize,\n lineHeight: typography.b1Weak.lineHeight,\n color: theme.palette.semantic.text['text-weak'],\n fontWeight: typography.b1Weak.fontWeight,\n fontFamily: typography.b1Weak.fontFamily,\n letterSpacing: typography.b1Weak.letterSpacing,\n}));\n\nconst BreadCrumbs = memo(\n ({\n items,\n type = 'default',\n className,\n 'data-testid': dataTestId,\n ariaLabel,\n ariaLabelEllipsis,\n }: BreadCrumbsProps) => {\n const [isExpanded, setIsExpanded] = useState(false);\n const theme = useTheme();\n const isSmallScreen = useMediaQuery(theme.breakpoints.down('tablet'));\n\n if (!items?.length) {\n return null;\n }\n\n const shouldCollapse =\n (type === 'collapsed' || (type === 'default' && isSmallScreen)) && items.length > 2 && !isExpanded;\n\n // Build breadcrumb items array\n const breadcrumbItems: React.ReactNode[] = [];\n\n if (shouldCollapse) {\n const firstItem = items[0];\n const lastItem = items[items.length - 1];\n if (!firstItem || !lastItem) {\n return null;\n }\n // First item\n breadcrumbItems.push(\n <Link\n key={`first-${firstItem.label}-${firstItem.href || ''}`}\n fdKey={`breadcrumb-${firstItem.label}`}\n href={firstItem.href}\n iconLeft={<ArrowLeft02Icon size=\"sm\" />}\n size=\"body\"\n tone=\"Neutral Weak\"\n underline={false}\n weight=\"regular\"\n >\n {firstItem.label}\n </Link>,\n );\n\n // Ellipsis\n breadcrumbItems.push(\n <StyledEllipsisButton\n key=\"ellipsis\"\n aria-label={ariaLabelEllipsis ?? undefined}\n onClick={() => setIsExpanded(true)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setIsExpanded(true);\n }\n }}\n type=\"button\"\n >\n ...\n </StyledEllipsisButton>,\n );\n\n // Last item\n breadcrumbItems.push(\n <StyledCurrentPage key={`current-${lastItem.label}-${lastItem.href || ''}`} aria-current=\"page\">\n {lastItem.label}\n </StyledCurrentPage>,\n );\n } else {\n // Default/expanded mode: show all items\n const allItems = items.map((item, index) => {\n const isFirst = index === 0;\n const isLast = index === items.length - 1;\n\n if (isLast) {\n return (\n <StyledCurrentPage key={`current-${item.label}-${item.href || ''}`} aria-current=\"page\">\n {item.label}\n </StyledCurrentPage>\n );\n }\n if (isFirst) {\n return (\n <Link\n key={`first-${item.label}-${item.href || ''}`}\n fdKey={`breadcrumb-${item.label}`}\n href={item.href}\n iconLeft={<ArrowLeft02Icon size=\"sm\" />}\n size=\"body\"\n tone=\"Neutral Weak\"\n underline={false}\n weight=\"regular\"\n >\n {item.label}\n </Link>\n );\n }\n return (\n <Link\n key={`middle-${item.label}-${item.href || ''}`}\n fdKey={`breadcrumb-${item.label}`}\n href={item.href}\n size=\"body\"\n tone=\"Neutral Weak\"\n underline={false}\n weight=\"regular\"\n >\n {item.label}\n </Link>\n );\n });\n breadcrumbItems.push(...allItems);\n }\n\n return (\n <StyledBreadcrumbs\n aria-label={ariaLabel ?? undefined}\n className={className}\n data-testid={dataTestId}\n separator=\"/\"\n >\n {breadcrumbItems}\n </StyledBreadcrumbs>\n );\n },\n);\n\nBreadCrumbs.displayName = 'BreadCrumbs';\n\nexport default BreadCrumbs;\n"],"names":["StyledBreadcrumbs","styled","BreadcrumbsMUI","theme","color","palette","semantic","text","marginLeft","spacing","marginRight","StyledEllipsisButton","display","alignItems","background","border","cursor","padding","borderRadius","radius","transition","fontFamily","typography","b1Weak","fontSize","lineHeight","fontWeight","letterSpacing","backgroundColor","fill","outline","stroke","outlineOffset","StyledCurrentPage","BreadCrumbs","memo","items","type","className","dataTestId","ariaLabel","ariaLabelEllipsis","isExpanded","setIsExpanded","useState","useTheme","isSmallScreen","useMediaQuery","breakpoints","down","length","breadcrumbItems","firstItem","lastItem","push","_jsx","Link","fdKey","label","href","iconLeft","ArrowLeft02Icon","size","tone","underline","weight","undefined","onClick","onKeyDown","e","key","preventDefault","children","allItems","map","item","index","isFirst","separator","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime");require("react");var t=require("@mui/material/Link"),r=require("@mui/material/styles"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime");require("react");var t=require("@mui/material/Link"),r=require("@mui/material/styles"),n=require("./getLinkStyles.cjs.js");const i=r.styled(t,{shouldForwardProp:e=>!["tone","size","weight","contentState","underline","fdKey","iconLeft","iconRight"].includes(e)})((({theme:e,tone:t="Brand",size:r="body",weight:i="regular",underline:o,contentState:a="default"})=>{const s=n.getLinkStyles(e,t,o),c=e.typography[l(r,i)];return{...s.default,...s[a],...c,"&:hover":{...s.hover},"&:focus:not(:focus-visible)":{outline:"none"},"&:focus-visible":{...s.focus},"&:active":{...s.press},"& > svg":{flexShrink:0,verticalAlign:"middle",width:"20px",height:"20px"}}})),o=t=>{const{children:r,className:n,fdKey:o,href:l,contentState:a="default",target:s,rel:c,tone:u="Brand",underline:d=!0,size:f="body",weight:h="regular",iconLeft:g=null,iconRight:p=null,...y}=t,b={...y,className:n,"data-fd":o,fdKey:o,href:l,iconLeft:g,iconRight:p,rel:"_blank"!==s||c?c:"noopener noreferrer",size:f,contentState:a,target:s,tone:u,underline:d,weight:h};return e.jsxs(i,{...b,children:[g,r,p]})},l=(e,t)=>"caption"===e?"bold"===t?"captionStrong":"captionWeak":"body"===e&&"bold"===t?"b1Strong":"b1Weak";exports.Link=o,exports.default=o;
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/Link/index.tsx"],"sourcesContent":["import React, { type ReactElement } from 'react';\n\nimport MuiLink, { type LinkProps, type LinkProps as MuiLinkProps } from '@mui/material/Link';\nimport { styled } from '@mui/material/styles';\n\nimport { getLinkStyles, type LinkTone } from './getLinkStyles';\n\nexport type LinkSize = 'body' | 'caption';\nexport type LinkWeight = 'bold' | 'regular';\nexport type LinkState = 'default' | 'disabled' | 'focus' | 'hover' | 'press';\n\nexport interface StyledLinkProps extends Omit<MuiLinkProps, 'color' | '
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/atoms/Link/index.tsx"],"sourcesContent":["import React, { type ReactElement } from 'react';\n\nimport MuiLink, { type LinkProps, type LinkProps as MuiLinkProps } from '@mui/material/Link';\nimport { styled } from '@mui/material/styles';\n\nimport { getLinkStyles, type LinkTone } from './getLinkStyles';\n\nexport type LinkSize = 'body' | 'caption';\nexport type LinkWeight = 'bold' | 'regular';\nexport type LinkState = 'default' | 'disabled' | 'focus' | 'hover' | 'press';\n\nexport interface StyledLinkProps extends Omit<MuiLinkProps, 'color' | 'underline'> {\n className?: string;\n contentState?: LinkState;\n children: React.ReactNode;\n href?: string;\n target?: '_blank' | '_parent' | '_self' | '_top';\n rel?: string;\n fdKey: string;\n tone?: LinkTone;\n underline?: boolean;\n size?: LinkSize;\n weight?: LinkWeight;\n iconLeft?: React.ReactNode;\n iconRight?: React.ReactNode;\n}\n\nconst StyledLink = styled(MuiLink, {\n shouldForwardProp: (prop: string) =>\n !['tone', 'size', 'weight', 'contentState', 'underline', 'fdKey', 'iconLeft', 'iconRight'].includes(prop),\n})<StyledLinkProps>(({\n theme,\n tone = 'Brand',\n size = 'body',\n weight = 'regular',\n underline,\n contentState = 'default',\n}) => {\n const styles = getLinkStyles(theme, tone, underline);\n\n const typographyStyle = theme.typography[getTypographyVariant(size, weight)];\n\n return {\n ...styles.default,\n ...styles[contentState],\n ...typographyStyle,\n\n '&:hover': {\n ...styles.hover,\n },\n '&:focus:not(:focus-visible)': {\n outline: 'none', // Hide focus ring for mouse/touch only\n },\n // focus visible so that the focus ring only shows for keyboard users\n '&:focus-visible': { ...styles.focus },\n '&:active': {\n ...styles.press,\n },\n // Style icons\n '& > svg': {\n flexShrink: 0,\n verticalAlign: 'middle',\n width: '20px',\n height: '20px',\n },\n };\n});\n\nexport const Link = (props: StyledLinkProps): ReactElement => {\n const {\n children,\n className,\n fdKey,\n href,\n contentState = 'default',\n target,\n rel,\n tone = 'Brand',\n underline = true,\n size = 'body',\n weight = 'regular',\n iconLeft = null,\n iconRight = null,\n ...rest\n } = props;\n // Automatically add rel=\"noopener noreferrer\" for external links\n const linkRel = target === '_blank' && !rel ? 'noopener noreferrer' : rel;\n\n const styledLinkProps = {\n ...rest,\n className,\n 'data-fd': fdKey,\n fdKey,\n href,\n iconLeft,\n iconRight,\n rel: linkRel,\n size,\n contentState,\n target,\n tone,\n underline,\n weight,\n } as unknown as React.ComponentProps<typeof StyledLink>;\n\n return (\n <StyledLink {...styledLinkProps}>\n {iconLeft}\n {children}\n {iconRight}\n </StyledLink>\n );\n};\n\nconst getTypographyVariant = (\n size: LinkSize,\n weight: LinkWeight,\n): 'b1Strong' | 'b1Weak' | 'captionStrong' | 'captionWeak' => {\n if (size === 'caption') {\n return weight === 'bold' ? 'captionStrong' : 'captionWeak';\n }\n if (size === 'body') {\n return weight === 'bold' ? 'b1Strong' : 'b1Weak';\n }\n return 'b1Weak';\n};\n\nexport default Link;\nexport type { LinkProps };\n"],"names":["StyledLink","styled","MuiLink","shouldForwardProp","prop","includes","theme","tone","size","weight","underline","contentState","styles","getLinkStyles","typographyStyle","typography","getTypographyVariant","default","hover","outline","focus","press","flexShrink","verticalAlign","width","height","Link","props","children","className","fdKey","href","target","rel","iconLeft","iconRight","rest","styledLinkProps","_jsxs"],"mappings":"kOA2BA,MAAMA,EAAaC,EAAAA,OAAOC,EAAS,CACjCC,kBAAoBC,IACjB,CAAC,OAAQ,OAAQ,SAAU,eAAgB,YAAa,QAAS,WAAY,aAAaC,SAASD,IAFrFH,EAGC,EAClBK,QACAC,OAAO,QACPC,OAAO,OACPC,SAAS,UACTC,YACAC,eAAe,cAEf,MAAMC,EAASC,EAAAA,cAAcP,EAAOC,EAAMG,GAEpCI,EAAkBR,EAAMS,WAAWC,EAAqBR,EAAMC,IAEpE,MAAO,IACFG,EAAOK,WACPL,EAAOD,MACPG,EAEH,UAAW,IACNF,EAAOM,OAEZ,8BAA+B,CAC7BC,QAAS,QAGX,kBAAmB,IAAKP,EAAOQ,OAC/B,WAAY,IACPR,EAAOS,OAGZ,UAAW,CACTC,WAAY,EACZC,cAAe,SACfC,MAAO,OACPC,OAAQ,YAKDC,EAAQC,IACnB,MAAMC,SACJA,EAAQC,UACRA,EAASC,MACTA,EAAKC,KACLA,EAAIpB,aACJA,EAAe,UAASqB,OACxBA,EAAMC,IACNA,EAAG1B,KACHA,EAAO,QAAOG,UACdA,GAAY,EAAIF,KAChBA,EAAO,OAAMC,OACbA,EAAS,UAASyB,SAClBA,EAAW,KAAIC,UACfA,EAAY,QACTC,GACDT,EAIEU,EAAkB,IACnBD,EACHP,YACA,UAAWC,EACXA,QACAC,OACAG,WACAC,YACAF,IAVyB,WAAXD,GAAwBC,EAA8BA,EAAxB,sBAW5CzB,OACAG,eACAqB,SACAzB,OACAG,YACAD,UAGF,OACE6B,EAAAA,KAACtC,EAAU,IAAKqC,EAAeT,SAAA,CAC5BM,EACAN,EACAO,MAKDnB,EAAuB,CAC3BR,EACAC,IAEa,YAATD,EACgB,SAAXC,EAAoB,gBAAkB,cAElC,SAATD,GACgB,SAAXC,EAAoB,WAEtB"}
|
|
@@ -6,9 +6,9 @@ import { LinkTone } from './getLinkStyles.js';
|
|
|
6
6
|
type LinkSize = 'body' | 'caption';
|
|
7
7
|
type LinkWeight = 'bold' | 'regular';
|
|
8
8
|
type LinkState = 'default' | 'disabled' | 'focus' | 'hover' | 'press';
|
|
9
|
-
interface StyledLinkProps extends Omit<LinkProps, 'color' | '
|
|
9
|
+
interface StyledLinkProps extends Omit<LinkProps, 'color' | 'underline'> {
|
|
10
10
|
className?: string;
|
|
11
|
-
|
|
11
|
+
contentState?: LinkState;
|
|
12
12
|
children: react__default.ReactNode;
|
|
13
13
|
href?: string;
|
|
14
14
|
target?: '_blank' | '_parent' | '_self' | '_top';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as e}from"react/jsx-runtime";import"react";import t from"@mui/material/Link";import{styled as
|
|
1
|
+
import{jsxs as e}from"react/jsx-runtime";import"react";import t from"@mui/material/Link";import{styled as n}from"@mui/material/styles";import{getLinkStyles as o}from"./getLinkStyles.js";const r=n(t,{shouldForwardProp:e=>!["tone","size","weight","contentState","underline","fdKey","iconLeft","iconRight"].includes(e)})((({theme:e,tone:t="Brand",size:n="body",weight:r="regular",underline:i,contentState:l="default"})=>{const c=o(e,t,i),d=e.typography[a(n,r)];return{...c.default,...c[l],...d,"&:hover":{...c.hover},"&:focus:not(:focus-visible)":{outline:"none"},"&:focus-visible":{...c.focus},"&:active":{...c.press},"& > svg":{flexShrink:0,verticalAlign:"middle",width:"20px",height:"20px"}}})),i=t=>{const{children:n,className:o,fdKey:i,href:a,contentState:l="default",target:c,rel:d,tone:s="Brand",underline:u=!0,size:f="body",weight:h="regular",iconLeft:g=null,iconRight:m=null,...p}=t,b={...p,className:o,"data-fd":i,fdKey:i,href:a,iconLeft:g,iconRight:m,rel:"_blank"!==c||d?d:"noopener noreferrer",size:f,contentState:l,target:c,tone:s,underline:u,weight:h};return e(r,{...b,children:[g,n,m]})},a=(e,t)=>"caption"===e?"bold"===t?"captionStrong":"captionWeak":"body"===e&&"bold"===t?"b1Strong":"b1Weak";export{i as Link,i as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/atoms/Link/index.tsx"],"sourcesContent":["import React, { type ReactElement } from 'react';\n\nimport MuiLink, { type LinkProps, type LinkProps as MuiLinkProps } from '@mui/material/Link';\nimport { styled } from '@mui/material/styles';\n\nimport { getLinkStyles, type LinkTone } from './getLinkStyles';\n\nexport type LinkSize = 'body' | 'caption';\nexport type LinkWeight = 'bold' | 'regular';\nexport type LinkState = 'default' | 'disabled' | 'focus' | 'hover' | 'press';\n\nexport interface StyledLinkProps extends Omit<MuiLinkProps, 'color' | '
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/atoms/Link/index.tsx"],"sourcesContent":["import React, { type ReactElement } from 'react';\n\nimport MuiLink, { type LinkProps, type LinkProps as MuiLinkProps } from '@mui/material/Link';\nimport { styled } from '@mui/material/styles';\n\nimport { getLinkStyles, type LinkTone } from './getLinkStyles';\n\nexport type LinkSize = 'body' | 'caption';\nexport type LinkWeight = 'bold' | 'regular';\nexport type LinkState = 'default' | 'disabled' | 'focus' | 'hover' | 'press';\n\nexport interface StyledLinkProps extends Omit<MuiLinkProps, 'color' | 'underline'> {\n className?: string;\n contentState?: LinkState;\n children: React.ReactNode;\n href?: string;\n target?: '_blank' | '_parent' | '_self' | '_top';\n rel?: string;\n fdKey: string;\n tone?: LinkTone;\n underline?: boolean;\n size?: LinkSize;\n weight?: LinkWeight;\n iconLeft?: React.ReactNode;\n iconRight?: React.ReactNode;\n}\n\nconst StyledLink = styled(MuiLink, {\n shouldForwardProp: (prop: string) =>\n !['tone', 'size', 'weight', 'contentState', 'underline', 'fdKey', 'iconLeft', 'iconRight'].includes(prop),\n})<StyledLinkProps>(({\n theme,\n tone = 'Brand',\n size = 'body',\n weight = 'regular',\n underline,\n contentState = 'default',\n}) => {\n const styles = getLinkStyles(theme, tone, underline);\n\n const typographyStyle = theme.typography[getTypographyVariant(size, weight)];\n\n return {\n ...styles.default,\n ...styles[contentState],\n ...typographyStyle,\n\n '&:hover': {\n ...styles.hover,\n },\n '&:focus:not(:focus-visible)': {\n outline: 'none', // Hide focus ring for mouse/touch only\n },\n // focus visible so that the focus ring only shows for keyboard users\n '&:focus-visible': { ...styles.focus },\n '&:active': {\n ...styles.press,\n },\n // Style icons\n '& > svg': {\n flexShrink: 0,\n verticalAlign: 'middle',\n width: '20px',\n height: '20px',\n },\n };\n});\n\nexport const Link = (props: StyledLinkProps): ReactElement => {\n const {\n children,\n className,\n fdKey,\n href,\n contentState = 'default',\n target,\n rel,\n tone = 'Brand',\n underline = true,\n size = 'body',\n weight = 'regular',\n iconLeft = null,\n iconRight = null,\n ...rest\n } = props;\n // Automatically add rel=\"noopener noreferrer\" for external links\n const linkRel = target === '_blank' && !rel ? 'noopener noreferrer' : rel;\n\n const styledLinkProps = {\n ...rest,\n className,\n 'data-fd': fdKey,\n fdKey,\n href,\n iconLeft,\n iconRight,\n rel: linkRel,\n size,\n contentState,\n target,\n tone,\n underline,\n weight,\n } as unknown as React.ComponentProps<typeof StyledLink>;\n\n return (\n <StyledLink {...styledLinkProps}>\n {iconLeft}\n {children}\n {iconRight}\n </StyledLink>\n );\n};\n\nconst getTypographyVariant = (\n size: LinkSize,\n weight: LinkWeight,\n): 'b1Strong' | 'b1Weak' | 'captionStrong' | 'captionWeak' => {\n if (size === 'caption') {\n return weight === 'bold' ? 'captionStrong' : 'captionWeak';\n }\n if (size === 'body') {\n return weight === 'bold' ? 'b1Strong' : 'b1Weak';\n }\n return 'b1Weak';\n};\n\nexport default Link;\nexport type { LinkProps };\n"],"names":["StyledLink","styled","MuiLink","shouldForwardProp","prop","includes","theme","tone","size","weight","underline","contentState","styles","getLinkStyles","typographyStyle","typography","getTypographyVariant","default","hover","outline","focus","press","flexShrink","verticalAlign","width","height","Link","props","children","className","fdKey","href","target","rel","iconLeft","iconRight","rest","styledLinkProps","_jsxs"],"mappings":"0LA2BA,MAAMA,EAAaC,EAAOC,EAAS,CACjCC,kBAAoBC,IACjB,CAAC,OAAQ,OAAQ,SAAU,eAAgB,YAAa,QAAS,WAAY,aAAaC,SAASD,IAFrFH,EAGC,EAClBK,QACAC,OAAO,QACPC,OAAO,OACPC,SAAS,UACTC,YACAC,eAAe,cAEf,MAAMC,EAASC,EAAcP,EAAOC,EAAMG,GAEpCI,EAAkBR,EAAMS,WAAWC,EAAqBR,EAAMC,IAEpE,MAAO,IACFG,EAAOK,WACPL,EAAOD,MACPG,EAEH,UAAW,IACNF,EAAOM,OAEZ,8BAA+B,CAC7BC,QAAS,QAGX,kBAAmB,IAAKP,EAAOQ,OAC/B,WAAY,IACPR,EAAOS,OAGZ,UAAW,CACTC,WAAY,EACZC,cAAe,SACfC,MAAO,OACPC,OAAQ,YAKDC,EAAQC,IACnB,MAAMC,SACJA,EAAQC,UACRA,EAASC,MACTA,EAAKC,KACLA,EAAIpB,aACJA,EAAe,UAASqB,OACxBA,EAAMC,IACNA,EAAG1B,KACHA,EAAO,QAAOG,UACdA,GAAY,EAAIF,KAChBA,EAAO,OAAMC,OACbA,EAAS,UAASyB,SAClBA,EAAW,KAAIC,UACfA,EAAY,QACTC,GACDT,EAIEU,EAAkB,IACnBD,EACHP,YACA,UAAWC,EACXA,QACAC,OACAG,WACAC,YACAF,IAVyB,WAAXD,GAAwBC,EAA8BA,EAAxB,sBAW5CzB,OACAG,eACAqB,SACAzB,OACAG,YACAD,UAGF,OACE6B,EAACtC,EAAU,IAAKqC,EAAeT,SAAA,CAC5BM,EACAN,EACAO,MAKDnB,EAAuB,CAC3BR,EACAC,IAEa,YAATD,EACgB,SAAXC,EAAoB,gBAAkB,cAElC,SAATD,GACgB,SAAXC,EAAoB,WAEtB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime");require("react");var t=require("@mui/material/styles"),s=require("@mui/material/Box"),r=require("../../../atoms/Card/index.cjs.js"),i=require("../../../atoms/CircularProgress/index.cjs.js"),a=require("@mui/material/Grid2"),o=require("../../../molecules/EmptyState/index.cjs.js"),l=require("../../../../icons/CheckmarkCircleSolid/index.cjs.js"),n=require("../hooks/useAssets.cjs.js");const d=t.styled(a)((()=>({listStyle:"none",margin:0,padding:0}))),c=t.styled(s,{shouldForwardProp:e=>"selected"!==e})((({theme:e,selected:t})=>({width:"100%",cursor:"pointer",position:"relative","& .MuiCard-root":{borderWidth:"2px",borderColor:t?e.palette.semantic.stroke["stroke-selected"]:"transparent",boxShadow:t?"none":`inset 0 0 0 1px ${e.palette.semantic.stroke["stroke-weak"]}`},"&:focus-visible .MuiCard-root":{borderColor:e.palette.semantic.stroke["stroke-selected"],boxShadow:"none"}}))),m=t.styled(l)((({theme:e})=>({position:"absolute",top:e.spacing(2),left:e.spacing(2),zIndex:1,color:e.palette.semantic.icon["icon-primary"],"& circle":{fill:e.palette.common.white}}))),p=t.styled(s)((({theme:e})=>({display:"flex",justifyContent:"center",alignItems:"center",minHeight:"200px",padding:e.spacing(4)}))),u=t.styled(s)((({theme:e})=>({padding:e.spacing(4)})));module.exports=({orgId:t,selectedAssets:s,onAssetClick:l,enabled:x=!0})=>{const{data:g,isLoading:j,error:h}=n.useGetAssets(t,x);return j?e.jsx(p,{children:e.jsx(i.CircularProgress,{size:"large"})}):h?e.jsx(u,{children:e.jsx(o.EmptyState,{description:"Failed to load assets. Please try again later.",title:"Error loading assets"})}):g&&0!==g.length?e.jsx(d,{container:!0,component:"ul",spacing:1,children:g.map((t=>{const i=s.has(t.id);return e.jsx(a,{"aria-selected":i,component:"li",size:{widescreen:3,desktop:3,mobile:6,tablet:4},children:e.jsxs(c,{"aria-label":"Select "+t.fileName,onClick:()=>l(t),onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),l(t))},role:"button",selected:i,tabIndex:0,children:[i&&e.jsx(m,{size:"lg"}),e.jsx(r,{content:t.fileName,heading:"",imageAlt:t.metadata.altText,imageSrc:t.url})]})},t.id)}))}):e.jsx(u,{children:e.jsx(o.EmptyState,{description:"No assets available to display.",title:"No assets found"})})};
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../../src/components/organisms/AssetManager/LibraryTabContent/index.tsx"],"sourcesContent":["import React from 'react';\n\nimport { styled } from '@mui/material/styles';\n\nimport Box from '@fd/components/atoms/Box';\nimport Card from '@fd/components/atoms/Card';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport Grid from '@fd/components/atoms/Grid';\nimport EmptyState from '@fd/components/molecules/EmptyState';\nimport CheckmarkCircleSolidIcon from '@fd/icons/CheckmarkCircleSolid';\n\nimport { useGetAssets } from '../hooks/useAssets';\nimport type { Asset } from '../types';\n\nconst StyledList = styled(Grid)<{ component: string }>(() => ({\n listStyle: 'none',\n margin: 0,\n padding: 0,\n}));\n\nconst StyledCardWrapper = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'selected',\n})<{ selected?: boolean }>(({ theme, selected }) => ({\n width: '100%',\n cursor: 'pointer',\n position: 'relative',\n '& .MuiCard-root': {\n // Always use 2px border to prevent layout shift\n borderWidth: '2px',\n borderColor: selected ? theme.palette.semantic.stroke['stroke-selected'] : 'transparent',\n // Use box-shadow to create the visual 1px border when not selected\n // This prevents layout shift while maintaining the visual appearance\n boxShadow: selected ? 'none' : `inset 0 0 0 1px ${theme.palette.semantic.stroke['stroke-weak']}`,\n },\n '&:focus-visible .MuiCard-root': {\n borderColor: theme.palette.semantic.stroke['stroke-selected'],\n boxShadow: 'none',\n },\n}));\n\nconst StyledCheckmarkIcon = styled(CheckmarkCircleSolidIcon)(({ theme }) => ({\n position: 'absolute',\n top: theme.spacing(2),\n left: theme.spacing(2),\n zIndex: 1,\n color: theme.palette.semantic.icon['icon-primary'],\n '& circle': {\n fill: theme.palette.common.white,\n },\n}));\n\nconst StyledLoadingContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '200px',\n padding: theme.spacing(4),\n}));\n\nconst StyledErrorContainer = styled(Box)(({ theme }) => ({\n padding: theme.spacing(4),\n}));\n\n/**\n * Props for the LibraryTabContent component.\n * @param orgId - Organization ID for fetching assets\n * @param selectedAssets - Map of selected assets (id -> Asset) for O(1) lookup performance\n * @param onAssetClick - Callback when an asset is clicked\n * @param enabled - Whether the component is enabled (for conditional fetching)\n */\nexport interface LibraryTabContentProps {\n /** Organization ID for fetching assets */\n orgId: string;\n /** Map of selected assets (id -> Asset) for O(1) lookup performance */\n selectedAssets: Map<string, Asset>;\n /** Callback when an asset is clicked */\n onAssetClick: (asset: Asset) => void;\n /** Whether the component is enabled (for conditional fetching) */\n enabled?: boolean;\n}\n\n/**\n * LibraryTab component displays a grid of assets that can be selected.\n * Handles fetching assets internally and displays loading/error states.\n *\n * @param props - The component props\n * @returns The library tab content\n */\nconst LibraryTabContent: React.FC<LibraryTabContentProps> = ({\n orgId,\n selectedAssets,\n onAssetClick,\n enabled = true,\n}) => {\n const { data: assets, isLoading, error } = useGetAssets(orgId, enabled);\n\n if (isLoading) {\n return (\n <StyledLoadingContainer>\n <CircularProgress size=\"large\" />\n </StyledLoadingContainer>\n );\n }\n\n if (error) {\n return (\n <StyledErrorContainer>\n <EmptyState\n description=\"Failed to load assets. Please try again later.\"\n title=\"Error loading assets\"\n />\n </StyledErrorContainer>\n );\n }\n\n if (!assets || assets.length === 0) {\n return (\n <StyledErrorContainer>\n <EmptyState description=\"No assets available to display.\" title=\"No assets found\" />\n </StyledErrorContainer>\n );\n }\n\n return (\n <StyledList container component=\"ul\" spacing={1}>\n {assets.map((asset: Asset) => {\n const isSelected = selectedAssets.has(asset.id);\n return (\n <Grid\n key={asset.id}\n aria-selected={isSelected}\n component=\"li\"\n size={{ widescreen: 3, desktop: 3, mobile: 6, tablet: 4 }}\n >\n <StyledCardWrapper\n aria-label={'Select ' + asset.fileName} // TODO: translate this text when translate provider is added\n onClick={() => onAssetClick(asset)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onAssetClick(asset);\n }\n }}\n role=\"button\"\n selected={isSelected}\n tabIndex={0}\n >\n {isSelected && <StyledCheckmarkIcon size=\"lg\" />}\n <Card\n content={asset.fileName}\n heading=\"\"\n imageAlt={asset.metadata.altText}\n imageSrc={asset.url}\n />\n </StyledCardWrapper>\n </Grid>\n );\n })}\n </StyledList>\n );\n};\n\nexport default LibraryTabContent;\n"],"names":["StyledList","styled","Grid","listStyle","margin","padding","StyledCardWrapper","Box","shouldForwardProp","prop","theme","selected","width","cursor","position","borderWidth","borderColor","palette","semantic","stroke","boxShadow","StyledCheckmarkIcon","CheckmarkCircleSolidIcon","top","spacing","left","zIndex","color","icon","fill","common","white","StyledLoadingContainer","display","justifyContent","alignItems","minHeight","StyledErrorContainer","orgId","selectedAssets","onAssetClick","enabled","data","assets","isLoading","error","useGetAssets","_jsx","children","CircularProgress","size","EmptyState","description","title","length","container","component","map","asset","isSelected","has","id","widescreen","desktop","mobile","tablet","_jsxs","fileName","onClick","onKeyDown","e","key","preventDefault","role","tabIndex","Card","content","heading","imageAlt","metadata","altText","imageSrc","url"],"mappings":"+aAcA,MAAMA,EAAaC,EAAAA,OAAOC,EAAPD,EAAoC,KAAA,CACrDE,UAAW,OACXC,OAAQ,EACRC,QAAS,MAGLC,EAAoBL,EAAAA,OAAOM,EAAK,CACpCC,kBAAoBC,GAAkB,aAATA,GADLR,EAEC,EAAGS,QAAOC,eAAU,CAC7CC,MAAO,OACPC,OAAQ,UACRC,SAAU,WACV,kBAAmB,CAEjBC,YAAa,MACbC,YAAaL,EAAWD,EAAMO,QAAQC,SAASC,OAAO,mBAAqB,cAG3EC,UAAWT,EAAW,OAAS,mBAAmBD,EAAMO,QAAQC,SAASC,OAAO,kBAElF,gCAAiC,CAC/BH,YAAaN,EAAMO,QAAQC,SAASC,OAAO,mBAC3CC,UAAW,YAITC,EAAsBpB,EAAAA,OAAOqB,EAAPrB,EAAiC,EAAGS,YAAO,CACrEI,SAAU,WACVS,IAAKb,EAAMc,QAAQ,GACnBC,KAAMf,EAAMc,QAAQ,GACpBE,OAAQ,EACRC,MAAOjB,EAAMO,QAAQC,SAASU,KAAK,gBACnC,WAAY,CACVC,KAAMnB,EAAMO,QAAQa,OAAOC,WAIzBC,EAAyB/B,EAAAA,OAAOM,EAAPN,EAAY,EAAGS,YAAO,CACnDuB,QAAS,OACTC,eAAgB,SAChBC,WAAY,SACZC,UAAW,QACX/B,QAASK,EAAMc,QAAQ,OAGnBa,EAAuBpC,EAAAA,OAAOM,EAAPN,EAAY,EAAGS,YAAO,CACjDL,QAASK,EAAMc,QAAQ,sBA4BmC,EAC1Dc,QACAC,iBACAC,eACAC,WAAU,MAEV,MAAQC,KAAMC,EAAMC,UAAEA,EAASC,MAAEA,GAAUC,EAAAA,aAAaR,EAAOG,GAE/D,OAAIG,EAEAG,EAAAA,IAACf,EAAsB,CAAAgB,SACrBD,EAAAA,IAACE,EAAAA,iBAAgB,CAACC,KAAK,YAKzBL,EAEAE,MAACV,EAAoB,CAAAW,SACnBD,EAAAA,IAACI,EAAAA,WAAU,CACTC,YAAY,iDACZC,MAAM,2BAMTV,GAA4B,IAAlBA,EAAOW,OASpBP,EAAAA,IAAC/C,EAAU,CAACuD,WAAS,EAACC,UAAU,KAAKhC,QAAS,WAC3CmB,EAAOc,KAAKC,IACX,MAAMC,EAAapB,EAAeqB,IAAIF,EAAMG,IAC5C,OACEd,EAAAA,IAAC7C,EAAI,CAAA,gBAEYyD,EACfH,UAAU,KACVN,KAAM,CAAEY,WAAY,EAAGC,QAAS,EAAGC,OAAQ,EAAGC,OAAQ,GAAGjB,SAEzDkB,EAAAA,KAAC5D,EAAiB,CAAA,aACJ,UAAYoD,EAAMS,SAC9BC,QAAS,IAAM5B,EAAakB,GAC5BW,UAAYC,IACI,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACzBD,EAAEE,iBACFhC,EAAakB,KAGjBe,KAAK,SACL9D,SAAUgD,EACVe,SAAU,EAAC1B,SAAA,CAEVW,GAAcZ,EAAAA,IAAC1B,EAAmB,CAAC6B,KAAK,OACzCH,EAAAA,IAAC4B,EAAI,CACHC,QAASlB,EAAMS,SACfU,QAAQ,GACRC,SAAUpB,EAAMqB,SAASC,QACzBC,SAAUvB,EAAMwB,UAvBfxB,EAAMG,SAZjBd,MAACV,EAAoB,CAAAW,SACnBD,EAAAA,IAACI,EAAAA,WAAU,CAACC,YAAY,kCAAkCC,MAAM"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import react__default from 'react';
|
|
2
|
+
import { Asset } from '../types/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for the LibraryTabContent component.
|
|
6
|
+
* @param orgId - Organization ID for fetching assets
|
|
7
|
+
* @param selectedAssets - Map of selected assets (id -> Asset) for O(1) lookup performance
|
|
8
|
+
* @param onAssetClick - Callback when an asset is clicked
|
|
9
|
+
* @param enabled - Whether the component is enabled (for conditional fetching)
|
|
10
|
+
*/
|
|
11
|
+
interface LibraryTabContentProps {
|
|
12
|
+
/** Organization ID for fetching assets */
|
|
13
|
+
orgId: string;
|
|
14
|
+
/** Map of selected assets (id -> Asset) for O(1) lookup performance */
|
|
15
|
+
selectedAssets: Map<string, Asset>;
|
|
16
|
+
/** Callback when an asset is clicked */
|
|
17
|
+
onAssetClick: (asset: Asset) => void;
|
|
18
|
+
/** Whether the component is enabled (for conditional fetching) */
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* LibraryTab component displays a grid of assets that can be selected.
|
|
23
|
+
* Handles fetching assets internally and displays loading/error states.
|
|
24
|
+
*
|
|
25
|
+
* @param props - The component props
|
|
26
|
+
* @returns The library tab content
|
|
27
|
+
*/
|
|
28
|
+
declare const LibraryTabContent: react__default.FC<LibraryTabContentProps>;
|
|
29
|
+
|
|
30
|
+
export { LibraryTabContent as default };
|
|
31
|
+
export type { LibraryTabContentProps };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import"react";import{styled as o}from"@mui/material/styles";import i from"@mui/material/Box";import r from"../../../atoms/Card/index.js";import{CircularProgress as a}from"../../../atoms/CircularProgress/index.js";import s from"@mui/material/Grid2";import{EmptyState as n}from"../../../molecules/EmptyState/index.js";import l from"../../../../icons/CheckmarkCircleSolid/index.js";import{useGetAssets as d}from"../hooks/useAssets.js";const m=o(s)((()=>({listStyle:"none",margin:0,padding:0}))),c=o(i,{shouldForwardProp:e=>"selected"!==e})((({theme:e,selected:t})=>({width:"100%",cursor:"pointer",position:"relative","& .MuiCard-root":{borderWidth:"2px",borderColor:t?e.palette.semantic.stroke["stroke-selected"]:"transparent",boxShadow:t?"none":`inset 0 0 0 1px ${e.palette.semantic.stroke["stroke-weak"]}`},"&:focus-visible .MuiCard-root":{borderColor:e.palette.semantic.stroke["stroke-selected"],boxShadow:"none"}}))),p=o(l)((({theme:e})=>({position:"absolute",top:e.spacing(2),left:e.spacing(2),zIndex:1,color:e.palette.semantic.icon["icon-primary"],"& circle":{fill:e.palette.common.white}}))),g=o(i)((({theme:e})=>({display:"flex",justifyContent:"center",alignItems:"center",minHeight:"200px",padding:e.spacing(4)}))),h=o(i)((({theme:e})=>({padding:e.spacing(4)}))),u=({orgId:o,selectedAssets:i,onAssetClick:l,enabled:u=!0})=>{const{data:f,isLoading:x,error:k}=d(o,u);return x?e(g,{children:e(a,{size:"large"})}):k?e(h,{children:e(n,{description:"Failed to load assets. Please try again later.",title:"Error loading assets"})}):f&&0!==f.length?e(m,{container:!0,component:"ul",spacing:1,children:f.map((o=>{const a=i.has(o.id);return e(s,{"aria-selected":a,component:"li",size:{widescreen:3,desktop:3,mobile:6,tablet:4},children:t(c,{"aria-label":"Select "+o.fileName,onClick:()=>l(o),onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),l(o))},role:"button",selected:a,tabIndex:0,children:[a&&e(p,{size:"lg"}),e(r,{content:o.fileName,heading:"",imageAlt:o.metadata.altText,imageSrc:o.url})]})},o.id)}))}):e(h,{children:e(n,{description:"No assets available to display.",title:"No assets found"})})};export{u as default};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/components/organisms/AssetManager/LibraryTabContent/index.tsx"],"sourcesContent":["import React from 'react';\n\nimport { styled } from '@mui/material/styles';\n\nimport Box from '@fd/components/atoms/Box';\nimport Card from '@fd/components/atoms/Card';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport Grid from '@fd/components/atoms/Grid';\nimport EmptyState from '@fd/components/molecules/EmptyState';\nimport CheckmarkCircleSolidIcon from '@fd/icons/CheckmarkCircleSolid';\n\nimport { useGetAssets } from '../hooks/useAssets';\nimport type { Asset } from '../types';\n\nconst StyledList = styled(Grid)<{ component: string }>(() => ({\n listStyle: 'none',\n margin: 0,\n padding: 0,\n}));\n\nconst StyledCardWrapper = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'selected',\n})<{ selected?: boolean }>(({ theme, selected }) => ({\n width: '100%',\n cursor: 'pointer',\n position: 'relative',\n '& .MuiCard-root': {\n // Always use 2px border to prevent layout shift\n borderWidth: '2px',\n borderColor: selected ? theme.palette.semantic.stroke['stroke-selected'] : 'transparent',\n // Use box-shadow to create the visual 1px border when not selected\n // This prevents layout shift while maintaining the visual appearance\n boxShadow: selected ? 'none' : `inset 0 0 0 1px ${theme.palette.semantic.stroke['stroke-weak']}`,\n },\n '&:focus-visible .MuiCard-root': {\n borderColor: theme.palette.semantic.stroke['stroke-selected'],\n boxShadow: 'none',\n },\n}));\n\nconst StyledCheckmarkIcon = styled(CheckmarkCircleSolidIcon)(({ theme }) => ({\n position: 'absolute',\n top: theme.spacing(2),\n left: theme.spacing(2),\n zIndex: 1,\n color: theme.palette.semantic.icon['icon-primary'],\n '& circle': {\n fill: theme.palette.common.white,\n },\n}));\n\nconst StyledLoadingContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '200px',\n padding: theme.spacing(4),\n}));\n\nconst StyledErrorContainer = styled(Box)(({ theme }) => ({\n padding: theme.spacing(4),\n}));\n\n/**\n * Props for the LibraryTabContent component.\n * @param orgId - Organization ID for fetching assets\n * @param selectedAssets - Map of selected assets (id -> Asset) for O(1) lookup performance\n * @param onAssetClick - Callback when an asset is clicked\n * @param enabled - Whether the component is enabled (for conditional fetching)\n */\nexport interface LibraryTabContentProps {\n /** Organization ID for fetching assets */\n orgId: string;\n /** Map of selected assets (id -> Asset) for O(1) lookup performance */\n selectedAssets: Map<string, Asset>;\n /** Callback when an asset is clicked */\n onAssetClick: (asset: Asset) => void;\n /** Whether the component is enabled (for conditional fetching) */\n enabled?: boolean;\n}\n\n/**\n * LibraryTab component displays a grid of assets that can be selected.\n * Handles fetching assets internally and displays loading/error states.\n *\n * @param props - The component props\n * @returns The library tab content\n */\nconst LibraryTabContent: React.FC<LibraryTabContentProps> = ({\n orgId,\n selectedAssets,\n onAssetClick,\n enabled = true,\n}) => {\n const { data: assets, isLoading, error } = useGetAssets(orgId, enabled);\n\n if (isLoading) {\n return (\n <StyledLoadingContainer>\n <CircularProgress size=\"large\" />\n </StyledLoadingContainer>\n );\n }\n\n if (error) {\n return (\n <StyledErrorContainer>\n <EmptyState\n description=\"Failed to load assets. Please try again later.\"\n title=\"Error loading assets\"\n />\n </StyledErrorContainer>\n );\n }\n\n if (!assets || assets.length === 0) {\n return (\n <StyledErrorContainer>\n <EmptyState description=\"No assets available to display.\" title=\"No assets found\" />\n </StyledErrorContainer>\n );\n }\n\n return (\n <StyledList container component=\"ul\" spacing={1}>\n {assets.map((asset: Asset) => {\n const isSelected = selectedAssets.has(asset.id);\n return (\n <Grid\n key={asset.id}\n aria-selected={isSelected}\n component=\"li\"\n size={{ widescreen: 3, desktop: 3, mobile: 6, tablet: 4 }}\n >\n <StyledCardWrapper\n aria-label={'Select ' + asset.fileName} // TODO: translate this text when translate provider is added\n onClick={() => onAssetClick(asset)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onAssetClick(asset);\n }\n }}\n role=\"button\"\n selected={isSelected}\n tabIndex={0}\n >\n {isSelected && <StyledCheckmarkIcon size=\"lg\" />}\n <Card\n content={asset.fileName}\n heading=\"\"\n imageAlt={asset.metadata.altText}\n imageSrc={asset.url}\n />\n </StyledCardWrapper>\n </Grid>\n );\n })}\n </StyledList>\n );\n};\n\nexport default LibraryTabContent;\n"],"names":["StyledList","styled","Grid","listStyle","margin","padding","StyledCardWrapper","Box","shouldForwardProp","prop","theme","selected","width","cursor","position","borderWidth","borderColor","palette","semantic","stroke","boxShadow","StyledCheckmarkIcon","CheckmarkCircleSolidIcon","top","spacing","left","zIndex","color","icon","fill","common","white","StyledLoadingContainer","display","justifyContent","alignItems","minHeight","StyledErrorContainer","LibraryTabContent","orgId","selectedAssets","onAssetClick","enabled","data","assets","isLoading","error","useGetAssets","_jsx","children","CircularProgress","size","EmptyState","description","title","length","container","component","map","asset","isSelected","has","id","widescreen","desktop","mobile","tablet","_jsxs","fileName","onClick","onKeyDown","e","key","preventDefault","role","tabIndex","Card","content","heading","imageAlt","metadata","altText","imageSrc","url"],"mappings":"keAcA,MAAMA,EAAaC,EAAOC,EAAPD,EAAoC,KAAA,CACrDE,UAAW,OACXC,OAAQ,EACRC,QAAS,MAGLC,EAAoBL,EAAOM,EAAK,CACpCC,kBAAoBC,GAAkB,aAATA,GADLR,EAEC,EAAGS,QAAOC,eAAU,CAC7CC,MAAO,OACPC,OAAQ,UACRC,SAAU,WACV,kBAAmB,CAEjBC,YAAa,MACbC,YAAaL,EAAWD,EAAMO,QAAQC,SAASC,OAAO,mBAAqB,cAG3EC,UAAWT,EAAW,OAAS,mBAAmBD,EAAMO,QAAQC,SAASC,OAAO,kBAElF,gCAAiC,CAC/BH,YAAaN,EAAMO,QAAQC,SAASC,OAAO,mBAC3CC,UAAW,YAITC,EAAsBpB,EAAOqB,EAAPrB,EAAiC,EAAGS,YAAO,CACrEI,SAAU,WACVS,IAAKb,EAAMc,QAAQ,GACnBC,KAAMf,EAAMc,QAAQ,GACpBE,OAAQ,EACRC,MAAOjB,EAAMO,QAAQC,SAASU,KAAK,gBACnC,WAAY,CACVC,KAAMnB,EAAMO,QAAQa,OAAOC,WAIzBC,EAAyB/B,EAAOM,EAAPN,EAAY,EAAGS,YAAO,CACnDuB,QAAS,OACTC,eAAgB,SAChBC,WAAY,SACZC,UAAW,QACX/B,QAASK,EAAMc,QAAQ,OAGnBa,EAAuBpC,EAAOM,EAAPN,EAAY,EAAGS,YAAO,CACjDL,QAASK,EAAMc,QAAQ,OA4BnBc,EAAsD,EAC1DC,QACAC,iBACAC,eACAC,WAAU,MAEV,MAAQC,KAAMC,EAAMC,UAAEA,EAASC,MAAEA,GAAUC,EAAaR,EAAOG,GAE/D,OAAIG,EAEAG,EAAChB,EAAsB,CAAAiB,SACrBD,EAACE,EAAgB,CAACC,KAAK,YAKzBL,EAEAE,EAACX,EAAoB,CAAAY,SACnBD,EAACI,EAAU,CACTC,YAAY,iDACZC,MAAM,2BAMTV,GAA4B,IAAlBA,EAAOW,OASpBP,EAAChD,EAAU,CAACwD,WAAS,EAACC,UAAU,KAAKjC,QAAS,WAC3CoB,EAAOc,KAAKC,IACX,MAAMC,EAAapB,EAAeqB,IAAIF,EAAMG,IAC5C,OACEd,EAAC9C,EAAI,CAAA,gBAEY0D,EACfH,UAAU,KACVN,KAAM,CAAEY,WAAY,EAAGC,QAAS,EAAGC,OAAQ,EAAGC,OAAQ,GAAGjB,SAEzDkB,EAAC7D,EAAiB,CAAA,aACJ,UAAYqD,EAAMS,SAC9BC,QAAS,IAAM5B,EAAakB,GAC5BW,UAAYC,IACI,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACzBD,EAAEE,iBACFhC,EAAakB,KAGjBe,KAAK,SACL/D,SAAUiD,EACVe,SAAU,EAAC1B,SAAA,CAEVW,GAAcZ,EAAC3B,EAAmB,CAAC8B,KAAK,OACzCH,EAAC4B,EAAI,CACHC,QAASlB,EAAMS,SACfU,QAAQ,GACRC,SAAUpB,EAAMqB,SAASC,QACzBC,SAAUvB,EAAMwB,UAvBfxB,EAAMG,SAZjBd,EAACX,EAAoB,CAAAY,SACnBD,EAACI,EAAU,CAACC,YAAY,kCAAkCC,MAAM"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime");require("react");var i=require("../../../../utilities/fileUtils.cjs.js"),l=require("../../FileUpload/index.cjs.js");const s=["jpg","jpeg","png","gif","bmp","tiff","ico","webp"];module.exports=({files:r,onUpload:o,onRemove:a})=>e.jsx(l,{allowedFileTypes:s,files:r,label:"",maxFiles:10,maxFileSize:i.TEN_MB_IN_BYTES,onRemove:a,onUpload:o});
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../../src/components/organisms/AssetManager/UploadTabContent/index.tsx"],"sourcesContent":["import React from 'react';\n\nimport { TEN_MB_IN_BYTES } from '@fd/utilities/fileUtils';\n\nimport FileUpload, { type FileUploadState } from '../../FileUpload';\n\nconst ALLOWED_FILE_TYPES = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'ico', 'webp'];\nconst MAX_FILES = 10;\n\n/**\n * Props for the UploadTabContent component.\n * @param files - Array of file upload states\n * @param onUpload - Callback fired when files are uploaded\n * @param onRemove - Callback fired when a file is removed\n */\nexport interface UploadTabContentProps {\n /** Array of file upload states */\n files: FileUploadState[];\n /** Callback fired when files are uploaded */\n onUpload: (files: File[]) => void;\n /** Callback fired when a file is removed */\n onRemove: (file: File) => void;\n}\n\n/**\n * UploadAsset component provides a file upload interface for uploading new assets.\n *\n * @param props - The component props\n * @returns The upload tab content\n */\nconst UploadTabContent: React.FC<UploadTabContentProps> = ({ files, onUpload, onRemove }) => {\n return (\n <FileUpload\n allowedFileTypes={ALLOWED_FILE_TYPES}\n files={files}\n label=\"\"\n maxFiles={MAX_FILES}\n maxFileSize={TEN_MB_IN_BYTES}\n onRemove={onRemove}\n onUpload={onUpload}\n />\n );\n};\n\nexport default UploadTabContent;\n"],"names":["ALLOWED_FILE_TYPES","files","onUpload","onRemove","_jsx","FileUpload","allowedFileTypes","label","maxFiles","maxFileSize","TEN_MB_IN_BYTES"],"mappings":"oKAMA,MAAMA,EAAqB,CAAC,MAAO,OAAQ,MAAO,MAAO,MAAO,OAAQ,MAAO,uBAwBrB,EAAGC,QAAOC,WAAUC,cAE1EC,EAAAA,IAACC,EAAU,CACTC,iBAAkBN,EAClBC,MAAOA,EACPM,MAAM,GACNC,SA7BY,GA8BZC,YAAaC,EAAAA,gBACbP,SAAUA,EACVD,SAAUA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import react__default from 'react';
|
|
2
|
+
import { FileUploadState } from '../../FileUpload/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Props for the UploadTabContent component.
|
|
6
|
+
* @param files - Array of file upload states
|
|
7
|
+
* @param onUpload - Callback fired when files are uploaded
|
|
8
|
+
* @param onRemove - Callback fired when a file is removed
|
|
9
|
+
*/
|
|
10
|
+
interface UploadTabContentProps {
|
|
11
|
+
/** Array of file upload states */
|
|
12
|
+
files: FileUploadState[];
|
|
13
|
+
/** Callback fired when files are uploaded */
|
|
14
|
+
onUpload: (files: File[]) => void;
|
|
15
|
+
/** Callback fired when a file is removed */
|
|
16
|
+
onRemove: (file: File) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* UploadAsset component provides a file upload interface for uploading new assets.
|
|
20
|
+
*
|
|
21
|
+
* @param props - The component props
|
|
22
|
+
* @returns The upload tab content
|
|
23
|
+
*/
|
|
24
|
+
declare const UploadTabContent: react__default.FC<UploadTabContentProps>;
|
|
25
|
+
|
|
26
|
+
export { UploadTabContent as default };
|
|
27
|
+
export type { UploadTabContentProps };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import"react";import{TEN_MB_IN_BYTES as i}from"../../../../utilities/fileUtils.js";import o from"../../FileUpload/index.js";const l=["jpg","jpeg","png","gif","bmp","tiff","ico","webp"],p=({files:p,onUpload:t,onRemove:m})=>e(o,{allowedFileTypes:l,files:p,label:"",maxFiles:10,maxFileSize:i,onRemove:m,onUpload:t});export{p as default};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/components/organisms/AssetManager/UploadTabContent/index.tsx"],"sourcesContent":["import React from 'react';\n\nimport { TEN_MB_IN_BYTES } from '@fd/utilities/fileUtils';\n\nimport FileUpload, { type FileUploadState } from '../../FileUpload';\n\nconst ALLOWED_FILE_TYPES = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'ico', 'webp'];\nconst MAX_FILES = 10;\n\n/**\n * Props for the UploadTabContent component.\n * @param files - Array of file upload states\n * @param onUpload - Callback fired when files are uploaded\n * @param onRemove - Callback fired when a file is removed\n */\nexport interface UploadTabContentProps {\n /** Array of file upload states */\n files: FileUploadState[];\n /** Callback fired when files are uploaded */\n onUpload: (files: File[]) => void;\n /** Callback fired when a file is removed */\n onRemove: (file: File) => void;\n}\n\n/**\n * UploadAsset component provides a file upload interface for uploading new assets.\n *\n * @param props - The component props\n * @returns The upload tab content\n */\nconst UploadTabContent: React.FC<UploadTabContentProps> = ({ files, onUpload, onRemove }) => {\n return (\n <FileUpload\n allowedFileTypes={ALLOWED_FILE_TYPES}\n files={files}\n label=\"\"\n maxFiles={MAX_FILES}\n maxFileSize={TEN_MB_IN_BYTES}\n onRemove={onRemove}\n onUpload={onUpload}\n />\n );\n};\n\nexport default UploadTabContent;\n"],"names":["ALLOWED_FILE_TYPES","UploadTabContent","files","onUpload","onRemove","_jsx","FileUpload","allowedFileTypes","label","maxFiles","maxFileSize","TEN_MB_IN_BYTES"],"mappings":"oKAMA,MAAMA,EAAqB,CAAC,MAAO,OAAQ,MAAO,MAAO,MAAO,OAAQ,MAAO,QAwBzEC,EAAoD,EAAGC,QAAOC,WAAUC,cAE1EC,EAACC,EAAU,CACTC,iBAAkBP,EAClBE,MAAOA,EACPM,MAAM,GACNC,SA7BY,GA8BZC,YAAaC,EACbP,SAAUA,EACVD,SAAUA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("@tanstack/react-query"),
|
|
1
|
+
"use strict";var e=require("../../../../utilities/timeUtilities.cjs.js"),s=require("@tanstack/react-query"),t=require("../services/asset.service.cjs.js");exports.useGetAssets=(r,i=!0)=>s.useQuery({queryKey:[t.getAssetsKey,r],queryFn:()=>t.getAssets(r),enabled:i,gcTime:e.TEN_MINUTES});
|
|
2
2
|
//# sourceMappingURL=useAssets.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssets.cjs.js","sources":["../../../../../src/components/organisms/AssetManager/hooks/useAssets.ts"],"sourcesContent":["import { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { getAssets, getAssetsKey } from '../services/asset.service';\nimport type { Asset } from '../types';\n\n/**\n * Hook to fetch assets from the API\n * Automatically determines the API URL based on environment and orgId\n * @param orgId - Organization ID\n * @param enabled - Whether the query should be enabled\n * @returns Query result with assets data, loading state, and error state\n */\nexport const useGetAssets = (orgId: string, enabled = true): UseQueryResult<Asset[], Error> => {\n return useQuery<Asset[]>({\n queryKey: [getAssetsKey, orgId],\n queryFn: () => getAssets(orgId),\n enabled,\n
|
|
1
|
+
{"version":3,"file":"useAssets.cjs.js","sources":["../../../../../src/components/organisms/AssetManager/hooks/useAssets.ts"],"sourcesContent":["import { TEN_MINUTES } from '@fd/utilities/timeUtilities';\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { getAssets, getAssetsKey } from '../services/asset.service';\nimport type { Asset } from '../types';\n\n/**\n * Hook to fetch assets from the API\n * Automatically determines the API URL based on environment and orgId\n * @param orgId - Organization ID\n * @param enabled - Whether the query should be enabled\n * @returns Query result with assets data, loading state, and error state\n */\nexport const useGetAssets = (orgId: string, enabled = true): UseQueryResult<Asset[], Error> => {\n return useQuery<Asset[]>({\n queryKey: [getAssetsKey, orgId],\n queryFn: () => getAssets(orgId),\n enabled,\n gcTime: TEN_MINUTES,\n });\n};\n"],"names":["orgId","enabled","useQuery","queryKey","getAssetsKey","queryFn","getAssets","gcTime","TEN_MINUTES"],"mappings":"+KAa4B,CAACA,EAAeC,GAAU,IAC7CC,WAAkB,CACvBC,SAAU,CAACC,EAAAA,aAAcJ,GACzBK,QAAS,IAAMC,EAAAA,UAAUN,GACzBC,UACAM,OAAQC,EAAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{TEN_MINUTES as e}from"../../../../utilities/timeUtilities.js";import{useQuery as t}from"@tanstack/react-query";import{getAssets as i,getAssetsKey as r}from"../services/asset.service.js";const s=(s,m=!0)=>t({queryKey:[r,s],queryFn:()=>i(s),enabled:m,gcTime:e});export{s as useGetAssets};
|
|
2
2
|
//# sourceMappingURL=useAssets.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAssets.js","sources":["../../../../../src/components/organisms/AssetManager/hooks/useAssets.ts"],"sourcesContent":["import { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { getAssets, getAssetsKey } from '../services/asset.service';\nimport type { Asset } from '../types';\n\n/**\n * Hook to fetch assets from the API\n * Automatically determines the API URL based on environment and orgId\n * @param orgId - Organization ID\n * @param enabled - Whether the query should be enabled\n * @returns Query result with assets data, loading state, and error state\n */\nexport const useGetAssets = (orgId: string, enabled = true): UseQueryResult<Asset[], Error> => {\n return useQuery<Asset[]>({\n queryKey: [getAssetsKey, orgId],\n queryFn: () => getAssets(orgId),\n enabled,\n
|
|
1
|
+
{"version":3,"file":"useAssets.js","sources":["../../../../../src/components/organisms/AssetManager/hooks/useAssets.ts"],"sourcesContent":["import { TEN_MINUTES } from '@fd/utilities/timeUtilities';\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\n\nimport { getAssets, getAssetsKey } from '../services/asset.service';\nimport type { Asset } from '../types';\n\n/**\n * Hook to fetch assets from the API\n * Automatically determines the API URL based on environment and orgId\n * @param orgId - Organization ID\n * @param enabled - Whether the query should be enabled\n * @returns Query result with assets data, loading state, and error state\n */\nexport const useGetAssets = (orgId: string, enabled = true): UseQueryResult<Asset[], Error> => {\n return useQuery<Asset[]>({\n queryKey: [getAssetsKey, orgId],\n queryFn: () => getAssets(orgId),\n enabled,\n gcTime: TEN_MINUTES,\n });\n};\n"],"names":["useGetAssets","orgId","enabled","useQuery","queryKey","getAssetsKey","queryFn","getAssets","gcTime","TEN_MINUTES"],"mappings":"iMAaO,MAAMA,EAAe,CAACC,EAAeC,GAAU,IAC7CC,EAAkB,CACvBC,SAAU,CAACC,EAAcJ,GACzBK,QAAS,IAAMC,EAAUN,GACzBC,UACAM,OAAQC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),a=require("react"),l=require("@mui/material/styles"),s=require("@mui/material/Box"),r=require("@mui/material/Tab"),t=require("../../molecules/Modal/index.cjs.js"),i=require("../../molecules/Tabs/index.cjs.js"),n=require("./LibraryTabContent/index.cjs.js"),o=require("./UploadTabContent/index.cjs.js");const c=l.styled(s)((({theme:e})=>({marginBottom:e.spacing(3)})));module.exports=({open:l,onClose:s,onSelect:u,orgId:d,multiSelect:b=!1})=>{const[m,p]=a.useState(new Map),[j,y]=a.useState("library"),[C,g]=a.useState([]);a.useEffect((()=>{l||(p(new Map),g([]))}),[l]);const x=a.useCallback((()=>{p(new Map),s()}),[s]),k=a.useCallback((()=>{const e=Array.from(m.values());u&&e.length>0&&u(e),p(new Map),s()}),[u,m,s]),v=a.useCallback((e=>{p((a=>{const l=a.has(e.id),s=new Map(a);return b?l?s.delete(e.id):s.set(e.id,e):l?s.clear():(s.clear(),s.set(e.id,e)),s}))}),[b]),h=a.useCallback((()=>{g([]),y("library")}),[]),q=a.useCallback((e=>{const a=e.map((e=>({file:e})));g((e=>[...e,...a]))}),[]),f=a.useCallback((e=>{g((a=>a.filter((a=>a.file!==e))))}),[]),S=a.useMemo((()=>{const e={label:"Cancel",onClick:x,variant:"secondary",tone:"neutral",id:"asset-manager-cancel"},a={library:[e,{label:"Select",onClick:k,variant:"primary",disabled:0===m.size,id:"asset-manager-select"}],upload:[e,{label:"Save",onClick:h,disabled:0===C.length,variant:"primary",id:"asset-manager-upload"}]};return a[j]??a.library}),[j,m.size,C.length,x,k,h]);return e.jsxs(t,{actions:S,onClose:x,open:l,size:"large",title:"library"===j?"Select Images":"Upload Images",children:[e.jsx(c,{children:e.jsxs(i,{fdKey:"asset-manager-tabs",onChange:(e,a)=>y(a),value:j,children:[e.jsx(r,{label:"Upload",value:"upload"}),e.jsx(r,{label:"Library",value:"library"})]})}),"library"===j?e.jsx(n,{enabled:l,onAssetClick:v,orgId:d,selectedAssets:m}):e.jsx(o,{files:C,onRemove:f,onUpload:q})]})};
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/organisms/AssetManager/index.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\n\nimport { styled } from '@mui/material/styles';\n\nimport Box from '@fd/components/atoms/Box';\nimport Card from '@fd/components/atoms/Card';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport Grid from '@fd/components/atoms/Grid';\nimport Tab from '@fd/components/atoms/Tab';\nimport EmptyState from '@fd/components/molecules/EmptyState';\nimport Modal from '@fd/components/molecules/Modal';\nimport Tabs from '@fd/components/molecules/Tabs';\nimport CheckmarkCircleSolidIcon from '@fd/icons/CheckmarkCircleSolid';\n\nimport { useGetAssets } from './hooks/useAssets';\nimport type { Asset } from './types';\n\nconst StyledTabsContainer = styled(Box)(({ theme }) => ({\n marginBottom: theme.spacing(3),\n}));\n\nconst StyledCardWrapper = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'selected',\n})<{ selected?: boolean }>(({ theme, selected }) => ({\n width: '100%',\n cursor: 'pointer',\n position: 'relative',\n '& .MuiCard-root': {\n // Always use 2px border to prevent layout shift\n borderWidth: '2px',\n borderColor: selected ? theme.palette.semantic.stroke['stroke-selected'] : 'transparent',\n // Use box-shadow to create the visual 1px border when not selected\n // This prevents layout shift while maintaining the visual appearance\n boxShadow: selected ? 'none' : `inset 0 0 0 1px ${theme.palette.semantic.stroke['stroke-weak']}`,\n },\n '&:hover': {\n opacity: 0.9,\n },\n '&:focus-visible .MuiCard-root': {\n borderColor: theme.palette.semantic.stroke['stroke-selected'],\n boxShadow: 'none',\n },\n}));\n\nconst StyledCheckmarkIcon = styled(CheckmarkCircleSolidIcon)(({ theme }) => ({\n position: 'absolute',\n top: theme.spacing(2),\n left: theme.spacing(2),\n zIndex: 1,\n color: theme.palette.semantic.icon['icon-primary'],\n '& circle': {\n fill: theme.palette.common.white,\n },\n}));\n\n/**\n * Props for the AssetManager component.\n * Provides a modal interface for selecting images from a grid display.\n * It supports both single and multiple image selection modes.\n *\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n *\n * ```tsx\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n */\nexport interface AssetManagerProps {\n /** Whether the asset manager modal is open */\n open: boolean;\n /** Callback function when the modal is closed or cancelled */\n onClose: () => void;\n /** Callback function when assets are selected */\n onSelect?: (selectedAssets: Asset[]) => void;\n /**\n * Organization ID for fetching assets\n */\n orgId: string;\n /** Whether multiple assets can be selected. Defaults to false */\n multiSelect?: boolean;\n}\n\nconst StyledLoadingContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '200px',\n padding: theme.spacing(4),\n}));\n\nconst StyledErrorContainer = styled(Box)(({ theme }) => ({\n padding: theme.spacing(4),\n}));\n\nconst AssetManager: React.FC<AssetManagerProps> = ({\n open,\n onClose,\n onSelect,\n orgId,\n multiSelect = false,\n}) => {\n const [selectedAssetIds, setSelectedAssetIds] = useState<string[]>([]);\n\n // Fetch assets from API - service handles everything\n const { data: assets, isLoading, error } = useGetAssets(orgId, open);\n\n // Reset selection when modal opens/closes\n useEffect(() => {\n if (!open) {\n setSelectedAssetIds([]);\n }\n }, [open]);\n\n const handleCancel = (): void => {\n setSelectedAssetIds([]);\n onClose();\n };\n\n const handleSelect = (): void => {\n if (onSelect && assets) {\n const selectedAssets = assets.filter((asset: Asset) => selectedAssetIds.includes(asset.id));\n onSelect(selectedAssets);\n }\n setSelectedAssetIds([]);\n onClose();\n };\n\n const handleAssetClick = (assetId: string): void => {\n setSelectedAssetIds((prev) => {\n if (multiSelect) {\n if (prev.includes(assetId)) {\n return prev.filter((id) => id !== assetId);\n }\n return [...prev, assetId];\n } else {\n if (prev.includes(assetId)) {\n return [];\n }\n return [assetId];\n }\n });\n };\n\n const getActions = () => {\n return [\n {\n label: 'Cancel',\n onClick: handleCancel,\n variant: 'secondary' as const,\n tone: 'neutral' as const,\n id: 'asset-manager-cancel',\n },\n {\n label: 'Select',\n onClick: handleSelect,\n variant: 'primary' as const,\n disabled: selectedAssetIds.length === 0,\n id: 'asset-manager-select',\n },\n ];\n };\n\n const renderBrowseTab = (): React.ReactElement => {\n if (isLoading) {\n return (\n <StyledLoadingContainer>\n <CircularProgress size=\"large\" />\n </StyledLoadingContainer>\n );\n }\n\n if (error) {\n return (\n <StyledErrorContainer>\n <EmptyState\n description=\"Failed to load assets. Please try again later.\"\n title=\"Error loading assets\"\n />\n </StyledErrorContainer>\n );\n }\n\n if (!assets || assets.length === 0) {\n return (\n <StyledErrorContainer>\n <EmptyState description=\"No assets available to display.\" title=\"No assets found\" />\n </StyledErrorContainer>\n );\n }\n\n return (\n <Grid container component=\"ul\" spacing={1} sx={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {assets.map((asset: Asset) => {\n const isSelected = selectedAssetIds.includes(asset.id);\n return (\n <Grid\n key={asset.id}\n aria-selected={isSelected}\n component=\"li\"\n size={{ widescreen: 3, desktop: 3, mobile: 6, tablet: 4 }}\n >\n <StyledCardWrapper\n aria-label={'Select ' + asset.fileName} // TODO: translate this text when translate provider is added\n onClick={() => handleAssetClick(asset.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleAssetClick(asset.id);\n }\n }}\n role=\"button\"\n selected={isSelected}\n tabIndex={0}\n >\n {isSelected && <StyledCheckmarkIcon size=\"lg\" />}\n <Card\n content={asset.fileName}\n heading=\"\"\n imageAlt={asset.metadata.altText}\n imageSrc={asset.url}\n />\n </StyledCardWrapper>\n </Grid>\n );\n })}\n </Grid>\n );\n };\n\n return (\n // TODO: replace this with a new modal component when available\n <Modal actions={getActions()} onClose={handleCancel} open={open} title=\"Select Images\">\n <StyledTabsContainer>\n {/* TODO: replace this with a new tabs component when available */}\n <Tabs fdKey=\"asset-manager-tabs\" onChange={() => {}} value={1}>\n <Tab label=\"Upload\" />\n <Tab label=\"Library\" />\n </Tabs>\n </StyledTabsContainer>\n {renderBrowseTab()}\n </Modal>\n );\n};\n\nexport default AssetManager;\n"],"names":["StyledTabsContainer","styled","Box","theme","marginBottom","spacing","StyledCardWrapper","shouldForwardProp","prop","selected","width","cursor","position","borderWidth","borderColor","palette","semantic","stroke","boxShadow","opacity","StyledCheckmarkIcon","CheckmarkCircleSolidIcon","top","left","zIndex","color","icon","fill","common","white","StyledLoadingContainer","display","justifyContent","alignItems","minHeight","padding","StyledErrorContainer","open","onClose","onSelect","orgId","multiSelect","selectedAssetIds","setSelectedAssetIds","useState","data","assets","isLoading","error","useGetAssets","useEffect","handleCancel","handleSelect","selectedAssets","filter","asset","includes","id","handleAssetClick","assetId","prev","_jsxs","Modal","actions","label","onClick","variant","tone","disabled","length","title","children","_jsx","Tabs","fdKey","onChange","value","Tab","CircularProgress","size","EmptyState","description","Grid","container","component","sx","listStyle","margin","map","isSelected","widescreen","desktop","mobile","tablet","fileName","onKeyDown","e","key","preventDefault","role","tabIndex","Card","content","heading","imageAlt","metadata","altText","imageSrc","url"],"mappings":"8hBAiBA,MAAMA,EAAsBC,EAAAA,OAAOC,EAAPD,EAAY,EAAGE,YAAO,CAChDC,aAAcD,EAAME,QAAQ,OAGxBC,EAAoBL,EAAAA,OAAOC,EAAK,CACpCK,kBAAoBC,GAAkB,aAATA,GADLP,EAEC,EAAGE,QAAOM,eAAU,CAC7CC,MAAO,OACPC,OAAQ,UACRC,SAAU,WACV,kBAAmB,CAEjBC,YAAa,MACbC,YAAaL,EAAWN,EAAMY,QAAQC,SAASC,OAAO,mBAAqB,cAG3EC,UAAWT,EAAW,OAAS,mBAAmBN,EAAMY,QAAQC,SAASC,OAAO,kBAElF,UAAW,CACTE,QAAS,IAEX,gCAAiC,CAC/BL,YAAaX,EAAMY,QAAQC,SAASC,OAAO,mBAC3CC,UAAW,YAITE,EAAsBnB,EAAAA,OAAOoB,EAAPpB,EAAiC,EAAGE,YAAO,CACrES,SAAU,WACVU,IAAKnB,EAAME,QAAQ,GACnBkB,KAAMpB,EAAME,QAAQ,GACpBmB,OAAQ,EACRC,MAAOtB,EAAMY,QAAQC,SAASU,KAAK,gBACnC,WAAY,CACVC,KAAMxB,EAAMY,QAAQa,OAAOC,WA6BzBC,EAAyB7B,EAAAA,OAAOC,EAAPD,EAAY,EAAGE,YAAO,CACnD4B,QAAS,OACTC,eAAgB,SAChBC,WAAY,SACZC,UAAW,QACXC,QAAShC,EAAME,QAAQ,OAGnB+B,EAAuBnC,EAAAA,OAAOC,EAAPD,EAAY,EAAGE,YAAO,CACjDgC,QAAShC,EAAME,QAAQ,sBAGyB,EAChDgC,OACAC,UACAC,WACAC,QACAC,eAAc,MAEd,MAAOC,EAAkBC,GAAuBC,EAAAA,SAAmB,KAG3DC,KAAMC,EAAMC,UAAEA,EAASC,MAAEA,GAAUC,EAAAA,aAAaT,EAAOH,GAG/Da,EAAAA,WAAU,KACHb,GACHM,EAAoB,MAErB,CAACN,IAEJ,MAAMc,EAAe,KACnBR,EAAoB,IACpBL,KAGIc,EAAe,KACnB,GAAIb,GAAYO,EAAQ,CACtB,MAAMO,EAAiBP,EAAOQ,QAAQC,GAAiBb,EAAiBc,SAASD,EAAME,MACvFlB,EAASc,EACX,CACAV,EAAoB,IACpBL,KAGIoB,EAAoBC,IACxBhB,GAAqBiB,GACfnB,EACEmB,EAAKJ,SAASG,GACTC,EAAKN,QAAQG,GAAOA,IAAOE,IAE7B,IAAIC,EAAMD,GAEbC,EAAKJ,SAASG,GACT,GAEF,CAACA,MA2Fd,OAEEE,OAACC,EAAK,CAACC,QAvFA,CACL,CACEC,MAAO,SACPC,QAASd,EACTe,QAAS,YACTC,KAAM,UACNV,GAAI,wBAEN,CACEO,MAAO,SACPC,QAASb,EACTc,QAAS,UACTE,SAAsC,IAA5B1B,EAAiB2B,OAC3BZ,GAAI,yBA0EsBnB,QAASa,EAAcd,KAAMA,EAAMiC,MAAM,gBAAeC,SAAA,CACpFC,MAACxE,EAAmB,CAAAuE,SAElBV,EAAAA,KAACY,EAAI,CAACC,MAAM,qBAAqBC,SAAU,OAAUC,MAAO,EAACL,SAAA,CAC3DC,EAAAA,IAACK,EAAG,CAACb,MAAM,WACXQ,EAAAA,IAACK,EAAG,CAACb,MAAM,iBAzEbjB,EAEAyB,EAAAA,IAAC1C,EAAsB,CAAAyC,SACrBC,EAAAA,IAACM,EAAAA,iBAAgB,CAACC,KAAK,YAKzB/B,EAEAwB,MAACpC,EAAoB,CAAAmC,SACnBC,EAAAA,IAACQ,EAAAA,WAAU,CACTC,YAAY,iDACZX,MAAM,2BAMTxB,GAA4B,IAAlBA,EAAOuB,OASpBG,EAAAA,IAACU,EAAI,CAACC,aAAUC,UAAU,KAAK/E,QAAS,EAAGgF,GAAI,CAAEC,UAAW,OAAQC,OAAQ,EAAGpD,QAAS,GAAGoC,SACxFzB,EAAO0C,KAAKjC,IACX,MAAMkC,EAAa/C,EAAiBc,SAASD,EAAME,IACnD,OACEe,EAAAA,IAACU,EAAI,CAAA,gBAEYO,EACfL,UAAU,KACVL,KAAM,CAAEW,WAAY,EAAGC,QAAS,EAAGC,OAAQ,EAAGC,OAAQ,GAAGtB,SAEzDV,EAAAA,KAACvD,EAAiB,CAAA,aACJ,UAAYiD,EAAMuC,SAC9B7B,QAAS,IAAMP,EAAiBH,EAAME,IACtCsC,UAAYC,IACI,UAAVA,EAAEC,KAA6B,MAAVD,EAAEC,MACzBD,EAAEE,iBACFxC,EAAiBH,EAAME,MAG3B0C,KAAK,SACL1F,SAAUgF,EACVW,SAAU,EAAC7B,SAAA,CAEVkB,GAAcjB,EAAAA,IAACpD,EAAmB,CAAC2D,KAAK,OACzCP,EAAAA,IAAC6B,EAAI,CACHC,QAAS/C,EAAMuC,SACfS,QAAQ,GACRC,SAAUjD,EAAMkD,SAASC,QACzBC,SAAUpD,EAAMqD,UAvBfrD,EAAME,SAZjBe,MAACpC,EAAoB,CAAAmC,SACnBC,EAAAA,IAACQ,EAAAA,WAAU,CAACC,YAAY,kCAAkCX,MAAM"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/organisms/AssetManager/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { styled } from '@mui/material/styles';\n\nimport Box from '@fd/components/atoms/Box';\nimport Tab from '@fd/components/atoms/Tab';\nimport Modal, { type ModalAction } from '@fd/components/molecules/Modal';\nimport Tabs from '@fd/components/molecules/Tabs';\n\nimport type { FileUploadState } from '../FileUpload';\nimport LibraryTabContent from './LibraryTabContent';\nimport type { Asset } from './types';\nimport UploadAssetContent from './UploadTabContent';\n\nconst StyledTabsContainer = styled(Box)(({ theme }) => ({\n marginBottom: theme.spacing(3),\n}));\n\n/**\n * Props for the AssetManager component.\n * Provides a modal interface for selecting images from a grid display.\n * It supports both single and multiple image selection modes.\n *\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n *\n * ```tsx\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n */\nexport interface AssetManagerProps {\n /** Whether the asset manager modal is open */\n open: boolean;\n /** Callback function when the modal is closed or cancelled */\n onClose: () => void;\n /** Callback function when assets are selected */\n onSelect?: (selectedAssets: Asset[]) => void;\n /**\n * Organization ID for fetching assets\n */\n orgId: string;\n /** Whether multiple assets can be selected. Defaults to false */\n multiSelect?: boolean;\n}\n\nconst AssetManager: React.FC<AssetManagerProps> = ({\n open,\n onClose,\n onSelect,\n orgId,\n multiSelect = false,\n}) => {\n // Use Map for O(1) lookup performance and direct access to Asset objects\n const [selectedAssetsMap, setSelectedAssetsMap] = useState<Map<string, Asset>>(new Map());\n const [selectedTab, setSelectedTab] = useState<string>('library');\n const [uploadedFiles, setUploadedFiles] = useState<FileUploadState[]>([]);\n\n // Reset selection when modal opens/closes\n useEffect(() => {\n if (!open) {\n setSelectedAssetsMap(new Map());\n setUploadedFiles([]);\n }\n }, [open]);\n\n const handleCancel = useCallback((): void => {\n setSelectedAssetsMap(new Map());\n onClose();\n }, [onClose]);\n\n const handleSelect = useCallback((): void => {\n const selectedAssets = Array.from(selectedAssetsMap.values());\n if (onSelect && selectedAssets.length > 0) {\n onSelect(selectedAssets);\n }\n setSelectedAssetsMap(new Map());\n onClose();\n }, [onSelect, selectedAssetsMap, onClose]);\n\n // TODO: translate titles\n const getTitle = (): string => {\n switch (selectedTab) {\n case 'library':\n return 'Select Images';\n default:\n return 'Upload Images';\n }\n };\n\n const handleAssetClick = useCallback(\n (asset: Asset): void => {\n setSelectedAssetsMap((prevMap) => {\n const isSelected = prevMap.has(asset.id);\n const newMap = new Map(prevMap);\n\n if (multiSelect) {\n if (isSelected) {\n newMap.delete(asset.id);\n } else {\n newMap.set(asset.id, asset);\n }\n } else {\n // Single select: replace selection or clear if clicking same asset\n if (isSelected) {\n newMap.clear();\n } else {\n newMap.clear();\n newMap.set(asset.id, asset);\n }\n }\n\n return newMap;\n });\n },\n [multiSelect],\n );\n\n const handleSaveAssets = useCallback((): void => {\n // TODO: call Upload asset api\n setUploadedFiles([]);\n setSelectedTab('library');\n }, []);\n\n const handleUpload = useCallback((files: File[]): void => {\n // Add files with uploading state\n const newFiles: FileUploadState[] = files.map((file) => ({\n file,\n }));\n setUploadedFiles((prev) => [...prev, ...newFiles]);\n }, []);\n\n const handleRemove = useCallback((fileToRemove: File): void => {\n setUploadedFiles((prev) => prev.filter((fileState) => fileState.file !== fileToRemove));\n }, []);\n\n // Tab-specific action button configurations\n // TODO: translate button labels\n const actionButtons = useMemo<ModalAction[]>(() => {\n // Common cancel button configuration\n const cancelButton: ModalAction = {\n label: 'Cancel',\n onClick: handleCancel,\n variant: 'secondary',\n tone: 'neutral',\n id: 'asset-manager-cancel',\n };\n\n const tabActions: Record<string, ModalAction[]> = {\n library: [\n cancelButton,\n {\n label: 'Select',\n onClick: handleSelect,\n variant: 'primary',\n disabled: selectedAssetsMap.size === 0,\n id: 'asset-manager-select',\n },\n ],\n upload: [\n cancelButton,\n {\n label: 'Save',\n onClick: handleSaveAssets,\n disabled: uploadedFiles.length === 0,\n variant: 'primary',\n id: 'asset-manager-upload',\n },\n ],\n };\n\n return tabActions[selectedTab] ?? (tabActions['library'] as ModalAction[]);\n }, [\n selectedTab,\n selectedAssetsMap.size,\n uploadedFiles.length,\n handleCancel,\n handleSelect,\n handleSaveAssets,\n ]);\n\n return (\n <Modal actions={actionButtons} onClose={handleCancel} open={open} size=\"large\" title={getTitle()}>\n <StyledTabsContainer>\n <Tabs\n fdKey=\"asset-manager-tabs\"\n onChange={(_, value: string) => setSelectedTab(value)}\n value={selectedTab}\n >\n <Tab label=\"Upload\" value=\"upload\" />\n <Tab label=\"Library\" value=\"library\" />\n </Tabs>\n </StyledTabsContainer>\n {selectedTab === 'library' ? (\n <LibraryTabContent\n enabled={open}\n onAssetClick={handleAssetClick}\n orgId={orgId}\n selectedAssets={selectedAssetsMap}\n />\n ) : (\n <UploadAssetContent files={uploadedFiles} onRemove={handleRemove} onUpload={handleUpload} />\n )}\n </Modal>\n );\n};\n\nexport default AssetManager;\n"],"names":["StyledTabsContainer","styled","Box","theme","marginBottom","spacing","open","onClose","onSelect","orgId","multiSelect","selectedAssetsMap","setSelectedAssetsMap","useState","Map","selectedTab","setSelectedTab","uploadedFiles","setUploadedFiles","useEffect","handleCancel","useCallback","handleSelect","selectedAssets","Array","from","values","length","handleAssetClick","asset","prevMap","isSelected","has","id","newMap","delete","set","clear","handleSaveAssets","handleUpload","files","newFiles","map","file","prev","handleRemove","fileToRemove","filter","fileState","actionButtons","useMemo","cancelButton","label","onClick","variant","tone","tabActions","library","disabled","size","upload","_jsxs","Modal","actions","title","children","_jsx","Tabs","fdKey","onChange","_","value","Tab","LibraryTabContent","enabled","onAssetClick","UploadAssetContent","onRemove","onUpload"],"mappings":"6VAcA,MAAMA,EAAsBC,EAAAA,OAAOC,EAAPD,EAAY,EAAGE,YAAO,CAChDC,aAAcD,EAAME,QAAQ,sBA4BoB,EAChDC,OACAC,UACAC,WACAC,QACAC,eAAc,MAGd,MAAOC,EAAmBC,GAAwBC,EAAAA,SAA6B,IAAIC,MAC5EC,EAAaC,GAAkBH,EAAAA,SAAiB,YAChDI,EAAeC,GAAoBL,EAAAA,SAA4B,IAGtEM,EAAAA,WAAU,KACHb,IACHM,EAAqB,IAAIE,KACzBI,EAAiB,OAElB,CAACZ,IAEJ,MAAMc,EAAeC,EAAAA,aAAY,KAC/BT,EAAqB,IAAIE,KACzBP,MACC,CAACA,IAEEe,EAAeD,EAAAA,aAAY,KAC/B,MAAME,EAAiBC,MAAMC,KAAKd,EAAkBe,UAChDlB,GAAYe,EAAeI,OAAS,GACtCnB,EAASe,GAEXX,EAAqB,IAAIE,KACzBP,MACC,CAACC,EAAUG,EAAmBJ,IAY3BqB,EAAmBP,eACtBQ,IACCjB,GAAsBkB,IACpB,MAAMC,EAAaD,EAAQE,IAAIH,EAAMI,IAC/BC,EAAS,IAAIpB,IAAIgB,GAkBvB,OAhBIpB,EACEqB,EACFG,EAAOC,OAAON,EAAMI,IAEpBC,EAAOE,IAAIP,EAAMI,GAAIJ,GAInBE,EACFG,EAAOG,SAEPH,EAAOG,QACPH,EAAOE,IAAIP,EAAMI,GAAIJ,IAIlBK,OAGX,CAACxB,IAGG4B,EAAmBjB,EAAAA,aAAY,KAEnCH,EAAiB,IACjBF,EAAe,aACd,IAEGuB,EAAelB,eAAamB,IAEhC,MAAMC,EAA8BD,EAAME,KAAKC,IAAI,CACjDA,WAEFzB,GAAkB0B,GAAS,IAAIA,KAASH,OACvC,IAEGI,EAAexB,eAAayB,IAChC5B,GAAkB0B,GAASA,EAAKG,QAAQC,GAAcA,EAAUL,OAASG,QACxE,IAIGG,EAAgBC,EAAAA,SAAuB,KAE3C,MAAMC,EAA4B,CAChCC,MAAO,SACPC,QAASjC,EACTkC,QAAS,YACTC,KAAM,UACNtB,GAAI,wBAGAuB,EAA4C,CAChDC,QAAS,CACPN,EACA,CACEC,MAAO,SACPC,QAAS/B,EACTgC,QAAS,UACTI,SAAqC,IAA3B/C,EAAkBgD,KAC5B1B,GAAI,yBAGR2B,OAAQ,CACNT,EACA,CACEC,MAAO,OACPC,QAASf,EACToB,SAAmC,IAAzBzC,EAAcU,OACxB2B,QAAS,UACTrB,GAAI,0BAKV,OAAOuB,EAAWzC,IAAiByC,EAAoB,UACtD,CACDzC,EACAJ,EAAkBgD,KAClB1C,EAAcU,OACdP,EACAE,EACAgB,IAGF,OACEuB,EAAAA,KAACC,EAAK,CAACC,QAASd,EAAe1C,QAASa,EAAcd,KAAMA,EAAMqD,KAAK,QAAQK,MAnGxE,YADCjD,EAEG,gBAEA,gBAgGqFkD,SAAA,CAC9FC,EAAAA,IAAClE,EAAmB,CAAAiE,SAClBJ,EAAAA,KAACM,EAAI,CACHC,MAAM,qBACNC,SAAU,CAACC,EAAGC,IAAkBvD,EAAeuD,GAC/CA,MAAOxD,EAAWkD,SAAA,CAElBC,EAAAA,IAACM,EAAG,CAACpB,MAAM,SAASmB,MAAM,WAC1BL,MAACM,EAAG,CAACpB,MAAM,UAAUmB,MAAM,iBAGd,YAAhBxD,EACCmD,MAACO,EAAiB,CAChBC,QAASpE,EACTqE,aAAc/C,EACdnB,MAAOA,EACPc,eAAgBZ,IAGlBuD,EAAAA,IAACU,EAAkB,CAACpC,MAAOvB,EAAe4D,SAAUhC,EAAciC,SAAUvC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as e,jsx as
|
|
1
|
+
import{jsxs as e,jsx as a}from"react/jsx-runtime";import{useState as r,useEffect as l,useCallback as t,useMemo as i}from"react";import{styled as o}from"@mui/material/styles";import n from"@mui/material/Box";import s from"@mui/material/Tab";import m from"../../molecules/Modal/index.js";import d from"../../molecules/Tabs/index.js";import c from"./LibraryTabContent/index.js";import p from"./UploadTabContent/index.js";const b=o(n)((({theme:e})=>({marginBottom:e.spacing(3)}))),u=({open:o,onClose:n,onSelect:u,orgId:f,multiSelect:g=!1})=>{const[y,C]=r(new Map),[h,v]=r("library"),[x,M]=r([]);l((()=>{o||(C(new Map),M([]))}),[o]);const j=t((()=>{C(new Map),n()}),[n]),w=t((()=>{const e=Array.from(y.values());u&&e.length>0&&u(e),C(new Map),n()}),[u,y,n]),S=t((e=>{C((a=>{const r=a.has(e.id),l=new Map(a);return g?r?l.delete(e.id):l.set(e.id,e):r?l.clear():(l.clear(),l.set(e.id,e)),l}))}),[g]),k=t((()=>{M([]),v("library")}),[]),I=t((e=>{const a=e.map((e=>({file:e})));M((e=>[...e,...a]))}),[]),T=t((e=>{M((a=>a.filter((a=>a.file!==e))))}),[]),U=i((()=>{const e={label:"Cancel",onClick:j,variant:"secondary",tone:"neutral",id:"asset-manager-cancel"},a={library:[e,{label:"Select",onClick:w,variant:"primary",disabled:0===y.size,id:"asset-manager-select"}],upload:[e,{label:"Save",onClick:k,disabled:0===x.length,variant:"primary",id:"asset-manager-upload"}]};return a[h]??a.library}),[h,y.size,x.length,j,w,k]);return e(m,{actions:U,onClose:j,open:o,size:"large",title:"library"===h?"Select Images":"Upload Images",children:[a(b,{children:e(d,{fdKey:"asset-manager-tabs",onChange:(e,a)=>v(a),value:h,children:[a(s,{label:"Upload",value:"upload"}),a(s,{label:"Library",value:"library"})]})}),"library"===h?a(c,{enabled:o,onAssetClick:S,orgId:f,selectedAssets:y}):a(p,{files:x,onRemove:T,onUpload:I})]})};export{u as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/AssetManager/index.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react';\n\nimport { styled } from '@mui/material/styles';\n\nimport Box from '@fd/components/atoms/Box';\nimport Card from '@fd/components/atoms/Card';\nimport CircularProgress from '@fd/components/atoms/CircularProgress';\nimport Grid from '@fd/components/atoms/Grid';\nimport Tab from '@fd/components/atoms/Tab';\nimport EmptyState from '@fd/components/molecules/EmptyState';\nimport Modal from '@fd/components/molecules/Modal';\nimport Tabs from '@fd/components/molecules/Tabs';\nimport CheckmarkCircleSolidIcon from '@fd/icons/CheckmarkCircleSolid';\n\nimport { useGetAssets } from './hooks/useAssets';\nimport type { Asset } from './types';\n\nconst StyledTabsContainer = styled(Box)(({ theme }) => ({\n marginBottom: theme.spacing(3),\n}));\n\nconst StyledCardWrapper = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'selected',\n})<{ selected?: boolean }>(({ theme, selected }) => ({\n width: '100%',\n cursor: 'pointer',\n position: 'relative',\n '& .MuiCard-root': {\n // Always use 2px border to prevent layout shift\n borderWidth: '2px',\n borderColor: selected ? theme.palette.semantic.stroke['stroke-selected'] : 'transparent',\n // Use box-shadow to create the visual 1px border when not selected\n // This prevents layout shift while maintaining the visual appearance\n boxShadow: selected ? 'none' : `inset 0 0 0 1px ${theme.palette.semantic.stroke['stroke-weak']}`,\n },\n '&:hover': {\n opacity: 0.9,\n },\n '&:focus-visible .MuiCard-root': {\n borderColor: theme.palette.semantic.stroke['stroke-selected'],\n boxShadow: 'none',\n },\n}));\n\nconst StyledCheckmarkIcon = styled(CheckmarkCircleSolidIcon)(({ theme }) => ({\n position: 'absolute',\n top: theme.spacing(2),\n left: theme.spacing(2),\n zIndex: 1,\n color: theme.palette.semantic.icon['icon-primary'],\n '& circle': {\n fill: theme.palette.common.white,\n },\n}));\n\n/**\n * Props for the AssetManager component.\n * Provides a modal interface for selecting images from a grid display.\n * It supports both single and multiple image selection modes.\n *\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n *\n * ```tsx\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n */\nexport interface AssetManagerProps {\n /** Whether the asset manager modal is open */\n open: boolean;\n /** Callback function when the modal is closed or cancelled */\n onClose: () => void;\n /** Callback function when assets are selected */\n onSelect?: (selectedAssets: Asset[]) => void;\n /**\n * Organization ID for fetching assets\n */\n orgId: string;\n /** Whether multiple assets can be selected. Defaults to false */\n multiSelect?: boolean;\n}\n\nconst StyledLoadingContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n minHeight: '200px',\n padding: theme.spacing(4),\n}));\n\nconst StyledErrorContainer = styled(Box)(({ theme }) => ({\n padding: theme.spacing(4),\n}));\n\nconst AssetManager: React.FC<AssetManagerProps> = ({\n open,\n onClose,\n onSelect,\n orgId,\n multiSelect = false,\n}) => {\n const [selectedAssetIds, setSelectedAssetIds] = useState<string[]>([]);\n\n // Fetch assets from API - service handles everything\n const { data: assets, isLoading, error } = useGetAssets(orgId, open);\n\n // Reset selection when modal opens/closes\n useEffect(() => {\n if (!open) {\n setSelectedAssetIds([]);\n }\n }, [open]);\n\n const handleCancel = (): void => {\n setSelectedAssetIds([]);\n onClose();\n };\n\n const handleSelect = (): void => {\n if (onSelect && assets) {\n const selectedAssets = assets.filter((asset: Asset) => selectedAssetIds.includes(asset.id));\n onSelect(selectedAssets);\n }\n setSelectedAssetIds([]);\n onClose();\n };\n\n const handleAssetClick = (assetId: string): void => {\n setSelectedAssetIds((prev) => {\n if (multiSelect) {\n if (prev.includes(assetId)) {\n return prev.filter((id) => id !== assetId);\n }\n return [...prev, assetId];\n } else {\n if (prev.includes(assetId)) {\n return [];\n }\n return [assetId];\n }\n });\n };\n\n const getActions = () => {\n return [\n {\n label: 'Cancel',\n onClick: handleCancel,\n variant: 'secondary' as const,\n tone: 'neutral' as const,\n id: 'asset-manager-cancel',\n },\n {\n label: 'Select',\n onClick: handleSelect,\n variant: 'primary' as const,\n disabled: selectedAssetIds.length === 0,\n id: 'asset-manager-select',\n },\n ];\n };\n\n const renderBrowseTab = (): React.ReactElement => {\n if (isLoading) {\n return (\n <StyledLoadingContainer>\n <CircularProgress size=\"large\" />\n </StyledLoadingContainer>\n );\n }\n\n if (error) {\n return (\n <StyledErrorContainer>\n <EmptyState\n description=\"Failed to load assets. Please try again later.\"\n title=\"Error loading assets\"\n />\n </StyledErrorContainer>\n );\n }\n\n if (!assets || assets.length === 0) {\n return (\n <StyledErrorContainer>\n <EmptyState description=\"No assets available to display.\" title=\"No assets found\" />\n </StyledErrorContainer>\n );\n }\n\n return (\n <Grid container component=\"ul\" spacing={1} sx={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {assets.map((asset: Asset) => {\n const isSelected = selectedAssetIds.includes(asset.id);\n return (\n <Grid\n key={asset.id}\n aria-selected={isSelected}\n component=\"li\"\n size={{ widescreen: 3, desktop: 3, mobile: 6, tablet: 4 }}\n >\n <StyledCardWrapper\n aria-label={'Select ' + asset.fileName} // TODO: translate this text when translate provider is added\n onClick={() => handleAssetClick(asset.id)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleAssetClick(asset.id);\n }\n }}\n role=\"button\"\n selected={isSelected}\n tabIndex={0}\n >\n {isSelected && <StyledCheckmarkIcon size=\"lg\" />}\n <Card\n content={asset.fileName}\n heading=\"\"\n imageAlt={asset.metadata.altText}\n imageSrc={asset.url}\n />\n </StyledCardWrapper>\n </Grid>\n );\n })}\n </Grid>\n );\n };\n\n return (\n // TODO: replace this with a new modal component when available\n <Modal actions={getActions()} onClose={handleCancel} open={open} title=\"Select Images\">\n <StyledTabsContainer>\n {/* TODO: replace this with a new tabs component when available */}\n <Tabs fdKey=\"asset-manager-tabs\" onChange={() => {}} value={1}>\n <Tab label=\"Upload\" />\n <Tab label=\"Library\" />\n </Tabs>\n </StyledTabsContainer>\n {renderBrowseTab()}\n </Modal>\n );\n};\n\nexport default AssetManager;\n"],"names":["StyledTabsContainer","styled","Box","theme","marginBottom","spacing","StyledCardWrapper","shouldForwardProp","prop","selected","width","cursor","position","borderWidth","borderColor","palette","semantic","stroke","boxShadow","opacity","StyledCheckmarkIcon","CheckmarkCircleSolidIcon","top","left","zIndex","color","icon","fill","common","white","StyledLoadingContainer","display","justifyContent","alignItems","minHeight","padding","StyledErrorContainer","AssetManager","open","onClose","onSelect","orgId","multiSelect","selectedAssetIds","setSelectedAssetIds","useState","data","assets","isLoading","error","useGetAssets","useEffect","handleCancel","handleAssetClick","assetId","prev","includes","filter","id","_jsxs","Modal","actions","label","onClick","variant","tone","selectedAssets","asset","disabled","length","title","children","_jsx","Tabs","fdKey","onChange","value","Tab","CircularProgress","size","EmptyState","description","Grid","container","component","sx","listStyle","margin","map","isSelected","widescreen","desktop","mobile","tablet","fileName","onKeyDown","e","key","preventDefault","role","tabIndex","Card","content","heading","imageAlt","metadata","altText","imageSrc","url"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/AssetManager/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport { styled } from '@mui/material/styles';\n\nimport Box from '@fd/components/atoms/Box';\nimport Tab from '@fd/components/atoms/Tab';\nimport Modal, { type ModalAction } from '@fd/components/molecules/Modal';\nimport Tabs from '@fd/components/molecules/Tabs';\n\nimport type { FileUploadState } from '../FileUpload';\nimport LibraryTabContent from './LibraryTabContent';\nimport type { Asset } from './types';\nimport UploadAssetContent from './UploadTabContent';\n\nconst StyledTabsContainer = styled(Box)(({ theme }) => ({\n marginBottom: theme.spacing(3),\n}));\n\n/**\n * Props for the AssetManager component.\n * Provides a modal interface for selecting images from a grid display.\n * It supports both single and multiple image selection modes.\n *\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n *\n * ```tsx\n * import AssetManager from '@flipdish/portal-library/components/organisms/AssetManager';\n */\nexport interface AssetManagerProps {\n /** Whether the asset manager modal is open */\n open: boolean;\n /** Callback function when the modal is closed or cancelled */\n onClose: () => void;\n /** Callback function when assets are selected */\n onSelect?: (selectedAssets: Asset[]) => void;\n /**\n * Organization ID for fetching assets\n */\n orgId: string;\n /** Whether multiple assets can be selected. Defaults to false */\n multiSelect?: boolean;\n}\n\nconst AssetManager: React.FC<AssetManagerProps> = ({\n open,\n onClose,\n onSelect,\n orgId,\n multiSelect = false,\n}) => {\n // Use Map for O(1) lookup performance and direct access to Asset objects\n const [selectedAssetsMap, setSelectedAssetsMap] = useState<Map<string, Asset>>(new Map());\n const [selectedTab, setSelectedTab] = useState<string>('library');\n const [uploadedFiles, setUploadedFiles] = useState<FileUploadState[]>([]);\n\n // Reset selection when modal opens/closes\n useEffect(() => {\n if (!open) {\n setSelectedAssetsMap(new Map());\n setUploadedFiles([]);\n }\n }, [open]);\n\n const handleCancel = useCallback((): void => {\n setSelectedAssetsMap(new Map());\n onClose();\n }, [onClose]);\n\n const handleSelect = useCallback((): void => {\n const selectedAssets = Array.from(selectedAssetsMap.values());\n if (onSelect && selectedAssets.length > 0) {\n onSelect(selectedAssets);\n }\n setSelectedAssetsMap(new Map());\n onClose();\n }, [onSelect, selectedAssetsMap, onClose]);\n\n // TODO: translate titles\n const getTitle = (): string => {\n switch (selectedTab) {\n case 'library':\n return 'Select Images';\n default:\n return 'Upload Images';\n }\n };\n\n const handleAssetClick = useCallback(\n (asset: Asset): void => {\n setSelectedAssetsMap((prevMap) => {\n const isSelected = prevMap.has(asset.id);\n const newMap = new Map(prevMap);\n\n if (multiSelect) {\n if (isSelected) {\n newMap.delete(asset.id);\n } else {\n newMap.set(asset.id, asset);\n }\n } else {\n // Single select: replace selection or clear if clicking same asset\n if (isSelected) {\n newMap.clear();\n } else {\n newMap.clear();\n newMap.set(asset.id, asset);\n }\n }\n\n return newMap;\n });\n },\n [multiSelect],\n );\n\n const handleSaveAssets = useCallback((): void => {\n // TODO: call Upload asset api\n setUploadedFiles([]);\n setSelectedTab('library');\n }, []);\n\n const handleUpload = useCallback((files: File[]): void => {\n // Add files with uploading state\n const newFiles: FileUploadState[] = files.map((file) => ({\n file,\n }));\n setUploadedFiles((prev) => [...prev, ...newFiles]);\n }, []);\n\n const handleRemove = useCallback((fileToRemove: File): void => {\n setUploadedFiles((prev) => prev.filter((fileState) => fileState.file !== fileToRemove));\n }, []);\n\n // Tab-specific action button configurations\n // TODO: translate button labels\n const actionButtons = useMemo<ModalAction[]>(() => {\n // Common cancel button configuration\n const cancelButton: ModalAction = {\n label: 'Cancel',\n onClick: handleCancel,\n variant: 'secondary',\n tone: 'neutral',\n id: 'asset-manager-cancel',\n };\n\n const tabActions: Record<string, ModalAction[]> = {\n library: [\n cancelButton,\n {\n label: 'Select',\n onClick: handleSelect,\n variant: 'primary',\n disabled: selectedAssetsMap.size === 0,\n id: 'asset-manager-select',\n },\n ],\n upload: [\n cancelButton,\n {\n label: 'Save',\n onClick: handleSaveAssets,\n disabled: uploadedFiles.length === 0,\n variant: 'primary',\n id: 'asset-manager-upload',\n },\n ],\n };\n\n return tabActions[selectedTab] ?? (tabActions['library'] as ModalAction[]);\n }, [\n selectedTab,\n selectedAssetsMap.size,\n uploadedFiles.length,\n handleCancel,\n handleSelect,\n handleSaveAssets,\n ]);\n\n return (\n <Modal actions={actionButtons} onClose={handleCancel} open={open} size=\"large\" title={getTitle()}>\n <StyledTabsContainer>\n <Tabs\n fdKey=\"asset-manager-tabs\"\n onChange={(_, value: string) => setSelectedTab(value)}\n value={selectedTab}\n >\n <Tab label=\"Upload\" value=\"upload\" />\n <Tab label=\"Library\" value=\"library\" />\n </Tabs>\n </StyledTabsContainer>\n {selectedTab === 'library' ? (\n <LibraryTabContent\n enabled={open}\n onAssetClick={handleAssetClick}\n orgId={orgId}\n selectedAssets={selectedAssetsMap}\n />\n ) : (\n <UploadAssetContent files={uploadedFiles} onRemove={handleRemove} onUpload={handleUpload} />\n )}\n </Modal>\n );\n};\n\nexport default AssetManager;\n"],"names":["StyledTabsContainer","styled","Box","theme","marginBottom","spacing","AssetManager","open","onClose","onSelect","orgId","multiSelect","selectedAssetsMap","setSelectedAssetsMap","useState","Map","selectedTab","setSelectedTab","uploadedFiles","setUploadedFiles","useEffect","handleCancel","useCallback","handleSelect","selectedAssets","Array","from","values","length","handleAssetClick","asset","prevMap","isSelected","has","id","newMap","delete","set","clear","handleSaveAssets","handleUpload","files","newFiles","map","file","prev","handleRemove","fileToRemove","filter","fileState","actionButtons","useMemo","cancelButton","label","onClick","variant","tone","tabActions","library","disabled","size","upload","_jsxs","Modal","actions","title","children","_jsx","Tabs","fdKey","onChange","_","value","Tab","LibraryTabContent","enabled","onAssetClick","UploadAssetContent","onRemove","onUpload"],"mappings":"kaAcA,MAAMA,EAAsBC,EAAOC,EAAPD,EAAY,EAAGE,YAAO,CAChDC,aAAcD,EAAME,QAAQ,OA4BxBC,EAA4C,EAChDC,OACAC,UACAC,WACAC,QACAC,eAAc,MAGd,MAAOC,EAAmBC,GAAwBC,EAA6B,IAAIC,MAC5EC,EAAaC,GAAkBH,EAAiB,YAChDI,EAAeC,GAAoBL,EAA4B,IAGtEM,GAAU,KACHb,IACHM,EAAqB,IAAIE,KACzBI,EAAiB,OAElB,CAACZ,IAEJ,MAAMc,EAAeC,GAAY,KAC/BT,EAAqB,IAAIE,KACzBP,MACC,CAACA,IAEEe,EAAeD,GAAY,KAC/B,MAAME,EAAiBC,MAAMC,KAAKd,EAAkBe,UAChDlB,GAAYe,EAAeI,OAAS,GACtCnB,EAASe,GAEXX,EAAqB,IAAIE,KACzBP,MACC,CAACC,EAAUG,EAAmBJ,IAY3BqB,EAAmBP,GACtBQ,IACCjB,GAAsBkB,IACpB,MAAMC,EAAaD,EAAQE,IAAIH,EAAMI,IAC/BC,EAAS,IAAIpB,IAAIgB,GAkBvB,OAhBIpB,EACEqB,EACFG,EAAOC,OAAON,EAAMI,IAEpBC,EAAOE,IAAIP,EAAMI,GAAIJ,GAInBE,EACFG,EAAOG,SAEPH,EAAOG,QACPH,EAAOE,IAAIP,EAAMI,GAAIJ,IAIlBK,OAGX,CAACxB,IAGG4B,EAAmBjB,GAAY,KAEnCH,EAAiB,IACjBF,EAAe,aACd,IAEGuB,EAAelB,GAAamB,IAEhC,MAAMC,EAA8BD,EAAME,KAAKC,IAAI,CACjDA,WAEFzB,GAAkB0B,GAAS,IAAIA,KAASH,OACvC,IAEGI,EAAexB,GAAayB,IAChC5B,GAAkB0B,GAASA,EAAKG,QAAQC,GAAcA,EAAUL,OAASG,QACxE,IAIGG,EAAgBC,GAAuB,KAE3C,MAAMC,EAA4B,CAChCC,MAAO,SACPC,QAASjC,EACTkC,QAAS,YACTC,KAAM,UACNtB,GAAI,wBAGAuB,EAA4C,CAChDC,QAAS,CACPN,EACA,CACEC,MAAO,SACPC,QAAS/B,EACTgC,QAAS,UACTI,SAAqC,IAA3B/C,EAAkBgD,KAC5B1B,GAAI,yBAGR2B,OAAQ,CACNT,EACA,CACEC,MAAO,OACPC,QAASf,EACToB,SAAmC,IAAzBzC,EAAcU,OACxB2B,QAAS,UACTrB,GAAI,0BAKV,OAAOuB,EAAWzC,IAAiByC,EAAoB,UACtD,CACDzC,EACAJ,EAAkBgD,KAClB1C,EAAcU,OACdP,EACAE,EACAgB,IAGF,OACEuB,EAACC,EAAK,CAACC,QAASd,EAAe1C,QAASa,EAAcd,KAAMA,EAAMqD,KAAK,QAAQK,MAnGxE,YADCjD,EAEG,gBAEA,gBAgGqFkD,SAAA,CAC9FC,EAACnE,EAAmB,CAAAkE,SAClBJ,EAACM,EAAI,CACHC,MAAM,qBACNC,SAAU,CAACC,EAAGC,IAAkBvD,EAAeuD,GAC/CA,MAAOxD,EAAWkD,SAAA,CAElBC,EAACM,EAAG,CAACpB,MAAM,SAASmB,MAAM,WAC1BL,EAACM,EAAG,CAACpB,MAAM,UAAUmB,MAAM,iBAGd,YAAhBxD,EACCmD,EAACO,EAAiB,CAChBC,QAASpE,EACTqE,aAAc/C,EACdnB,MAAOA,EACPc,eAAgBZ,IAGlBuD,EAACU,EAAkB,CAACpC,MAAOvB,EAAe4D,SAAUhC,EAAciC,SAAUvC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("react/jsx-runtime")
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime");require("react");var i=require("@mui/material/Stack/Stack"),l=require("@mui/material/styles/useTheme"),a=require("@mui/material/Typography"),t=require("./components/FileDropZone.cjs.js"),s=require("./components/FileItem.cjs.js");module.exports=n=>{const o=l(),{label:r="Upload File",files:d,allowedFileTypes:m,maxFiles:x,maxFileSize:p,onUpload:c,onRemove:u,multiple:F=!0,dragActiveText:T,dragInactiveText:g,browseButtonText:v,invalidFileTypesText:j="File type is not allowed. Allowed types: {allowedFileTypes}",invalidFileSizeText:y="File size is too large. Maximum size: {maxFileSize}",invalidFileCountText:f="Too many files selected. Maximum allowed: {maxFiles}"}=n,h=e=>{u(e)};return e.jsxs(e.Fragment,{children:[e.jsx(a,{paddingBottom:o.spacing(1),variant:"b1Weak",children:r}),e.jsxs(i,{direction:"column",flex:1,gap:o.spacing(1),children:[e.jsx(t,{allowedFileTypes:m,browseButtonText:v,dragActiveText:T,dragInactiveText:g,handleUpload:e=>{c(e)},invalidFileCountText:f,invalidFileSizeText:y,invalidFileTypesText:j,maxFiles:x,maxFileSize:p,multiple:F}),d.length>0&&e.jsx(i,{direction:"column",gap:o.spacing(1.5),children:d.map((i=>e.jsx(s,{file:i.file,isUploading:i.isUploading,onRemove:h},`${i.file.name}-${i.file.size}-${i.file.lastModified}`)))})]})]})};
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/organisms/FileUpload/index.tsx"],"sourcesContent":["import React
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../../src/components/organisms/FileUpload/index.tsx"],"sourcesContent":["import React from 'react';\n\nimport Stack from '@mui/material/Stack/Stack';\nimport useTheme from '@mui/material/styles/useTheme';\n\nimport Typography from '@fd/components/atoms/Typography';\n\nimport FileDropZone from './components/FileDropZone';\nimport FileItem from './components/FileItem';\n\nexport interface FileUploadState {\n file: File;\n isUploading?: boolean;\n}\n\nexport interface FileUploadProps {\n /**\n * Label text displayed above the file upload area.\n * @default 'Upload File'\n */\n label?: string;\n\n /**\n * Array of file upload states (file object with optional isUploading flag).\n */\n files: FileUploadState[];\n\n /**\n * Array of allowed file extensions (without dots).\n * Example: ['jpg', 'png', 'pdf']\n */\n allowedFileTypes: string[];\n\n /**\n * Whether multiple files can be selected at once.\n * @default true\n */\n multiple?: boolean;\n\n /**\n * Maximum number of files that can be uploaded.\n */\n maxFiles: number;\n\n /**\n * Maximum file size allowed in bytes.\n * Example: 10 * 1024 * 1024 for 10MB\n */\n maxFileSize: number;\n\n /**\n * Callback fired when files are uploaded.\n */\n onUpload: (files: File[]) => void;\n\n /**\n * Callback fired when a file is removed.\n */\n onRemove: (file: File) => void;\n\n /**\n * Text displayed when files are being dragged over the drop zone.\n * @default 'Drop files here'\n */\n dragActiveText?: string;\n\n /**\n * Text displayed when no files are being dragged (idle state).\n * @default 'Drag and drop files here'\n */\n dragInactiveText?: string;\n\n /**\n * Text displayed on the browse/upload button.\n * @default 'Browse files'\n */\n browseButtonText?: string;\n\n /**\n * Text displayed when a file type is not allowed.\n * @default 'File type is not allowed. Allowed types: {allowedFileTypes}'\n */\n invalidFileTypesText?: string;\n\n /**\n * Text displayed when a file size is too large.\n * @default 'File size is too large. Maximum size: {maxFileSize}'\n */\n invalidFileSizeText?: string;\n\n /**\n * Text displayed when too many files are selected.\n * @default 'Too many files selected. Maximum allowed: {maxFiles}'\n */\n invalidFileCountText?: string;\n}\n\nconst FileUpload: React.FC<FileUploadProps> = (props) => {\n const theme = useTheme();\n const {\n label = 'Upload File',\n files,\n allowedFileTypes,\n maxFiles,\n maxFileSize,\n onUpload,\n onRemove,\n multiple = true,\n dragActiveText,\n dragInactiveText,\n browseButtonText,\n invalidFileTypesText = 'File type is not allowed. Allowed types: {allowedFileTypes}',\n invalidFileSizeText = 'File size is too large. Maximum size: {maxFileSize}',\n invalidFileCountText = 'Too many files selected. Maximum allowed: {maxFiles}',\n } = props;\n\n const handleUpload = (newFiles: File[]): void => {\n // Notify parent - parent will manage state\n onUpload(newFiles);\n };\n\n const handleRemoveFile = (fileToRemove: File): void => {\n // Notify parent - parent will manage state\n onRemove(fileToRemove);\n };\n\n return (\n <>\n <Typography paddingBottom={theme.spacing(1)} variant=\"b1Weak\">\n {label}\n </Typography>\n <Stack direction=\"column\" flex={1} gap={theme.spacing(1)}>\n <FileDropZone\n allowedFileTypes={allowedFileTypes}\n browseButtonText={browseButtonText}\n dragActiveText={dragActiveText}\n dragInactiveText={dragInactiveText}\n handleUpload={handleUpload}\n invalidFileCountText={invalidFileCountText}\n invalidFileSizeText={invalidFileSizeText}\n invalidFileTypesText={invalidFileTypesText}\n maxFiles={maxFiles}\n maxFileSize={maxFileSize}\n multiple={multiple}\n />\n\n {files.length > 0 && (\n <Stack direction=\"column\" gap={theme.spacing(1.5)}>\n {files.map((fileState) => (\n <FileItem\n key={`${fileState.file.name}-${fileState.file.size}-${fileState.file.lastModified}`}\n file={fileState.file}\n isUploading={fileState.isUploading}\n onRemove={handleRemoveFile}\n />\n ))}\n </Stack>\n )}\n </Stack>\n </>\n );\n};\n\nexport default FileUpload;\n"],"names":["props","theme","useTheme","label","files","allowedFileTypes","maxFiles","maxFileSize","onUpload","onRemove","multiple","dragActiveText","dragInactiveText","browseButtonText","invalidFileTypesText","invalidFileSizeText","invalidFileCountText","handleRemoveFile","fileToRemove","_jsxs","_Fragment","children","_jsx","Typography","paddingBottom","spacing","variant","Stack","direction","flex","gap","FileDropZone","handleUpload","newFiles","length","map","fileState","FileItem","file","isUploading","name","size","lastModified"],"mappings":"oSAiG+CA,IAC7C,MAAMC,EAAQC,KACRC,MACJA,EAAQ,cAAaC,MACrBA,EAAKC,iBACLA,EAAgBC,SAChBA,EAAQC,YACRA,EAAWC,SACXA,EAAQC,SACRA,EAAQC,SACRA,GAAW,EAAIC,eACfA,EAAcC,iBACdA,EAAgBC,iBAChBA,EAAgBC,qBAChBA,EAAuB,8DAA6DC,oBACpFA,EAAsB,sDAAqDC,qBAC3EA,EAAuB,wDACrBhB,EAOEiB,EAAoBC,IAExBT,EAASS,IAGX,OACEC,OAAAC,EAAAA,SAAA,CAAAC,SAAA,CACEC,EAAAA,IAACC,EAAU,CAACC,cAAevB,EAAMwB,QAAQ,GAAIC,QAAQ,SAAQL,SAC1DlB,IAEHgB,EAAAA,KAACQ,EAAK,CAACC,UAAU,SAASC,KAAM,EAAGC,IAAK7B,EAAMwB,QAAQ,GAAEJ,SAAA,CACtDC,MAACS,GACC1B,iBAAkBA,EAClBQ,iBAAkBA,EAClBF,eAAgBA,EAChBC,iBAAkBA,EAClBoB,aArBcC,IAEpBzB,EAASyB,IAoBHjB,qBAAsBA,EACtBD,oBAAqBA,EACrBD,qBAAsBA,EACtBR,SAAUA,EACVC,YAAaA,EACbG,SAAUA,IAGXN,EAAM8B,OAAS,GACdZ,MAACK,EAAK,CAACC,UAAU,SAASE,IAAK7B,EAAMwB,QAAQ,KAAIJ,SAC9CjB,EAAM+B,KAAKC,GACVd,EAAAA,IAACe,GAECC,KAAMF,EAAUE,KAChBC,YAAaH,EAAUG,YACvB9B,SAAUQ,GAHL,GAAGmB,EAAUE,KAAKE,QAAQJ,EAAUE,KAAKG,QAAQL,EAAUE,KAAKI"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsxs as e,Fragment as i,jsx as l}from"react/jsx-runtime";import
|
|
1
|
+
import{jsxs as e,Fragment as i,jsx as l}from"react/jsx-runtime";import"react";import t from"@mui/material/Stack/Stack";import a from"@mui/material/styles/useTheme";import o from"@mui/material/Typography";import m from"./components/FileDropZone.js";import n from"./components/FileItem.js";const r=r=>{const s=a(),{label:d="Upload File",files:p,allowedFileTypes:c,maxFiles:x,maxFileSize:F,onUpload:T,onRemove:u,multiple:f=!0,dragActiveText:g,dragInactiveText:v,browseButtonText:y,invalidFileTypesText:h="File type is not allowed. Allowed types: {allowedFileTypes}",invalidFileSizeText:w="File size is too large. Maximum size: {maxFileSize}",invalidFileCountText:z="Too many files selected. Maximum allowed: {maxFiles}"}=r,S=e=>{u(e)};return e(i,{children:[l(o,{paddingBottom:s.spacing(1),variant:"b1Weak",children:d}),e(t,{direction:"column",flex:1,gap:s.spacing(1),children:[l(m,{allowedFileTypes:c,browseButtonText:y,dragActiveText:g,dragInactiveText:v,handleUpload:e=>{T(e)},invalidFileCountText:z,invalidFileSizeText:w,invalidFileTypesText:h,maxFiles:x,maxFileSize:F,multiple:f}),p.length>0&&l(t,{direction:"column",gap:s.spacing(1.5),children:p.map((e=>l(n,{file:e.file,isUploading:e.isUploading,onRemove:S},`${e.file.name}-${e.file.size}-${e.file.lastModified}`)))})]})]})};export{r as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/FileUpload/index.tsx"],"sourcesContent":["import React
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/FileUpload/index.tsx"],"sourcesContent":["import React from 'react';\n\nimport Stack from '@mui/material/Stack/Stack';\nimport useTheme from '@mui/material/styles/useTheme';\n\nimport Typography from '@fd/components/atoms/Typography';\n\nimport FileDropZone from './components/FileDropZone';\nimport FileItem from './components/FileItem';\n\nexport interface FileUploadState {\n file: File;\n isUploading?: boolean;\n}\n\nexport interface FileUploadProps {\n /**\n * Label text displayed above the file upload area.\n * @default 'Upload File'\n */\n label?: string;\n\n /**\n * Array of file upload states (file object with optional isUploading flag).\n */\n files: FileUploadState[];\n\n /**\n * Array of allowed file extensions (without dots).\n * Example: ['jpg', 'png', 'pdf']\n */\n allowedFileTypes: string[];\n\n /**\n * Whether multiple files can be selected at once.\n * @default true\n */\n multiple?: boolean;\n\n /**\n * Maximum number of files that can be uploaded.\n */\n maxFiles: number;\n\n /**\n * Maximum file size allowed in bytes.\n * Example: 10 * 1024 * 1024 for 10MB\n */\n maxFileSize: number;\n\n /**\n * Callback fired when files are uploaded.\n */\n onUpload: (files: File[]) => void;\n\n /**\n * Callback fired when a file is removed.\n */\n onRemove: (file: File) => void;\n\n /**\n * Text displayed when files are being dragged over the drop zone.\n * @default 'Drop files here'\n */\n dragActiveText?: string;\n\n /**\n * Text displayed when no files are being dragged (idle state).\n * @default 'Drag and drop files here'\n */\n dragInactiveText?: string;\n\n /**\n * Text displayed on the browse/upload button.\n * @default 'Browse files'\n */\n browseButtonText?: string;\n\n /**\n * Text displayed when a file type is not allowed.\n * @default 'File type is not allowed. Allowed types: {allowedFileTypes}'\n */\n invalidFileTypesText?: string;\n\n /**\n * Text displayed when a file size is too large.\n * @default 'File size is too large. Maximum size: {maxFileSize}'\n */\n invalidFileSizeText?: string;\n\n /**\n * Text displayed when too many files are selected.\n * @default 'Too many files selected. Maximum allowed: {maxFiles}'\n */\n invalidFileCountText?: string;\n}\n\nconst FileUpload: React.FC<FileUploadProps> = (props) => {\n const theme = useTheme();\n const {\n label = 'Upload File',\n files,\n allowedFileTypes,\n maxFiles,\n maxFileSize,\n onUpload,\n onRemove,\n multiple = true,\n dragActiveText,\n dragInactiveText,\n browseButtonText,\n invalidFileTypesText = 'File type is not allowed. Allowed types: {allowedFileTypes}',\n invalidFileSizeText = 'File size is too large. Maximum size: {maxFileSize}',\n invalidFileCountText = 'Too many files selected. Maximum allowed: {maxFiles}',\n } = props;\n\n const handleUpload = (newFiles: File[]): void => {\n // Notify parent - parent will manage state\n onUpload(newFiles);\n };\n\n const handleRemoveFile = (fileToRemove: File): void => {\n // Notify parent - parent will manage state\n onRemove(fileToRemove);\n };\n\n return (\n <>\n <Typography paddingBottom={theme.spacing(1)} variant=\"b1Weak\">\n {label}\n </Typography>\n <Stack direction=\"column\" flex={1} gap={theme.spacing(1)}>\n <FileDropZone\n allowedFileTypes={allowedFileTypes}\n browseButtonText={browseButtonText}\n dragActiveText={dragActiveText}\n dragInactiveText={dragInactiveText}\n handleUpload={handleUpload}\n invalidFileCountText={invalidFileCountText}\n invalidFileSizeText={invalidFileSizeText}\n invalidFileTypesText={invalidFileTypesText}\n maxFiles={maxFiles}\n maxFileSize={maxFileSize}\n multiple={multiple}\n />\n\n {files.length > 0 && (\n <Stack direction=\"column\" gap={theme.spacing(1.5)}>\n {files.map((fileState) => (\n <FileItem\n key={`${fileState.file.name}-${fileState.file.size}-${fileState.file.lastModified}`}\n file={fileState.file}\n isUploading={fileState.isUploading}\n onRemove={handleRemoveFile}\n />\n ))}\n </Stack>\n )}\n </Stack>\n </>\n );\n};\n\nexport default FileUpload;\n"],"names":["FileUpload","props","theme","useTheme","label","files","allowedFileTypes","maxFiles","maxFileSize","onUpload","onRemove","multiple","dragActiveText","dragInactiveText","browseButtonText","invalidFileTypesText","invalidFileSizeText","invalidFileCountText","handleRemoveFile","fileToRemove","_jsxs","_Fragment","children","_jsx","Typography","paddingBottom","spacing","variant","Stack","direction","flex","gap","FileDropZone","handleUpload","newFiles","length","map","fileState","FileItem","file","isUploading","name","size","lastModified"],"mappings":"gSAiGA,MAAMA,EAAyCC,IAC7C,MAAMC,EAAQC,KACRC,MACJA,EAAQ,cAAaC,MACrBA,EAAKC,iBACLA,EAAgBC,SAChBA,EAAQC,YACRA,EAAWC,SACXA,EAAQC,SACRA,EAAQC,SACRA,GAAW,EAAIC,eACfA,EAAcC,iBACdA,EAAgBC,iBAChBA,EAAgBC,qBAChBA,EAAuB,8DAA6DC,oBACpFA,EAAsB,sDAAqDC,qBAC3EA,EAAuB,wDACrBhB,EAOEiB,EAAoBC,IAExBT,EAASS,IAGX,OACEC,EAAAC,EAAA,CAAAC,SAAA,CACEC,EAACC,EAAU,CAACC,cAAevB,EAAMwB,QAAQ,GAAIC,QAAQ,SAAQL,SAC1DlB,IAEHgB,EAACQ,EAAK,CAACC,UAAU,SAASC,KAAM,EAAGC,IAAK7B,EAAMwB,QAAQ,GAAEJ,SAAA,CACtDC,EAACS,GACC1B,iBAAkBA,EAClBQ,iBAAkBA,EAClBF,eAAgBA,EAChBC,iBAAkBA,EAClBoB,aArBcC,IAEpBzB,EAASyB,IAoBHjB,qBAAsBA,EACtBD,oBAAqBA,EACrBD,qBAAsBA,EACtBR,SAAUA,EACVC,YAAaA,EACbG,SAAUA,IAGXN,EAAM8B,OAAS,GACdZ,EAACK,EAAK,CAACC,UAAU,SAASE,IAAK7B,EAAMwB,QAAQ,KAAIJ,SAC9CjB,EAAM+B,KAAKC,GACVd,EAACe,GAECC,KAAMF,EAAUE,KAChBC,YAAaH,EAAUG,YACvB9B,SAAUQ,GAHL,GAAGmB,EAAUE,KAAKE,QAAQJ,EAAUE,KAAKG,QAAQL,EAAUE,KAAKI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Heading.cjs.js","sources":["../../../../src/components/organisms/Heading/Heading.tsx"],"sourcesContent":["import React from 'react';\n\nimport Toolbar from '@mui/material/Toolbar';\n\nimport styled from '@fd/utilities/styledUtilities';\n\nimport Box from '../../atoms/Box';\nimport BreadCrumbs, { type BreadcrumbItem } from '../../atoms/BreadCrumbs';\nimport Button from '../../atoms/Button';\nimport { type ButtonType } from '../../atoms/Button/getButtonStyles';\nimport Typography from '../../atoms/Typography';\nimport
|
|
1
|
+
{"version":3,"file":"Heading.cjs.js","sources":["../../../../src/components/organisms/Heading/Heading.tsx"],"sourcesContent":["import React from 'react';\n\nimport Toolbar from '@mui/material/Toolbar';\n\nimport styled from '@fd/utilities/styledUtilities';\n\nimport Box from '../../atoms/Box';\nimport BreadCrumbs, { type BreadcrumbItem } from '../../atoms/BreadCrumbs';\nimport Button from '../../atoms/Button';\nimport { type ButtonType } from '../../atoms/Button/getButtonStyles';\nimport Typography from '../../atoms/Typography';\nimport ButtonGroup from '../../molecules/ButtonGroup';\nimport { Combobox, type ComboboxOption, type ComboboxProps } from '../../molecules/Combobox';\n\nexport interface ButtonConfig {\n variant: ButtonType;\n onClick: () => void;\n label: string;\n fdKey: string;\n disabled?: boolean;\n}\n\nexport interface SelectConfig {\n options: ComboboxOption[];\n label: string;\n placeholder?: string;\n fdKey: string;\n onChange?: ComboboxProps['onChange'];\n value?: ComboboxProps['value'];\n translations: ComboboxProps['translations'];\n}\n\nexport interface HeadingProps {\n title?: string;\n buttons?: ButtonConfig[];\n description?: string;\n breadcrumbItems?: BreadcrumbItem[];\n selectBoxes?: SelectConfig[];\n}\n\nconst StyledToolbar = styled(Toolbar)(({ theme }) => ({\n flexDirection: 'column',\n alignItems: 'stretch',\n [theme.breakpoints.up('tablet')]: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n },\n [theme.breakpoints.down('tablet')]: {\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n },\n}));\n\nconst StyledLeftSection = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n flex: '1 1 auto',\n gap: theme.spacing(0.5),\n minWidth: 0,\n maxWidth: '100%',\n [theme.breakpoints.up('tablet')]: {\n marginRight: theme.spacing(2),\n },\n}));\n\nconst StyledRightSection = styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: theme.spacing(1),\n flexShrink: 0,\n alignSelf: 'flex-start',\n paddingTop: theme.spacing(0.5),\n [theme.breakpoints.down('tablet')]: {\n justifyContent: 'flex-end',\n marginTop: theme.spacing(1),\n paddingTop: 0,\n alignSelf: 'stretch',\n width: '100%',\n },\n}));\n\nconst StyledSelectedSection = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: theme.spacing(2),\n width: '100%',\n maxWidth: '100%',\n [theme.breakpoints.up('tablet')]: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingTop: theme.spacing(2),\n flexWrap: 'wrap',\n },\n [theme.breakpoints.down('tablet')]: {\n flexDirection: 'column',\n alignItems: 'flex-start',\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n width: '100%',\n },\n}));\n\nexport const Heading: React.FC<HeadingProps> = ({\n title,\n buttons,\n description,\n breadcrumbItems,\n selectBoxes,\n}: HeadingProps) => {\n const renderSelectedSection = () => {\n if (!selectBoxes?.length) {\n return null;\n }\n\n return (\n <StyledSelectedSection>\n {selectBoxes.map((selectConfig) => (\n <Combobox\n key={selectConfig.fdKey}\n fdKey={selectConfig.fdKey}\n label={selectConfig.label}\n onChange={selectConfig.onChange}\n options={selectConfig.options}\n placeholder={selectConfig.placeholder}\n translations={selectConfig.translations}\n value={selectConfig.value ?? null}\n />\n ))}\n </StyledSelectedSection>\n );\n };\n\n const renderLeftSection = () => (\n <StyledLeftSection>\n {breadcrumbItems && <BreadCrumbs items={breadcrumbItems} />}\n {title && <Typography variant=\"h1Strong\">{title}</Typography>}\n {description && (\n <Typography color=\"semantic.text.text-weak\" variant=\"captionWeak\">\n {description}\n </Typography>\n )}\n {renderSelectedSection()}\n </StyledLeftSection>\n );\n\n const renderRightSection = () => {\n if (!buttons?.length) {\n return null;\n }\n\n return (\n <StyledRightSection>\n <ButtonGroup align=\"right\" fdKey=\"heading-button-group\" layout=\"horizontal\" size=\"medium\">\n {buttons.map((buttonConfig: ButtonConfig) => {\n const variant: ButtonType = buttonConfig.variant;\n return (\n <Button\n key={buttonConfig.fdKey}\n disabled={buttonConfig.disabled ?? false}\n fdKey={buttonConfig.fdKey}\n onClick={buttonConfig.onClick}\n variant={variant}\n >\n {buttonConfig.label}\n </Button>\n );\n })}\n </ButtonGroup>\n </StyledRightSection>\n );\n };\n\n return (\n <StyledToolbar>\n {renderLeftSection()}\n {renderRightSection()}\n </StyledToolbar>\n );\n};\n\nexport default Heading;\n"],"names":["StyledToolbar","styled","Toolbar","theme","flexDirection","alignItems","breakpoints","up","justifyContent","paddingTop","spacing","paddingBottom","down","StyledLeftSection","Box","display","flex","gap","minWidth","maxWidth","marginRight","StyledRightSection","flexShrink","alignSelf","marginTop","width","StyledSelectedSection","flexWrap","Heading","title","buttons","description","breadcrumbItems","selectBoxes","_jsxs","children","_jsx","BreadCrumbs","items","Typography","variant","color","length","map","selectConfig","Combobox","fdKey","label","onChange","options","placeholder","translations","value","ButtonGroup","align","layout","size","buttonConfig","Button","disabled","onClick"],"mappings":"8cAwCA,MAAMA,EAAgBC,EAAAA,OAAOC,EAAPD,EAAgB,EAAGE,YAAO,CAC9CC,cAAe,SACfC,WAAY,UACZ,CAACF,EAAMG,YAAYC,GAAG,WAAY,CAChCH,cAAe,MACfC,WAAY,aACZG,eAAgB,gBAChBC,WAAYN,EAAMO,QAAQ,GAC1BC,cAAeR,EAAMO,QAAQ,IAE/B,CAACP,EAAMG,YAAYM,KAAK,WAAY,CAClCH,WAAYN,EAAMO,QAAQ,GAC1BC,cAAeR,EAAMO,QAAQ,QAI3BG,EAAoBZ,EAAAA,OAAOa,EAAPb,EAAY,EAAGE,YAAO,CAC9CY,QAAS,OACTX,cAAe,SACfC,WAAY,aACZW,KAAM,WACNC,IAAKd,EAAMO,QAAQ,IACnBQ,SAAU,EACVC,SAAU,OACV,CAAChB,EAAMG,YAAYC,GAAG,WAAY,CAChCa,YAAajB,EAAMO,QAAQ,QAIzBW,EAAqBpB,EAAAA,OAAOa,EAAPb,EAAY,EAAGE,YAAO,CAC/CY,QAAS,OACTP,eAAgB,WAChBH,WAAY,SACZY,IAAKd,EAAMO,QAAQ,GACnBY,WAAY,EACZC,UAAW,aACXd,WAAYN,EAAMO,QAAQ,IAC1B,CAACP,EAAMG,YAAYM,KAAK,WAAY,CAClCJ,eAAgB,WAChBgB,UAAWrB,EAAMO,QAAQ,GACzBD,WAAY,EACZc,UAAW,UACXE,MAAO,YAILC,EAAwBzB,EAAAA,OAAOa,EAAPb,EAAY,EAAGE,YAAO,CAClDY,QAAS,OACTX,cAAe,SACfC,WAAY,aACZY,IAAKd,EAAMO,QAAQ,GACnBe,MAAO,OACPN,SAAU,OACV,CAAChB,EAAMG,YAAYC,GAAG,WAAY,CAChCH,cAAe,MACfC,WAAY,SACZI,WAAYN,EAAMO,QAAQ,GAC1BiB,SAAU,QAEZ,CAACxB,EAAMG,YAAYM,KAAK,WAAY,CAClCR,cAAe,SACfC,WAAY,aACZI,WAAYN,EAAMO,QAAQ,GAC1BC,cAAeR,EAAMO,QAAQ,GAC7Be,MAAO,YAIEG,EAAkC,EAC7CC,QACAC,UACAC,cACAC,kBACAC,iBAkEEC,EAAAA,KAAClC,EAAa,CAAAmC,SAAA,CAxCdD,OAACrB,EAAiB,CAAAsB,SAAA,CACfH,GAAmBI,EAAAA,IAACC,EAAW,CAACC,MAAON,IACvCH,GAASO,EAAAA,IAACG,EAAU,CAACC,QAAQ,WAAUL,SAAEN,IACzCE,GACCK,EAAAA,IAACG,EAAU,CAACE,MAAM,0BAA0BD,QAAQ,cAAaL,SAC9DJ,IA5BFE,GAAaS,OAKhBN,EAAAA,IAACV,EAAqB,CAAAS,SACnBF,EAAYU,KAAKC,GAChBR,EAAAA,IAACS,EAAAA,SAAQ,CAEPC,MAAOF,EAAaE,MACpBC,MAAOH,EAAaG,MACpBC,SAAUJ,EAAaI,SACvBC,QAASL,EAAaK,QACtBC,YAAaN,EAAaM,YAC1BC,aAAcP,EAAaO,aAC3BC,MAAOR,EAAaQ,OAAS,MAPxBR,EAAaE,WAPjB,QAmCJhB,GAASY,OAKZN,EAAAA,IAACf,EAAkB,CAAAc,SACjBC,EAAAA,IAACiB,EAAW,CAACC,MAAM,QAAQR,MAAM,uBAAuBS,OAAO,aAAaC,KAAK,SAAQrB,SACtFL,EAAQa,KAAKc,IACZ,MAAMjB,EAAsBiB,EAAajB,QACzC,OACEJ,EAAAA,IAACsB,SAAM,CAELC,SAAUF,EAAaE,WAAY,EACnCb,MAAOW,EAAaX,MACpBc,QAASH,EAAaG,QACtBpB,QAASA,EAAOL,SAEfsB,EAAaV,OANTU,EAAaX,cAVrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Heading.js","sources":["../../../../src/components/organisms/Heading/Heading.tsx"],"sourcesContent":["import React from 'react';\n\nimport Toolbar from '@mui/material/Toolbar';\n\nimport styled from '@fd/utilities/styledUtilities';\n\nimport Box from '../../atoms/Box';\nimport BreadCrumbs, { type BreadcrumbItem } from '../../atoms/BreadCrumbs';\nimport Button from '../../atoms/Button';\nimport { type ButtonType } from '../../atoms/Button/getButtonStyles';\nimport Typography from '../../atoms/Typography';\nimport
|
|
1
|
+
{"version":3,"file":"Heading.js","sources":["../../../../src/components/organisms/Heading/Heading.tsx"],"sourcesContent":["import React from 'react';\n\nimport Toolbar from '@mui/material/Toolbar';\n\nimport styled from '@fd/utilities/styledUtilities';\n\nimport Box from '../../atoms/Box';\nimport BreadCrumbs, { type BreadcrumbItem } from '../../atoms/BreadCrumbs';\nimport Button from '../../atoms/Button';\nimport { type ButtonType } from '../../atoms/Button/getButtonStyles';\nimport Typography from '../../atoms/Typography';\nimport ButtonGroup from '../../molecules/ButtonGroup';\nimport { Combobox, type ComboboxOption, type ComboboxProps } from '../../molecules/Combobox';\n\nexport interface ButtonConfig {\n variant: ButtonType;\n onClick: () => void;\n label: string;\n fdKey: string;\n disabled?: boolean;\n}\n\nexport interface SelectConfig {\n options: ComboboxOption[];\n label: string;\n placeholder?: string;\n fdKey: string;\n onChange?: ComboboxProps['onChange'];\n value?: ComboboxProps['value'];\n translations: ComboboxProps['translations'];\n}\n\nexport interface HeadingProps {\n title?: string;\n buttons?: ButtonConfig[];\n description?: string;\n breadcrumbItems?: BreadcrumbItem[];\n selectBoxes?: SelectConfig[];\n}\n\nconst StyledToolbar = styled(Toolbar)(({ theme }) => ({\n flexDirection: 'column',\n alignItems: 'stretch',\n [theme.breakpoints.up('tablet')]: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n },\n [theme.breakpoints.down('tablet')]: {\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n },\n}));\n\nconst StyledLeftSection = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n flex: '1 1 auto',\n gap: theme.spacing(0.5),\n minWidth: 0,\n maxWidth: '100%',\n [theme.breakpoints.up('tablet')]: {\n marginRight: theme.spacing(2),\n },\n}));\n\nconst StyledRightSection = styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: theme.spacing(1),\n flexShrink: 0,\n alignSelf: 'flex-start',\n paddingTop: theme.spacing(0.5),\n [theme.breakpoints.down('tablet')]: {\n justifyContent: 'flex-end',\n marginTop: theme.spacing(1),\n paddingTop: 0,\n alignSelf: 'stretch',\n width: '100%',\n },\n}));\n\nconst StyledSelectedSection = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: theme.spacing(2),\n width: '100%',\n maxWidth: '100%',\n [theme.breakpoints.up('tablet')]: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingTop: theme.spacing(2),\n flexWrap: 'wrap',\n },\n [theme.breakpoints.down('tablet')]: {\n flexDirection: 'column',\n alignItems: 'flex-start',\n paddingTop: theme.spacing(2),\n paddingBottom: theme.spacing(2),\n width: '100%',\n },\n}));\n\nexport const Heading: React.FC<HeadingProps> = ({\n title,\n buttons,\n description,\n breadcrumbItems,\n selectBoxes,\n}: HeadingProps) => {\n const renderSelectedSection = () => {\n if (!selectBoxes?.length) {\n return null;\n }\n\n return (\n <StyledSelectedSection>\n {selectBoxes.map((selectConfig) => (\n <Combobox\n key={selectConfig.fdKey}\n fdKey={selectConfig.fdKey}\n label={selectConfig.label}\n onChange={selectConfig.onChange}\n options={selectConfig.options}\n placeholder={selectConfig.placeholder}\n translations={selectConfig.translations}\n value={selectConfig.value ?? null}\n />\n ))}\n </StyledSelectedSection>\n );\n };\n\n const renderLeftSection = () => (\n <StyledLeftSection>\n {breadcrumbItems && <BreadCrumbs items={breadcrumbItems} />}\n {title && <Typography variant=\"h1Strong\">{title}</Typography>}\n {description && (\n <Typography color=\"semantic.text.text-weak\" variant=\"captionWeak\">\n {description}\n </Typography>\n )}\n {renderSelectedSection()}\n </StyledLeftSection>\n );\n\n const renderRightSection = () => {\n if (!buttons?.length) {\n return null;\n }\n\n return (\n <StyledRightSection>\n <ButtonGroup align=\"right\" fdKey=\"heading-button-group\" layout=\"horizontal\" size=\"medium\">\n {buttons.map((buttonConfig: ButtonConfig) => {\n const variant: ButtonType = buttonConfig.variant;\n return (\n <Button\n key={buttonConfig.fdKey}\n disabled={buttonConfig.disabled ?? false}\n fdKey={buttonConfig.fdKey}\n onClick={buttonConfig.onClick}\n variant={variant}\n >\n {buttonConfig.label}\n </Button>\n );\n })}\n </ButtonGroup>\n </StyledRightSection>\n );\n };\n\n return (\n <StyledToolbar>\n {renderLeftSection()}\n {renderRightSection()}\n </StyledToolbar>\n );\n};\n\nexport default Heading;\n"],"names":["StyledToolbar","styled","Toolbar","theme","flexDirection","alignItems","breakpoints","up","justifyContent","paddingTop","spacing","paddingBottom","down","StyledLeftSection","Box","display","flex","gap","minWidth","maxWidth","marginRight","StyledRightSection","flexShrink","alignSelf","marginTop","width","StyledSelectedSection","flexWrap","Heading","title","buttons","description","breadcrumbItems","selectBoxes","_jsxs","children","_jsx","BreadCrumbs","items","Typography","variant","color","length","map","selectConfig","Combobox","fdKey","label","onChange","options","placeholder","translations","value","ButtonGroup","align","layout","size","buttonConfig","Button","disabled","onClick"],"mappings":"kbAwCA,MAAMA,EAAgBC,EAAOC,EAAPD,EAAgB,EAAGE,YAAO,CAC9CC,cAAe,SACfC,WAAY,UACZ,CAACF,EAAMG,YAAYC,GAAG,WAAY,CAChCH,cAAe,MACfC,WAAY,aACZG,eAAgB,gBAChBC,WAAYN,EAAMO,QAAQ,GAC1BC,cAAeR,EAAMO,QAAQ,IAE/B,CAACP,EAAMG,YAAYM,KAAK,WAAY,CAClCH,WAAYN,EAAMO,QAAQ,GAC1BC,cAAeR,EAAMO,QAAQ,QAI3BG,EAAoBZ,EAAOa,EAAPb,EAAY,EAAGE,YAAO,CAC9CY,QAAS,OACTX,cAAe,SACfC,WAAY,aACZW,KAAM,WACNC,IAAKd,EAAMO,QAAQ,IACnBQ,SAAU,EACVC,SAAU,OACV,CAAChB,EAAMG,YAAYC,GAAG,WAAY,CAChCa,YAAajB,EAAMO,QAAQ,QAIzBW,EAAqBpB,EAAOa,EAAPb,EAAY,EAAGE,YAAO,CAC/CY,QAAS,OACTP,eAAgB,WAChBH,WAAY,SACZY,IAAKd,EAAMO,QAAQ,GACnBY,WAAY,EACZC,UAAW,aACXd,WAAYN,EAAMO,QAAQ,IAC1B,CAACP,EAAMG,YAAYM,KAAK,WAAY,CAClCJ,eAAgB,WAChBgB,UAAWrB,EAAMO,QAAQ,GACzBD,WAAY,EACZc,UAAW,UACXE,MAAO,YAILC,EAAwBzB,EAAOa,EAAPb,EAAY,EAAGE,YAAO,CAClDY,QAAS,OACTX,cAAe,SACfC,WAAY,aACZY,IAAKd,EAAMO,QAAQ,GACnBe,MAAO,OACPN,SAAU,OACV,CAAChB,EAAMG,YAAYC,GAAG,WAAY,CAChCH,cAAe,MACfC,WAAY,SACZI,WAAYN,EAAMO,QAAQ,GAC1BiB,SAAU,QAEZ,CAACxB,EAAMG,YAAYM,KAAK,WAAY,CAClCR,cAAe,SACfC,WAAY,aACZI,WAAYN,EAAMO,QAAQ,GAC1BC,cAAeR,EAAMO,QAAQ,GAC7Be,MAAO,YAIEG,EAAkC,EAC7CC,QACAC,UACAC,cACAC,kBACAC,iBAkEEC,EAAClC,EAAa,CAAAmC,SAAA,CAxCdD,EAACrB,EAAiB,CAAAsB,SAAA,CACfH,GAAmBI,EAACC,EAAW,CAACC,MAAON,IACvCH,GAASO,EAACG,EAAU,CAACC,QAAQ,WAAUL,SAAEN,IACzCE,GACCK,EAACG,EAAU,CAACE,MAAM,0BAA0BD,QAAQ,cAAaL,SAC9DJ,IA5BFE,GAAaS,OAKhBN,EAACV,EAAqB,CAAAS,SACnBF,EAAYU,KAAKC,GAChBR,EAACS,EAAQ,CAEPC,MAAOF,EAAaE,MACpBC,MAAOH,EAAaG,MACpBC,SAAUJ,EAAaI,SACvBC,QAASL,EAAaK,QACtBC,YAAaN,EAAaM,YAC1BC,aAAcP,EAAaO,aAC3BC,MAAOR,EAAaQ,OAAS,MAPxBR,EAAaE,WAPjB,QAmCJhB,GAASY,OAKZN,EAACf,EAAkB,CAAAc,SACjBC,EAACiB,EAAW,CAACC,MAAM,QAAQR,MAAM,uBAAuBS,OAAO,aAAaC,KAAK,SAAQrB,SACtFL,EAAQa,KAAKc,IACZ,MAAMjB,EAAsBiB,EAAajB,QACzC,OACEJ,EAACsB,EAAM,CAELC,SAAUF,EAAaE,WAAY,EACnCb,MAAOW,EAAaX,MACpBc,QAASH,EAAaG,QACtBpB,QAASA,EAAOL,SAEfsB,EAAaV,OANTU,EAAaX,cAVrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileUtils.cjs.js","sources":["../../src/utilities/fileUtils.ts"],"sourcesContent":["export const TEN_MB_IN_BYTES = 10 * 1024 * 1024;\n"],"names":[],"mappings":"qCAA+B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileUtils.js","sources":["../../src/utilities/fileUtils.ts"],"sourcesContent":["export const TEN_MB_IN_BYTES = 10 * 1024 * 1024;\n"],"names":["TEN_MB_IN_BYTES"],"mappings":"MAAaA,EAAkB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeUtilities.cjs.js","sources":["../../src/utilities/timeUtilities.ts"],"sourcesContent":["export const FIVE_MINUTES = 5 * 60 * 1000;\nexport const TEN_MINUTES = 10 * 60 * 1000;\nexport const THIRTY_MINUTES = 30 * 60 * 1000;\nexport const ONE_HOUR = 60 * 60 * 1000;\nexport const ONE_DAY = 24 * 60 * 60 * 1000;\n"],"names":[],"mappings":"kCAA4B,oBAIL,uBADC,yBAFG,2BACG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeUtilities.js","sources":["../../src/utilities/timeUtilities.ts"],"sourcesContent":["export const FIVE_MINUTES = 5 * 60 * 1000;\nexport const TEN_MINUTES = 10 * 60 * 1000;\nexport const THIRTY_MINUTES = 30 * 60 * 1000;\nexport const ONE_HOUR = 60 * 60 * 1000;\nexport const ONE_DAY = 24 * 60 * 60 * 1000;\n"],"names":["FIVE_MINUTES","TEN_MINUTES","THIRTY_MINUTES","ONE_HOUR","ONE_DAY"],"mappings":"MAAaA,EAAe,IACfC,EAAc,IACdC,EAAiB,KACjBC,EAAW,KACXC,EAAU"}
|