From f30e11134dcc952e76590ae3be50860716109d02 Mon Sep 17 00:00:00 2001 From: Kenneth Date: Wed, 23 Apr 2025 21:59:10 +0700 Subject: [PATCH 1/4] #feature: Add loading for Typography atomic --- src/atomics/Typography/TypographyLink.tsx | 7 ++++++- .../Typography/TypographyParagraph.tsx | 7 ++++++- src/atomics/Typography/TypographyText.tsx | 12 +++++++++++- src/atomics/Typography/TypographyTitle.tsx | 7 ++++++- src/atomics/Typography/styles.tsx | 19 +++++++++++++++++-- src/atomics/Typography/types.ts | 18 +++++++++++++----- 6 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/atomics/Typography/TypographyLink.tsx b/src/atomics/Typography/TypographyLink.tsx index 5fbb009..061c45e 100644 --- a/src/atomics/Typography/TypographyLink.tsx +++ b/src/atomics/Typography/TypographyLink.tsx @@ -1,9 +1,14 @@ import { forwardRef } from 'react'; import { TypographyLinkStyles } from './styles'; import { RdTypographyLinkProps } from './types'; +import { Skeleton } from '../../molecules'; export const TypographyLink = forwardRef( - ({ ...antdProps }: RdTypographyLinkProps, ref: RdTypographyLinkProps['ref']) => { + (props: RdTypographyLinkProps, ref: RdTypographyLinkProps['ref']) => { + const { loading, ...antdProps } = props; + + if (loading) return ; + return ; } ); diff --git a/src/atomics/Typography/TypographyParagraph.tsx b/src/atomics/Typography/TypographyParagraph.tsx index 0ab6f71..e61c790 100644 --- a/src/atomics/Typography/TypographyParagraph.tsx +++ b/src/atomics/Typography/TypographyParagraph.tsx @@ -1,9 +1,14 @@ import { forwardRef } from 'react'; import { TypographyParagraphStyles } from './styles'; import { RdTypographyParagraphProps } from './types'; +import { Skeleton } from '../../molecules'; export const TypographyParagraph = forwardRef( - ({ ...antdProps }: RdTypographyParagraphProps, ref: RdTypographyParagraphProps['ref']) => { + (props: RdTypographyParagraphProps, ref: RdTypographyParagraphProps['ref']) => { + const { loading, ...antdProps } = props; + + if (loading) return ; + return ; } ); diff --git a/src/atomics/Typography/TypographyText.tsx b/src/atomics/Typography/TypographyText.tsx index 905cd49..eb4044a 100644 --- a/src/atomics/Typography/TypographyText.tsx +++ b/src/atomics/Typography/TypographyText.tsx @@ -1,10 +1,20 @@ import { forwardRef, useMemo } from 'react'; import { TypographyTextStyles } from './styles'; import { RdTypographyTextProps } from './types'; +import { Skeleton } from '../../molecules'; export const TypographyText = forwardRef( (props: RdTypographyTextProps, ref: RdTypographyTextProps['ref']) => { - const { size = 'normal', editable, autoFocus = false, onChange, ...antdProps } = props; + const { + size = 'normal', + editable, + autoFocus = false, + loading = false, + onChange, + ...antdProps + } = props; + + if (loading) return ; const editableCustom = useMemo(() => { if (editable && typeof editable === 'object') { diff --git a/src/atomics/Typography/TypographyTitle.tsx b/src/atomics/Typography/TypographyTitle.tsx index 6034307..c9ceecd 100644 --- a/src/atomics/Typography/TypographyTitle.tsx +++ b/src/atomics/Typography/TypographyTitle.tsx @@ -1,9 +1,14 @@ import { forwardRef } from 'react'; +import { Skeleton } from '../../molecules'; import { TypographyTitleStyles } from './styles'; import { RdTypographyTitleProps } from './types'; export const TypographyTitle = forwardRef( - ({ disableMargin, ...antdProps }: RdTypographyTitleProps, ref: RdTypographyTitleProps['ref']) => { + (props: RdTypographyTitleProps, ref: RdTypographyTitleProps['ref']) => { + const { disableMargin, loading, ...antdProps } = props; + + if (loading) return ; + return ; } ); diff --git a/src/atomics/Typography/styles.tsx b/src/atomics/Typography/styles.tsx index ee82e8c..14280cb 100644 --- a/src/atomics/Typography/styles.tsx +++ b/src/atomics/Typography/styles.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; import { Typography } from 'antd'; import { getComponentOrGlobalToken } from '../../utils/token'; -import { RdTypographyTextProps, RdTypographyTitleProps } from './types'; +import { RdTypographyParagraphProps, RdTypographyTextProps, RdTypographyTitleProps } from './types'; import { css } from '@emotion/react'; import { getExcludeForwardProps } from '../../utils/styles'; @@ -36,4 +36,19 @@ export const TypographyTextStyles = styled(Typography.Text) + getExcludeForwardProps( + ['minRows'] as (keyof RdTypographyParagraphProps)[], + prop + ), +})` + ${({ minRows }) => { + return ( + minRows && + css` + min-height: ${Number(getComponentOrGlobalToken('Typography', 'lineHeight')) * Number(getComponentOrGlobalToken('Typography', 'fontSize')) * minRows}px; + ` + ); + }} +`; diff --git a/src/atomics/Typography/types.ts b/src/atomics/Typography/types.ts index 49dfba1..8faf32e 100644 --- a/src/atomics/Typography/types.ts +++ b/src/atomics/Typography/types.ts @@ -14,10 +14,18 @@ type TypographyComponentTokenExtend = {}; //#endregion //#region Define extended types -type TypographyPropsExtend = {}; -type TypographyLinkPropsExtend = {}; -type TypographyParagraphPropsExtend = {}; -type TypographyTextPropsExtend = { +type TypographyBaseProps = { + loading?: boolean; +}; +type TypographyPropsExtend = TypographyBaseProps & {}; +type TypographyLinkPropsExtend = TypographyBaseProps & {}; +type TypographyParagraphPropsExtend = TypographyBaseProps & { + /** + * Min rows of paragraph + */ + minRows?: number; +}; +type TypographyTextPropsExtend = TypographyBaseProps & { /** * @description The size of the text. * @default "normal" @@ -34,7 +42,7 @@ type TypographyTextPropsExtend = { /** * Extended properties for customizing the Typography.Title component. */ -type TypographyTitlePropsExtend = { +type TypographyTitlePropsExtend = TypographyBaseProps & { /** * If set to `true`, disables the default margin applied to the Typography.Title component. * @default false From e996951e82e0a5e361b38891580ab5089f85a838 Mon Sep 17 00:00:00 2001 From: Kenneth Date: Wed, 23 Apr 2025 21:59:27 +0700 Subject: [PATCH 2/4] #feature: Add loading for Image molecule --- src/molecules/Image/Image.tsx | 33 ++++++++++++++++++++++++++++++++- src/molecules/Image/styles.tsx | 16 +++++++++++++++- src/molecules/Image/types.ts | 8 ++++++-- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/molecules/Image/Image.tsx b/src/molecules/Image/Image.tsx index b6a2082..7ea3b6c 100644 --- a/src/molecules/Image/Image.tsx +++ b/src/molecules/Image/Image.tsx @@ -1,6 +1,37 @@ +import { Skeleton } from '../Skeleton'; import { ImageStyles } from './styles'; import { RdImageComponent } from './types'; export const Image: RdImageComponent = props => { - return ; + const { loading = false, ...antdProps } = props; + + return ( + <> + {/** + * Note: + * Previously, when `loading = true`, the component only rendered the `Skeleton.Node` + * and skipped rendering the `ImageStyles` completely. + * + * However, in that case, the `img` element was never created, so the browser wouldn't start downloading the image, + * and we couldn't catch the `onLoad` event. + * + * Now, even when `loading = true`, the image is still rendered (but hidden) so that: + * - The browser starts loading it + * - The `onLoad` event can be triggered when it's ready + * - Once the image is fully loaded, `loading` can be set to `false`, revealing the image + * + * This helps with smoother image transitions (e.g. fade-in) and avoids a jarring pop-in effect. + */} + {loading && ( + + )} +