Skip to content

Commit

Permalink
Merge pull request #838 from carolin913/develop
Browse files Browse the repository at this point in the history
feat(textarea): allowinputovermax支持超出字数限制可以输入
  • Loading branch information
honkinglin authored Jun 7, 2022
2 parents 61577ba + 8a73707 commit 15041ff
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 130 deletions.
2 changes: 0 additions & 2 deletions src/menu/__tests__/__snapshots__/menu.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,6 @@ exports[`double.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -972,7 +971,6 @@ exports[`double.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ exports[`close-all.jsx 1`] = `
exports[`content.jsx 1`] = `
<DocumentFragment>
<div
class="tdesign-demo-block-columns"
class="tdesign-demo-block-column"
>
<div
class="t-notification t-is-info"
Expand Down
2 changes: 1 addition & 1 deletion src/notification/_example/content.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Notification } from 'tdesign-react';

export default function NotificationExample() {
return (
<div className="tdesign-demo-block-columns">
<div className="tdesign-demo-block-column">
<Notification title="自定义内容(字符串)" content="这是一条消息通知" />
<Notification title="自定义内容" content={<div>这是一条消息通知</div>} />
</div>
Expand Down
12 changes: 6 additions & 6 deletions src/tabs/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ const TabBar: React.FC<TabBarProps> = (props) => {
const [barStyle, setBarStyle] = useState<CSSProperties>({});
const tabsClassPrefix = `${classPrefix}-tabs`;

const computeStyle = ({ tabPosition, activeId }) => {
const computeStyle = () => {
const isHorizontal = ['bottom', 'top'].includes(tabPosition);
const transformPosition = isHorizontal ? 'translateX' : 'translateY';
const itemProp = isHorizontal ? 'width' : 'height';
const barBorderProp = isHorizontal ? 'width' : 'height';

let offset = 0;

if (containerRef.current) {
const itemsRef = containerRef.current.querySelectorAll('.t-tabs__nav-item');

Expand Down Expand Up @@ -48,12 +49,11 @@ const TabBar: React.FC<TabBarProps> = (props) => {
};

useEffect(() => {
computeStyle({
tabPosition,
activeId,
});
if (containerRef.current) {
setTimeout(() => computeStyle());
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [tabPosition, activeId]);
}, [tabPosition, activeId, containerRef.current]);

return (
<div
Expand Down
8 changes: 0 additions & 8 deletions src/tabs/__tests__/__snapshots__/tabs.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ exports[`ban.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -175,7 +174,6 @@ exports[`base.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -320,7 +318,6 @@ exports[`combination.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -976,7 +973,6 @@ exports[`icon.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -1281,7 +1277,6 @@ exports[`position.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -1382,7 +1377,6 @@ exports[`size.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -1460,7 +1454,6 @@ exports[`size.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down Expand Up @@ -1547,7 +1540,6 @@ exports[`theme.jsx 1`] = `
>
<div
class="t-tabs__bar t-is-top"
style="transform: translateX(0px);"
/>
<div
class="t-tabs__bar t-is-top"
Expand Down
32 changes: 22 additions & 10 deletions src/textarea/Textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,23 @@ const Textarea = forwardRef((props: TextareaProps, ref: TextareaRefInterface) =>
autosize,
status,
tips,
allowInputOverMax,
...otherProps
} = props;

const [value = '', setValue] = useControlled(props, 'value', props.onChange);
const [isFocused, setIsFocused] = useState(false);
const [isOvermax, setIsOvermax] = useState(false);
const [textareaStyle, setTextareaStyle] = useState({});
const hasMaxcharacter = typeof maxcharacter !== 'undefined';
const textareaRef: React.RefObject<HTMLTextAreaElement> = useRef();
const wrapperRef: React.RefObject<HTMLDivElement> = useRef();
const currentLength = useMemo(() => (value ? String(value).length : 0), [value]);
const characterLength = useMemo(() => {
const characterInfo = getCharacterLength(String(value), maxcharacter);
const characterInfo = getCharacterLength(String(value), allowInputOverMax ? Infinity : maxcharacter);
if (typeof characterInfo === 'object') return characterInfo.length;
return characterInfo;
}, [value, maxcharacter]);
}, [value, allowInputOverMax, maxcharacter]);

const { classPrefix } = useConfig();

Expand Down Expand Up @@ -84,13 +86,20 @@ const Textarea = forwardRef((props: TextareaProps, ref: TextareaRefInterface) =>
function inputValueChangeHandle(e: React.FormEvent<HTMLTextAreaElement>) {
const { target } = e;
let val = (target as HTMLInputElement).value;
if (maxcharacter && maxcharacter >= 0) {
if (!allowInputOverMax && maxcharacter && maxcharacter >= 0) {
const stringInfo = getCharacterLength(val, maxcharacter);
val = typeof stringInfo === 'object' && stringInfo.characters;
}
setValue(val, { e });
}

const renderLimitText = (current: number, max: number) => (
<span className={`${classPrefix}-textarea__limit`}>
{isOvermax ? <span className={`${classPrefix}-textarea__tips--warning`}> {current}</span> : `${current}`}
{`/${max}`}
</span>
);

useEffect(() => {
// 当未设置 autosize 时,需要将 textarea 的 height 设置为 auto,以支持原生的 textarea rows 属性
if (autosize === false) {
Expand All @@ -102,6 +111,13 @@ const Textarea = forwardRef((props: TextareaProps, ref: TextareaRefInterface) =>
adjustTextareaHeight();
}, [adjustTextareaHeight, value]);

useEffect(() => {
if (allowInputOverMax) {
setIsOvermax(!!(maxlength && currentLength > maxlength) || !!(maxcharacter && characterLength > maxcharacter));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [characterLength]);

useImperativeHandle(ref as TextareaRefInterface, () => ({
currentElement: wrapperRef.current,
textareaElement: textareaRef.current,
Expand All @@ -118,19 +134,15 @@ const Textarea = forwardRef((props: TextareaProps, ref: TextareaRefInterface) =>
readOnly={readonly}
autoFocus={autofocus}
disabled={disabled}
maxLength={maxlength}
maxLength={allowInputOverMax ? Infinity : maxlength}
onChange={inputValueChangeHandle}
onKeyDown={(e) => onKeydown(e.currentTarget.value, { e })}
onKeyPress={(e) => onKeypress(e.currentTarget.value, { e })}
onKeyUp={(e) => onKeyup(e.currentTarget.value, { e })}
ref={textareaRef}
/>
{hasMaxcharacter ? (
<span className={`${classPrefix}-textarea__limit`}>{`${characterLength}/${maxcharacter}`}</span>
) : null}
{!hasMaxcharacter && maxlength ? (
<span className={`${classPrefix}-textarea__limit`}>{`${currentLength}/${maxlength}`}</span>
) : null}
{hasMaxcharacter && renderLimitText(characterLength, maxcharacter)}
{!hasMaxcharacter && maxlength && renderLimitText(currentLength, maxlength)}
{tips ? (
<div
className={classNames(`${classPrefix}-textarea__tips`, {
Expand Down
Loading

0 comments on commit 15041ff

Please sign in to comment.