From b6a0cbdf7ce0ac1edd1a93b36a98fac97bc72cda Mon Sep 17 00:00:00 2001 From: Emerson Pfeiffer Date: Mon, 1 Jul 2024 13:29:54 -0700 Subject: [PATCH] Fork file uploader beta from basui (#5343) --- .../__tests__/file-uploader-beta.test.tsx | 39 ++++++++++++++ src/file-uploader-beta/file-uploader-beta.tsx | 28 +++++++--- src/file-uploader-beta/styled-components.ts | 52 +++++++++++++++++-- src/file-uploader-beta/types.ts | 15 +++--- src/file-uploader-beta/utils.ts | 10 ++++ 5 files changed, 126 insertions(+), 18 deletions(-) diff --git a/src/file-uploader-beta/__tests__/file-uploader-beta.test.tsx b/src/file-uploader-beta/__tests__/file-uploader-beta.test.tsx index 75d4a65bf0..fcf6a52163 100644 --- a/src/file-uploader-beta/__tests__/file-uploader-beta.test.tsx +++ b/src/file-uploader-beta/__tests__/file-uploader-beta.test.tsx @@ -27,6 +27,45 @@ describe('FileUploaderBeta', () => { expect(container).toBeDefined(); }); + it('renders gracefully with different style override types', () => { + const { container } = render( + <> + {' '} + ({ + outline: `${$theme.colors.warning600} solid`, + backgroundColor: $theme.colors.warning600, + }), + }, + }, + }, + }, + }} + /> + + ); + expect(container).toBeDefined(); + }); + it('throws errors when invalid props are passed in', () => { const original = console.error; console.error = jest.fn(); diff --git a/src/file-uploader-beta/file-uploader-beta.tsx b/src/file-uploader-beta/file-uploader-beta.tsx index a192ea0317..595f67c5e5 100644 --- a/src/file-uploader-beta/file-uploader-beta.tsx +++ b/src/file-uploader-beta/file-uploader-beta.tsx @@ -26,7 +26,7 @@ import { StyledTrashCanFilledIconContainer, } from './styled-components'; import { FILE_STATUS, FILE_STATUS_TO_COLOR_MAP } from './constants'; -import { formatBytes } from './utils'; +import { destructureStyleOverride, formatBytes } from './utils'; import AlertIconComponent from '../icon/alert'; import CircleCheckFilledIconComponent from '../icon/circle-check-filled'; import PaperclipFilledIconComponent from '../icon/paperclip-filled'; @@ -275,7 +275,7 @@ export default function FileUploaderBeta(props: FileUploaderBetaProps) { style: { marginTop: 0, // @ts-expect-error - ...props.overrides?.ButtonComponent?.props?.style, + ...destructureStyleOverride(props.overrides?.ButtonComponent?.props?.style, theme), }, overrides: { // @ts-expect-error @@ -285,8 +285,11 @@ export default function FileUploaderBeta(props: FileUploaderBetaProps) { ...props.overrides?.ButtonComponent?.props?.overrides?.BaseButton, style: { backgroundColor: theme.colors.backgroundPrimary, - // @ts-expect-error - ...props.overrides?.ButtonComponent?.props?.overrides?.BaseButton?.style, + ...destructureStyleOverride( + // @ts-expect-error + props.overrides?.ButtonComponent?.props?.overrides?.BaseButton?.style, + theme + ), }, }, }, @@ -296,7 +299,7 @@ export default function FileUploaderBeta(props: FileUploaderBetaProps) { style: { ...theme.typography.ParagraphMedium, color: theme.colors.contentTertiary, - ...props.overrides?.ContentMessage?.style, + ...destructureStyleOverride(props.overrides?.ContentMessage?.style, theme), }, }, FileDragAndDrop: { @@ -309,7 +312,14 @@ export default function FileUploaderBeta(props: FileUploaderBetaProps) { paddingLeft: theme.sizing.scale600, paddingRight: theme.sizing.scale600, paddingTop: theme.sizing.scale600, - ...props.overrides?.FileDragAndDrop?.style, + ...destructureStyleOverride(props.overrides?.FileDragAndDrop?.style, theme), + }, + }, + Root: { + style: { + zIndex: 1, + ...destructureStyleOverride(props.overrides?.Root?.style, theme), + ...props.overrides?.Root?.style, }, }, }} @@ -475,7 +485,11 @@ export default function FileUploaderBeta(props: FileUploaderBetaProps) { )} {props.hint && ( - + {props.hint} )} diff --git a/src/file-uploader-beta/styled-components.ts b/src/file-uploader-beta/styled-components.ts index 6f0168b44e..f307268390 100644 --- a/src/file-uploader-beta/styled-components.ts +++ b/src/file-uploader-beta/styled-components.ts @@ -9,9 +9,26 @@ import type { StyleProps } from './types'; export const StyledFileRow = styled<'li', StyleProps>('li', (props) => { const { - $theme: { sizing }, + $theme: { animation, sizing }, } = props; return { + animationDuration: animation.timing400, + animationFillMode: 'forwards', + animationIterationCount: 1, + animationTimingFunction: animation.easeOutQuinticCurve, + animationName: { + '0%': { + transform: 'translateY(-32px)', + opacity: 0, + }, + '50%': { + opacity: 1, + }, + '100%': { + transform: 'translateY(0px)', + opacity: 1, + }, + }, paddingTop: sizing.scale500, paddingRight: sizing.scale500, paddingBottom: sizing.scale500, @@ -117,9 +134,20 @@ StyledFileRowUploadText.displayName = 'StyledFileRowUploadText'; export const StyledFileRows = styled<'ul', StyleProps>('ul', (props) => { const { - $theme: { borders, sizing }, + $theme: { animation, borders, sizing }, } = props; return { + animationDuration: animation.timing500, + animationIterationCount: 1, + animationTimingFunction: animation.easeInOutQuinticCurve, + animationName: { + '0%': { + transform: 'translateY(-32px)', + }, + '100%': { + transform: 'translateX(-0px)', + }, + }, ...borders.border200, borderRadius: borders.radius400, borderWidth: sizing.scale0, @@ -133,10 +161,28 @@ StyledFileRows.displayName = 'StyledFileRows'; export const StyledHint = styled<'div', StyleProps>('div', (props) => { const { - $theme: { colors, typography }, + $fileCount, + $theme: { animation, colors, typography }, } = props; let fontColor = colors.contentTertiary; + const animations = + $fileCount > 0 + ? { + animationDuration: animation.timing500, + animationIterationCount: 1, + animationTimingFunction: animation.easeInOutQuinticCurve, + animationName: { + '0%': { + transform: 'translateY(-32px)', + }, + '100%': { + transform: 'translateX(-0px)', + }, + }, + } + : {}; return { + ...animations, ...typography.font100, color: fontColor, }; diff --git a/src/file-uploader-beta/types.ts b/src/file-uploader-beta/types.ts index c852271968..6c0945915e 100644 --- a/src/file-uploader-beta/types.ts +++ b/src/file-uploader-beta/types.ts @@ -6,17 +6,16 @@ LICENSE file in the root directory of this source tree. */ import type { Override } from '../helpers/overrides'; import type { FILE_STATUS } from './constants'; -import type { FileUploaderOverrides, FileUploaderProps } from '../file-uploader/types'; +import type { + FileUploaderOverrides, + FileUploaderProps, + StyleProps as FileUploaderBasicStyleProps, +} from '../file-uploader/types'; -export type StyleProps = { - $afterFileDrop: boolean; +export type StyleProps = FileUploaderBasicStyleProps & { $alt: string; $color: string; - $disabled: boolean; - $isDragActive: boolean; - $isDragAccept: boolean; - $isDragReject: boolean; - $isFocused: boolean; + $fileCount: number; $src: string; }; diff --git a/src/file-uploader-beta/utils.ts b/src/file-uploader-beta/utils.ts index 4f7a9964b0..7390308381 100644 --- a/src/file-uploader-beta/utils.ts +++ b/src/file-uploader-beta/utils.ts @@ -4,6 +4,16 @@ Copyright (c) Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ +import type { Theme } from '../styles'; + +export const destructureStyleOverride = (styleOverride: any, theme: Theme) => { + if (typeof styleOverride === 'function') { + return styleOverride({ $theme: theme }); + } else { + return styleOverride; + } +}; + export const formatBytes = (bytes: number): string => { if (bytes === 0) return '0 bytes'; const k = 1000;