Skip to content

Commit

Permalink
feat: add forwardRef for component
Browse files Browse the repository at this point in the history
  • Loading branch information
aelf-lxy committed Mar 25, 2024
1 parent 7ab7bb2 commit 0ed3c17
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 133 deletions.
113 changes: 61 additions & 52 deletions packages/component/src/Address/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { memo } from 'react';
import React, { forwardRef } from 'react';

import Copy from './copy';
import useStyles from './style';
Expand Down Expand Up @@ -59,59 +59,68 @@ const getOmittedStr = (str: string, preLen?: number, endLen?: number) => {
return `${str.slice(0, preLen)}...${str.slice(-endLen)}`;
};

function Address({
address,
chain = 'AELF',
preLen = 0,
endLen = 0,
hasCopy = true,
addressClickCallback,
className,
size = 'default',
ignorePrefixSuffix = false,
ignoreEvent = false,
primaryLinkColor,
primaryIconColor,
addressHoverColor,
addressActiveColor,
}: IHashAddressProps) {
const {
styles: st,
cx,
prefixCls,
} = useStyles({
size,
ignoreEvent,
primaryLinkColor,
primaryIconColor,
addressHoverColor,
addressActiveColor,
});
const Address = forwardRef<HTMLDivElement, IHashAddressProps>(
(
{
address,
chain = 'AELF',
preLen = 0,
endLen = 0,
hasCopy = true,
addressClickCallback,
className,
size = 'default',
ignorePrefixSuffix = false,
ignoreEvent = false,
primaryLinkColor,
primaryIconColor,
addressHoverColor,
addressActiveColor,
}: IHashAddressProps,
ref,
) => {
const {
styles: st,
cx,
prefixCls,
} = useStyles({
size,
ignoreEvent,
primaryLinkColor,
primaryIconColor,
addressHoverColor,
addressActiveColor,
});

const addPrefixSuffixTxt = ignorePrefixSuffix ? address : addPrefixSuffix(address, chain);
const omittedStr = getOmittedStr(addPrefixSuffixTxt, preLen, endLen);
const addPrefixSuffixTxt = ignorePrefixSuffix ? address : addPrefixSuffix(address, chain);
const omittedStr = getOmittedStr(addPrefixSuffixTxt, preLen, endLen);

const addressClickHandler = (e: React.MouseEvent<HTMLElement>) => {
if (ignoreEvent) {
return;
}
if (addressClickCallback) {
addressClickCallback(address, addPrefixSuffixTxt, e);
}
};
const addressClickHandler = (e: React.MouseEvent<HTMLElement>) => {
if (ignoreEvent) {
return;
}
if (addressClickCallback) {
addressClickCallback(address, addPrefixSuffixTxt, e);
}
};

return (
<div className={cx(st.addressWrap, className, prefixCls + '-hash-address')}>
<span className={st.addressText} onClick={addressClickHandler}>
{omittedStr}
</span>
{hasCopy && (
<div className={st.copyBtnWrap}>
<Copy className={st.copyBtn} value={addPrefixSuffixTxt} />
</div>
)}
</div>
);
return (
<div className={cx(st.addressWrap, className, prefixCls + '-hash-address')} ref={ref}>
<span className={st.addressText} onClick={addressClickHandler}>
{omittedStr}
</span>
{hasCopy && (
<div className={st.copyBtnWrap}>
<Copy className={st.copyBtn} value={addPrefixSuffixTxt} />
</div>
)}
</div>
);
},
);

if (process.env.NODE_ENV !== 'production') {
Address.displayName = 'Address';
}

export default memo(Address);
export default Address;
51 changes: 31 additions & 20 deletions packages/component/src/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { MouseEvent } from 'react';
import React, { forwardRef, MouseEvent } from 'react';
import { Button as AntdButton, ButtonProps } from 'antd';
import { debounce } from 'lodash-es';

Expand All @@ -11,26 +11,37 @@ export interface IButtonProps extends Omit<ButtonProps, 'size' | 'onClick'> {
millisecondOfDebounce?: number;
}

function Button({ size = 'large', className, millisecondOfDebounce = 0, ...rest }: IButtonProps) {
const { styles: st, cx } = useStyles({ size });
const Button = forwardRef<HTMLElement, IButtonProps>(
({ size = 'large', className, millisecondOfDebounce = 0, ...rest }: IButtonProps, ref) => {
const { styles: st, cx } = useStyles({ size });

const buttonClickHandler = debounce(
(e: MouseEvent<HTMLElement>) => {
if (rest.onClick) {
rest.onClick(e);
}
},
millisecondOfDebounce,
{
leading: false,
trailing: true,
},
);
return (
<AntdButton {...rest} onClick={buttonClickHandler} className={cx(st.buttonWrap, className)}>
{rest.children}
</AntdButton>
);
const buttonClickHandler = debounce(
(e: MouseEvent<HTMLElement>) => {
if (rest.onClick) {
rest.onClick(e);
}
},
millisecondOfDebounce,
{
leading: false,
trailing: true,
},
);
return (
<AntdButton
ref={ref}
{...rest}
onClick={buttonClickHandler}
className={cx(st.buttonWrap, className)}
>
{rest.children}
</AntdButton>
);
},
);

if (process.env.NODE_ENV !== 'production') {
Button.displayName = 'Button';
}

export default Button;
13 changes: 10 additions & 3 deletions packages/component/src/Carousel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { SetStateAction, useState } from 'react';
import React, { forwardRef, SetStateAction, useState } from 'react';
import { NextButtonIcon, PrevButtonIcon } from '@aelf-design/internal-icons';
import { useResponsive, useTheme } from 'antd-style';
import { FreeMode, Navigation, Thumbs } from 'swiper/modules';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Swiper, SwiperRef, SwiperSlide } from 'swiper/react';

import useStyles from './styles';

Expand All @@ -23,7 +23,7 @@ export interface ICarouselProps {
onSlideClick?: (value: ICarouselSlideItem) => void;
}

export default function Carousel(props: ICarouselProps) {
const Carousel = forwardRef<SwiperRef, ICarouselProps>((props: ICarouselProps, ref) => {
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const {
data,
Expand Down Expand Up @@ -60,6 +60,7 @@ export default function Carousel(props: ICarouselProps) {
thumbs={{ swiper: thumbsSwiper }}
modules={[FreeMode, Navigation, Thumbs]}
className="swiper-gallery"
ref={ref}
>
{data.map((item, index) => {
return (
Expand Down Expand Up @@ -121,4 +122,10 @@ export default function Carousel(props: ICarouselProps) {
</Swiper>
</div>
);
});

if (process.env.NODE_ENV !== 'production') {
Carousel.displayName = 'Carousel';
}

export default Carousel;
36 changes: 25 additions & 11 deletions packages/component/src/Collapse/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { forwardRef } from 'react';
import { DownOutlined } from '@aelf-design/internal-icons';
import { Collapse as AntdCollapse, CollapseProps } from 'antd';

Expand All @@ -8,17 +8,31 @@ export interface ICollapseProps extends Omit<CollapseProps, 'expandIcon' | 'expa
className?: string;
}

function Collapse({ className, ...rest }: ICollapseProps) {
const { styles: st, cx } = useStyles();
return (
<AntdCollapse
{...rest}
expandIcon={({ isActive }) => <DownOutlined className={cx(isActive && st.collapseIcon)} />}
expandIconPosition={'end'}
className={cx(st.aelfdCollapse, className)}
/>
);
const InternalCollapse = forwardRef<HTMLDivElement, ICollapseProps>(
({ className, ...rest }: ICollapseProps, ref) => {
const { styles: st, cx } = useStyles();
return (
<AntdCollapse
{...rest}
expandIcon={({ isActive }) => <DownOutlined className={cx(isActive && st.collapseIcon)} />}
expandIconPosition={'end'}
className={cx(st.aelfdCollapse, className)}
ref={ref}
/>
);
},
);

if (process.env.NODE_ENV !== 'production') {
InternalCollapse.displayName = 'Collapse';
}

type ComputedCollapse = typeof InternalCollapse & {
Panel: typeof AntdCollapse.Panel;
};

const Collapse = InternalCollapse as ComputedCollapse;

Collapse.Panel = AntdCollapse.Panel;

export default Collapse;
8 changes: 4 additions & 4 deletions packages/component/src/Dropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { forwardRef } from 'react';
import { Dropdown as AntdDropdown, DropdownProps } from 'antd';

import useStyles from './style';
Expand All @@ -11,19 +11,19 @@ export interface IDropdownProps extends Omit<DropdownProps, 'overlayClassName'>
offsetY?: number;
}

function Dropdown({
const Dropdown = ({
children,
size = 'default',
offsetX = 0,
offsetY = 0,
...props
}: IDropdownProps) {
}: IDropdownProps) => {
const { styles, cx } = useStyles({ size, offsetX, offsetY });
return (
<AntdDropdown overlayClassName={cx(styles.dropDownWrap, props.overlayClassName)} {...props}>
{children}
</AntdDropdown>
);
}
};

export default Dropdown;
Loading

0 comments on commit 0ed3c17

Please sign in to comment.