Skip to content

Commit

Permalink
feat(tag): 对齐mobile-vue (#445)
Browse files Browse the repository at this point in the history
Co-authored-by: taninsist <[email protected]>
  • Loading branch information
taninsist and taninsist authored Aug 14, 2024
1 parent c6bc1f7 commit 862c5d5
Show file tree
Hide file tree
Showing 27 changed files with 2,374 additions and 374 deletions.
2 changes: 1 addition & 1 deletion site/mobile/mobile.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export default {
{
title: 'Tag 标签',
name: 'tag',
component: () => import('tdesign-mobile-react/tag/_example/index.jsx'),
component: () => import('tdesign-mobile-react/tag/_example/index.tsx'),
},
{
title: 'Toast 轻提示',
Expand Down
159 changes: 89 additions & 70 deletions src/tag/CheckTag.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,105 @@
import React, { forwardRef, Ref } from 'react';
import classNames from 'classnames';
import React, { forwardRef } from 'react';
import { Icon } from 'tdesign-icons-react';
import parseTNode from 'tdesign-mobile-react/_util/parseTNode';
import { StyledProps } from 'tdesign-mobile-react/common';
import useConfig from '../_util/useConfig';
import { TdCheckTagProps } from './type';
import useDefault from '../_util/useDefault';
import noop from '../_util/noop';
import useDefaultProps from '../hooks/useDefaultProps';
import { checkTagDefaultProps } from './defaultProps';
import { TdCheckTagProps } from './type';

export interface CheckTagProps extends TdCheckTagProps, StyledProps {}

const CheckTag = forwardRef<HTMLSpanElement, CheckTagProps>((originProps, ref) => {
const props = useDefaultProps(originProps, checkTagDefaultProps);
const {
checked,
defaultChecked,
content,
children,
style,
className,
icon,
disabled,
closable,
size,
shape,
variant,
onClick,
onChange,
onClose,
...otherProps
} = props;

const { classPrefix } = useConfig();

export interface TagCheckProps extends TdCheckTagProps {
className?: string;
style?: object;
}
const [innerChecked, onInnerChecked] = useDefault(checked, defaultChecked, onChange);

const TagCheck: React.FC<TagCheckProps> = React.memo(
forwardRef((props, ref: Ref<HTMLButtonElement>) => {
const {
checked = undefined,
defaultChecked = undefined,
content = '',
children,
style = {},
className = '',
icon = '',
disabled = false,
closable = false,
size = 'medium',
shape = 'square',
onClick = noop,
onChange = noop,
...other
} = props;
const baseClass = `${classPrefix}-tag`;

const { classPrefix } = useConfig();
const checkTagClass = classNames(
`${baseClass}`,
// `${baseClass}--checkable`,
`${baseClass}--${shape}`,
`${baseClass}--${innerChecked ? 'primary' : 'default'}`,
`${baseClass}--${size}`,
`${baseClass}--${variant}`,

const [innerChecked, onInnerChecked] = useDefault(checked, defaultChecked, onChange);
{
[`${baseClass}--closable`]: closable,
[`${baseClass}--disabled`]: disabled,
[`${baseClass}--checked`]: !disabled && innerChecked,
},
className,
);

const baseClass = `${classPrefix}-tag`;
const renderText = () => {
if (Array.isArray(content) && content.length === 2) {
return innerChecked ? content[0] : content[1];
}
return content;
};

const checkTagClass = classNames(
`${baseClass}`,
`${baseClass}--checkable`,
`${baseClass}--shape-${shape}`,
`${baseClass}--size-${size}`,
{
[`${classPrefix}-is-closable ${baseClass}--closable`]: closable,
[`${classPrefix}-is-disabled ${baseClass}--disabled`]: disabled,
[`${classPrefix}-is-checked ${baseClass}--checked`]: innerChecked,
},
className,
);
const childNode = parseTNode(renderText()) || parseTNode(children);

const tagStyle = {
...style,
};
const tagStyle = {
...style,
};

const handleClick = (e) => {
if (disabled || closable) {
return;
}
const handleClick = (e) => {
if (!props.disabled) {
onClick?.(e);
onInnerChecked(!innerChecked);
onClick({ e });
};
}
};

const handleClose = (e) => {
if (disabled) {
return;
}
e.stopPropagation();
onClick({ e });
};
const handleClose = (e) => {
e.stopPropagation();
if (!props.disabled) {
onClose?.({ e });
}
};

return (
<span className={checkTagClass} style={tagStyle} onClick={handleClick} ref={ref} {...other}>
<span className={`${baseClass}__icon`}>{icon}</span>
<span className={`${baseClass}__text`}>{content || children}</span>
{closable ? (
<span className={`${baseClass}__icon-close`} onClick={handleClose}>
<Icon name="close" />
</span>
) : null}
</span>
);
}),
);
return (
<span
ref={ref}
className={checkTagClass}
aria-disabled={disabled}
role="button"
onClick={handleClick}
style={tagStyle}
{...otherProps}
>
{icon && <span className={`${baseClass}__icon`}>{icon}</span>}
<span className={`${baseClass}__text`}>{childNode}</span>
{props.closable && (
<span className={`${baseClass}__icon-close`} onClick={handleClose}>
<Icon name="close" />
</span>
)}
</span>
);
});

export default TagCheck;
export default CheckTag;
102 changes: 50 additions & 52 deletions src/tag/Tag.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
import React, { useCallback, forwardRef } from 'react';
import classNames from 'classnames';
import React, { forwardRef } from 'react';
import { Icon } from 'tdesign-icons-react';
import noop from '../_util/noop';
import { TdTagProps } from './type';
import parseTNode from 'tdesign-mobile-react/_util/parseTNode';
import { StyledProps } from 'tdesign-mobile-react/common';
import useDefaultProps from 'tdesign-mobile-react/hooks/useDefaultProps';
import useConfig from '../_util/useConfig';
import { tagDefaultProps } from './defaultProps';
import { TdTagProps } from './type';

export interface TagProps extends TdTagProps {
className: string;
style: object;
}
export interface TagProps extends TdTagProps, StyledProps {}

const Tag = forwardRef<HTMLDivElement, TagProps>((props, ref) => {
const Tag = forwardRef<HTMLDivElement, TagProps>((originProps, ref) => {
const props = useDefaultProps(originProps, tagDefaultProps);
const {
className = '',
style = {},
closable = false,
content = null,
disabled = false,
icon = undefined,
className,
style,
closable,
content,
disabled,
icon,
maxWidth,
children = '',
shape = 'square',
size = 'medium',
theme = 'default',
variant = 'dark',
onClick = noop,
onClose = noop,
...other
children,
shape,
size,
theme,
variant,
onClick,
onClose,
...otherProps
} = props;

const { classPrefix } = useConfig();
const baseClass = `${classPrefix}-tag`;

const tagClassNames = classNames(
`${baseClass}`,
`${baseClass}--theme-${theme}`,
`${baseClass}--shape-${shape}`,
`${baseClass}--variant-${variant}`,
`${baseClass}--size-${size}`,
`${baseClass}--${theme}`,
`${baseClass}--${shape}`,
`${baseClass}--${variant}`,
`${baseClass}--${size}`,
{
[`${classPrefix}-is-closable ${baseClass}--closable`]: closable,
[`${classPrefix}-is-disabled ${baseClass}--disabled`]: disabled,
Expand All @@ -50,44 +51,41 @@ const Tag = forwardRef<HTMLDivElement, TagProps>((props, ref) => {
maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,
};

const getRenderContent = useCallback(() => {
const contentType = typeof content;
if (contentType === 'string' || contentType === 'number') {
return content;
}
// if (contentType === 'function') {
// return content();
// }

return content;
}, [content]);

function onClickClose(e) {
if (disabled) {
return;
}
const handleClose = (e) => {
e.stopPropagation();
onClose({ e });
}
if (!props.disabled) {
onClose?.({ e });
}
};

const handleClick = (e) => {
if (disabled) {
return;
}
onClick({ e });
onClick?.({ e });
};

const ChildNode = parseTNode(content) || parseTNode(children);

return (
<span className={tagClassNames} style={tagStyle} onClick={handleClick} ref={ref} {...other}>
<span className={`${baseClass}__icon`}>{icon}</span>
<span className={`${baseClass}__text`}>{getRenderContent() || children}</span>
{closable ? (
<span className={`${baseClass}__icon-close`} onClick={onClickClose}>
<span
className={tagClassNames}
style={tagStyle}
aria-disabled={props.disabled}
role="button"
onClick={handleClick}
ref={ref}
{...otherProps}
>
{icon && <span className={`${baseClass}__icon`}>{icon}</span>}
<span className={`${baseClass}__text`}>{ChildNode}</span>
{props.closable && (
<span className={`${baseClass}__icon-close`} onClick={handleClose}>
<Icon name="close" />
</span>
) : null}
)}
</span>
);
});

export default React.memo(Tag);
export default Tag;
Loading

0 comments on commit 862c5d5

Please sign in to comment.