diff --git a/components/input/ClearableLabeledInput.tsx b/components/input/ClearableLabeledInput.tsx index 09accd3fa..072019dd2 100644 --- a/components/input/ClearableLabeledInput.tsx +++ b/components/input/ClearableLabeledInput.tsx @@ -39,6 +39,7 @@ export default defineComponent({ triggerFocus: { type: Function as PropType<() => void> }, hidden: Boolean, status: String as PropType, + hashId: String, }, setup(props, { slots, attrs }) { const statusContext = FormItemInputContext.useInject(); @@ -73,6 +74,7 @@ export default defineComponent({ status: customStatus, addonAfter = slots.addonAfter, addonBefore = slots.addonBefore, + hashId, } = props; const { status: contextStatus, hasFeedback } = statusContext; @@ -96,6 +98,7 @@ export default defineComponent({ // className will go to addon wrapper [`${attrs.class}`]: !hasAddon({ addonAfter, addonBefore }) && attrs.class, }, + hashId, ); return ( , ); }; }, diff --git a/components/input/Input.tsx b/components/input/Input.tsx index 72b9a790b..a4eeb20bd 100644 --- a/components/input/Input.tsx +++ b/components/input/Input.tsx @@ -14,6 +14,9 @@ import inputProps from './inputProps'; import omit from '../_util/omit'; import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; +// CSSINJS +import useStyle from './style'; + export default defineComponent({ compatConfig: { MODE: 3 }, name: 'AInput', @@ -26,6 +29,9 @@ export default defineComponent({ const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status)); const { direction, prefixCls, size, autocomplete } = useConfigInject('input', props); + // Style + const [wrapSSR, hashId] = useStyle(prefixCls); + const focus = (option?: InputFocusOptions) => { inputRef.value?.focus(option); }; @@ -117,7 +123,7 @@ export default defineComponent({ const prefixClsValue = prefixCls.value; const inputHasPrefixSuffix = hasPrefixSuffix({ prefix, suffix }) || !!hasFeedback; const clearIcon = slots.clearIcon || (() => ); - return ( + return wrapSSR( + >, ); }; }, diff --git a/components/input/TextArea.tsx b/components/input/TextArea.tsx index 0ddc73c57..1863c6882 100644 --- a/components/input/TextArea.tsx +++ b/components/input/TextArea.tsx @@ -21,6 +21,9 @@ import omit from '../_util/omit'; import type { VueNode } from '../_util/type'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +// CSSINJS +import useStyle from './style'; + function fixEmojiLength(value: string, maxLength: number) { return [...(value || '')].slice(0, maxLength).join(''); } @@ -58,6 +61,10 @@ export default defineComponent({ const resizableTextArea = ref(); const mergedValue = ref(''); const { prefixCls, size, direction } = useConfigInject('input', props); + + // Style + const [wrapSSR, hashId] = useStyle(prefixCls); + const showCount = computed(() => { return (props.showCount as any) === '' || props.showCount || false; }); @@ -198,6 +205,7 @@ export default defineComponent({ [`${prefixCls.value}-lg`]: size.value === 'large', }, getStatusClassNames(prefixCls.value, mergedStatus.value), + hashId.value, ], showCount: null, prefixCls: prefixCls.value, @@ -252,6 +260,7 @@ export default defineComponent({ direction: direction.value, bordered, style: showCount.value ? undefined : style, + hashId: hashId.value, }; let textareaNode = ( @@ -283,6 +292,7 @@ export default defineComponent({ }, `${prefixCls.value}-textarea-show-count`, customClass, + hashId.value, )} style={style as CSSProperties} data-count={typeof dataCount !== 'object' ? dataCount : undefined} @@ -296,7 +306,7 @@ export default defineComponent({ ); } - return textareaNode; + return wrapSSR(textareaNode); }; }, }); diff --git a/components/input/style/index.tsx b/components/input/style/index.tsx index 40150302b..edbcb16dd 100644 --- a/components/input/style/index.tsx +++ b/components/input/style/index.tsx @@ -1,6 +1,941 @@ -import '../../style/index.less'; -import './index.less'; +import type { CSSObject } from '../../_util/cssinjs'; +import type { FullToken, GenerateStyle } from '../../theme/internal'; +import { genComponentStyleHook, mergeToken } from '../../theme/internal'; +import type { GlobalToken } from '../../theme/interface'; +import { clearFix, resetComponent } from '../../_style'; +import { genCompactItemStyle } from '../../_style/compact-item'; -// deps-lint-skip: form -// style dependencies -import '../../button/style'; +export type InputToken> = T & { + inputAffixPadding: number; + inputPaddingVertical: number; + inputPaddingVerticalLG: number; + inputPaddingVerticalSM: number; + inputPaddingHorizontal: number; + inputPaddingHorizontalLG: number; + inputPaddingHorizontalSM: number; + inputBorderHoverColor: string; + inputBorderActiveColor: string; +}; + +export const genPlaceholderStyle = (color: string): CSSObject => ({ + // Firefox + '&::-moz-placeholder': { + opacity: 1, + }, + '&::placeholder': { + color, + userSelect: 'none', // https://github.com/ant-design/ant-design/pull/32639 + }, + '&:placeholder-shown': { + textOverflow: 'ellipsis', + }, +}); + +export const genHoverStyle = (token: InputToken): CSSObject => ({ + borderColor: token.inputBorderHoverColor, + borderInlineEndWidth: token.lineWidth, +}); + +export const genActiveStyle = (token: InputToken) => ({ + borderColor: token.inputBorderHoverColor, + boxShadow: `0 0 0 ${token.controlOutlineWidth}px ${token.controlOutline}`, + borderInlineEndWidth: token.lineWidth, + outline: 0, +}); + +export const genDisabledStyle = (token: InputToken): CSSObject => ({ + color: token.colorTextDisabled, + backgroundColor: token.colorBgContainerDisabled, + borderColor: token.colorBorder, + boxShadow: 'none', + cursor: 'not-allowed', + opacity: 1, + + '&:hover': { + ...genHoverStyle(mergeToken(token, { inputBorderHoverColor: token.colorBorder })), + }, +}); + +const genInputLargeStyle = (token: InputToken): CSSObject => { + const { + inputPaddingVerticalLG, + fontSizeLG, + lineHeightLG, + borderRadiusLG, + inputPaddingHorizontalLG, + } = token; + + return { + padding: `${inputPaddingVerticalLG}px ${inputPaddingHorizontalLG}px`, + fontSize: fontSizeLG, + lineHeight: lineHeightLG, + borderRadius: borderRadiusLG, + }; +}; + +export const genInputSmallStyle = (token: InputToken): CSSObject => ({ + padding: `${token.inputPaddingVerticalSM}px ${token.controlPaddingHorizontalSM - 1}px`, + borderRadius: token.borderRadiusSM, +}); + +export const genStatusStyle = (token: InputToken, parentCls: string): CSSObject => { + const { + componentCls, + colorError, + colorWarning, + colorErrorOutline, + colorWarningOutline, + colorErrorBorderHover, + colorWarningBorderHover, + } = token; + + return { + [`&-status-error:not(${parentCls}-disabled):not(${parentCls}-borderless)${parentCls}`]: { + borderColor: colorError, + + '&:hover': { + borderColor: colorErrorBorderHover, + }, + + '&:focus, &-focused': { + ...genActiveStyle( + mergeToken(token, { + inputBorderActiveColor: colorError, + inputBorderHoverColor: colorError, + controlOutline: colorErrorOutline, + }), + ), + }, + + [`${componentCls}-prefix`]: { + color: colorError, + }, + }, + [`&-status-warning:not(${parentCls}-disabled):not(${parentCls}-borderless)${parentCls}`]: { + borderColor: colorWarning, + + '&:hover': { + borderColor: colorWarningBorderHover, + }, + + '&:focus, &-focused': { + ...genActiveStyle( + mergeToken(token, { + inputBorderActiveColor: colorWarning, + inputBorderHoverColor: colorWarning, + controlOutline: colorWarningOutline, + }), + ), + }, + + [`${componentCls}-prefix`]: { + color: colorWarning, + }, + }, + }; +}; + +export const genBasicInputStyle = (token: InputToken): CSSObject => ({ + position: 'relative', + display: 'inline-block', + width: '100%', + minWidth: 0, + padding: `${token.inputPaddingVertical}px ${token.inputPaddingHorizontal}px`, + color: token.colorText, + fontSize: token.fontSize, + lineHeight: token.lineHeight, + backgroundColor: token.colorBgContainer, + backgroundImage: 'none', + borderWidth: token.lineWidth, + borderStyle: token.lineType, + borderColor: token.colorBorder, + borderRadius: token.borderRadius, + transition: `all ${token.motionDurationMid}`, + ...genPlaceholderStyle(token.colorTextPlaceholder), + + '&:hover': { + ...genHoverStyle(token), + }, + + '&:focus, &-focused': { + ...genActiveStyle(token), + }, + + '&-disabled, &[disabled]': { + ...genDisabledStyle(token), + }, + + '&-borderless': { + '&, &:hover, &:focus, &-focused, &-disabled, &[disabled]': { + backgroundColor: 'transparent', + border: 'none', + boxShadow: 'none', + }, + }, + + // Reset height for `textarea`s + 'textarea&': { + maxWidth: '100%', // prevent textearea resize from coming out of its container + height: 'auto', + minHeight: token.controlHeight, + lineHeight: token.lineHeight, + verticalAlign: 'bottom', + transition: `all ${token.motionDurationSlow}, height 0s`, + resize: 'vertical', + }, + + // Size + '&-lg': { + ...genInputLargeStyle(token), + }, + '&-sm': { + ...genInputSmallStyle(token), + }, + + // RTL + '&-rtl': { + direction: 'rtl', + }, + + '&-textarea-rtl': { + direction: 'rtl', + }, +}); + +export const genInputGroupStyle = (token: InputToken): CSSObject => { + const { componentCls, antCls } = token; + + return { + position: 'relative', + display: 'table', + width: '100%', + borderCollapse: 'separate', + borderSpacing: 0, + + // Undo padding and float of grid classes + [`&[class*='col-']`]: { + paddingInlineEnd: token.paddingXS, + + '&:last-child': { + paddingInlineEnd: 0, + }, + }, + + // Sizing options + [`&-lg ${componentCls}, &-lg > ${componentCls}-group-addon`]: { + ...genInputLargeStyle(token), + }, + + [`&-sm ${componentCls}, &-sm > ${componentCls}-group-addon`]: { + ...genInputSmallStyle(token), + }, + + // Fix https://github.com/ant-design/ant-design/issues/5754 + [`&-lg ${antCls}-select-single ${antCls}-select-selector`]: { + height: token.controlHeightLG, + }, + + [`&-sm ${antCls}-select-single ${antCls}-select-selector`]: { + height: token.controlHeightSM, + }, + + [`> ${componentCls}`]: { + display: 'table-cell', + + '&:not(:first-child):not(:last-child)': { + borderRadius: 0, + }, + }, + + [`${componentCls}-group`]: { + [`&-addon, &-wrap`]: { + display: 'table-cell', + width: 1, + whiteSpace: 'nowrap', + verticalAlign: 'middle', + + '&:not(:first-child):not(:last-child)': { + borderRadius: 0, + }, + }, + + '&-wrap > *': { + display: 'block !important', + }, + + '&-addon': { + position: 'relative', + padding: `0 ${token.inputPaddingHorizontal}px`, + color: token.colorText, + fontWeight: 'normal', + fontSize: token.fontSize, + textAlign: 'center', + backgroundColor: token.colorFillAlter, + border: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`, + borderRadius: token.borderRadius, + transition: `all ${token.motionDurationSlow}`, + lineHeight: 1, + + // Reset Select's style in addon + [`${antCls}-select`]: { + margin: `-${token.inputPaddingVertical + 1}px -${token.inputPaddingHorizontal}px`, + + [`&${antCls}-select-single:not(${antCls}-select-customize-input)`]: { + [`${antCls}-select-selector`]: { + backgroundColor: 'inherit', + border: `${token.lineWidth}px ${token.lineType} transparent`, + boxShadow: 'none', + }, + }, + + '&-open, &-focused': { + [`${antCls}-select-selector`]: { + color: token.colorPrimary, + }, + }, + }, + + // https://github.com/ant-design/ant-design/issues/31333 + [`${antCls}-cascader-picker`]: { + margin: `-9px -${token.inputPaddingHorizontal}px`, + backgroundColor: 'transparent', + [`${antCls}-cascader-input`]: { + textAlign: 'start', + border: 0, + boxShadow: 'none', + }, + }, + }, + + '&-addon:first-child': { + borderInlineEnd: 0, + }, + + '&-addon:last-child': { + borderInlineStart: 0, + }, + }, + + [`${componentCls}`]: { + float: 'inline-start', + width: '100%', + marginBottom: 0, + textAlign: 'inherit', + + '&:focus': { + zIndex: 1, // Fix https://gw.alipayobjects.com/zos/rmsportal/DHNpoqfMXSfrSnlZvhsJ.png + borderInlineEndWidth: 1, + }, + + '&:hover': { + zIndex: 1, + borderInlineEndWidth: 1, + + [`${componentCls}-search-with-button &`]: { + zIndex: 0, + }, + }, + }, + + // Reset rounded corners + [`> ${componentCls}:first-child, ${componentCls}-group-addon:first-child`]: { + borderStartEndRadius: 0, + borderEndEndRadius: 0, + + // Reset Select's style in addon + [`${antCls}-select ${antCls}-select-selector`]: { + borderStartEndRadius: 0, + borderEndEndRadius: 0, + }, + }, + + [`> ${componentCls}-affix-wrapper`]: { + [`&:not(:first-child) ${componentCls}`]: { + borderStartStartRadius: 0, + borderEndStartRadius: 0, + }, + + [`&:not(:last-child) ${componentCls}`]: { + borderStartEndRadius: 0, + borderEndEndRadius: 0, + }, + }, + + [`> ${componentCls}:last-child, ${componentCls}-group-addon:last-child`]: { + borderStartStartRadius: 0, + borderEndStartRadius: 0, + + // Reset Select's style in addon + [`${antCls}-select ${antCls}-select-selector`]: { + borderStartStartRadius: 0, + borderEndStartRadius: 0, + }, + }, + + [`${componentCls}-affix-wrapper`]: { + '&:not(:last-child)': { + borderStartEndRadius: 0, + borderEndEndRadius: 0, + [`${componentCls}-search &`]: { + borderStartStartRadius: token.borderRadius, + borderEndStartRadius: token.borderRadius, + }, + }, + + [`&:not(:first-child), ${componentCls}-search &:not(:first-child)`]: { + borderStartStartRadius: 0, + borderEndStartRadius: 0, + }, + }, + + [`&${componentCls}-group-compact`]: { + display: 'block', + ...clearFix(), + + [`${componentCls}-group-addon, ${componentCls}-group-wrap, > ${componentCls}`]: { + '&:not(:first-child):not(:last-child)': { + borderInlineEndWidth: token.lineWidth, + + '&:hover': { + zIndex: 1, + }, + + '&:focus': { + zIndex: 1, + }, + }, + }, + + '& > *': { + display: 'inline-block', + float: 'none', + verticalAlign: 'top', // https://github.com/ant-design/ant-design-pro/issues/139 + borderRadius: 0, + }, + + [`& > ${componentCls}-affix-wrapper`]: { + display: 'inline-flex', + }, + + [`& > ${antCls}-picker-range`]: { + display: 'inline-flex', + }, + + '& > *:not(:last-child)': { + marginInlineEnd: -token.lineWidth, + borderInlineEndWidth: token.lineWidth, + }, + + // Undo float for .ant-input-group .ant-input + [`${componentCls}`]: { + float: 'none', + }, + + // reset border for Select, DatePicker, AutoComplete, Cascader, Mention, TimePicker, Input + [`& > ${antCls}-select > ${antCls}-select-selector, + & > ${antCls}-select-auto-complete ${componentCls}, + & > ${antCls}-cascader-picker ${componentCls}, + & > ${componentCls}-group-wrapper ${componentCls}`]: { + borderInlineEndWidth: token.lineWidth, + borderRadius: 0, + + '&:hover': { + zIndex: 1, + }, + + '&:focus': { + zIndex: 1, + }, + }, + + [`& > ${antCls}-select-focused`]: { + zIndex: 1, + }, + + // update z-index for arrow icon + [`& > ${antCls}-select > ${antCls}-select-arrow`]: { + zIndex: 1, // https://github.com/ant-design/ant-design/issues/20371 + }, + + [`& > *:first-child, + & > ${antCls}-select:first-child > ${antCls}-select-selector, + & > ${antCls}-select-auto-complete:first-child ${componentCls}, + & > ${antCls}-cascader-picker:first-child ${componentCls}`]: { + borderStartStartRadius: token.borderRadius, + borderEndStartRadius: token.borderRadius, + }, + + [`& > *:last-child, + & > ${antCls}-select:last-child > ${antCls}-select-selector, + & > ${antCls}-cascader-picker:last-child ${componentCls}, + & > ${antCls}-cascader-picker-focused:last-child ${componentCls}`]: { + borderInlineEndWidth: token.lineWidth, + borderStartEndRadius: token.borderRadius, + borderEndEndRadius: token.borderRadius, + }, + + // https://github.com/ant-design/ant-design/issues/12493 + [`& > ${antCls}-select-auto-complete ${componentCls}`]: { + verticalAlign: 'top', + }, + + [`${componentCls}-group-wrapper + ${componentCls}-group-wrapper`]: { + marginInlineStart: -token.lineWidth, + [`${componentCls}-affix-wrapper`]: { + borderRadius: 0, + }, + }, + + [`${componentCls}-group-wrapper:not(:last-child)`]: { + [`&${componentCls}-search > ${componentCls}-group`]: { + [`& > ${componentCls}-group-addon > ${componentCls}-search-button`]: { + borderRadius: 0, + }, + + [`& > ${componentCls}`]: { + borderStartStartRadius: token.borderRadius, + borderStartEndRadius: 0, + borderEndEndRadius: 0, + borderEndStartRadius: token.borderRadius, + }, + }, + }, + }, + }; +}; + +const genInputStyle: GenerateStyle = (token: InputToken) => { + const { componentCls, controlHeightSM, lineWidth } = token; + + const FIXED_CHROME_COLOR_HEIGHT = 16; + const colorSmallPadding = (controlHeightSM - lineWidth * 2 - FIXED_CHROME_COLOR_HEIGHT) / 2; + + return { + [componentCls]: { + ...resetComponent(token), + ...genBasicInputStyle(token), + ...genStatusStyle(token, componentCls), + + '&[type="color"]': { + height: token.controlHeight, + + [`&${componentCls}-lg`]: { + height: token.controlHeightLG, + }, + [`&${componentCls}-sm`]: { + height: controlHeightSM, + paddingTop: colorSmallPadding, + paddingBottom: colorSmallPadding, + }, + }, + }, + }; +}; + +const genAllowClearStyle = (token: InputToken): CSSObject => { + const { componentCls } = token; + return { + // ========================= Input ========================= + [`${componentCls}-clear-icon`]: { + margin: 0, + color: token.colorTextQuaternary, + fontSize: token.fontSizeIcon, + verticalAlign: -1, + // https://github.com/ant-design/ant-design/pull/18151 + // https://codesandbox.io/s/wizardly-sun-u10br + cursor: 'pointer', + transition: `color ${token.motionDurationSlow}`, + + '&:hover': { + color: token.colorTextTertiary, + }, + + '&:active': { + color: token.colorText, + }, + + '&-hidden': { + visibility: 'hidden', + }, + + '&-has-suffix': { + margin: `0 ${token.inputAffixPadding}px`, + }, + }, + + // ======================= TextArea ======================== + '&-textarea-with-clear-btn': { + padding: '0 !important', + border: '0 !important', + + [`${componentCls}-clear-icon`]: { + position: 'absolute', + insetBlockStart: token.paddingXS, + insetInlineEnd: token.paddingXS, + zIndex: 1, + }, + }, + }; +}; + +const genAffixStyle: GenerateStyle = (token: InputToken) => { + const { + componentCls, + inputAffixPadding, + colorTextDescription, + motionDurationSlow, + colorIcon, + colorIconHover, + iconCls, + } = token; + + return { + [`${componentCls}-affix-wrapper`]: { + ...genBasicInputStyle(token), + display: 'inline-flex', + + [`&:not(${componentCls}-affix-wrapper-disabled):hover`]: { + ...genHoverStyle(token), + zIndex: 1, + [`${componentCls}-search-with-button &`]: { + zIndex: 0, + }, + }, + + '&-focused, &:focus': { + zIndex: 1, + }, + + '&-disabled': { + [`${componentCls}[disabled]`]: { + background: 'transparent', + }, + }, + + [`> input${componentCls}`]: { + padding: 0, + fontSize: 'inherit', + border: 'none', + borderRadius: 0, + outline: 'none', + + '&:focus': { + boxShadow: 'none !important', + }, + }, + + '&::before': { + width: 0, + visibility: 'hidden', + content: '"\\a0"', + }, + + [`${componentCls}`]: { + '&-prefix, &-suffix': { + display: 'flex', + flex: 'none', + alignItems: 'center', + + '> *:not(:last-child)': { + marginInlineEnd: token.paddingXS, + }, + }, + + '&-show-count-suffix': { + color: colorTextDescription, + }, + + '&-show-count-has-suffix': { + marginInlineEnd: token.paddingXXS, + }, + + '&-prefix': { + marginInlineEnd: inputAffixPadding, + }, + + '&-suffix': { + marginInlineStart: inputAffixPadding, + }, + }, + + ...genAllowClearStyle(token), + + // password + [`${iconCls}${componentCls}-password-icon`]: { + color: colorIcon, + cursor: 'pointer', + transition: `all ${motionDurationSlow}`, + + '&:hover': { + color: colorIconHover, + }, + }, + + // status + ...genStatusStyle(token, `${componentCls}-affix-wrapper`), + }, + }; +}; + +const genGroupStyle: GenerateStyle = (token: InputToken) => { + const { componentCls, colorError, colorSuccess, borderRadiusLG, borderRadiusSM } = token; + + return { + [`${componentCls}-group`]: { + // Style for input-group: input with label, with button or dropdown... + ...resetComponent(token), + ...genInputGroupStyle(token), + + '&-rtl': { + direction: 'rtl', + }, + + '&-wrapper': { + display: 'inline-block', + width: '100%', + textAlign: 'start', + verticalAlign: 'top', // https://github.com/ant-design/ant-design/issues/6403 + + '&-rtl': { + direction: 'rtl', + }, + + // Size + '&-lg': { + [`${componentCls}-group-addon`]: { + borderRadius: borderRadiusLG, + }, + }, + '&-sm': { + [`${componentCls}-group-addon`]: { + borderRadius: borderRadiusSM, + }, + }, + + // Status + '&-status-error': { + [`${componentCls}-group-addon`]: { + color: colorError, + borderColor: colorError, + }, + }, + '&-status-warning': { + [`${componentCls}-group-addon:last-child`]: { + color: colorSuccess, + borderColor: colorSuccess, + }, + }, + }, + }, + }; +}; + +const genSearchInputStyle: GenerateStyle = (token: InputToken) => { + const { componentCls, antCls } = token; + const searchPrefixCls = `${componentCls}-search`; + return { + [searchPrefixCls]: { + [`${componentCls}`]: { + '&:hover, &:focus': { + borderColor: token.colorPrimaryHover, + + [`+ ${componentCls}-group-addon ${searchPrefixCls}-button:not(${antCls}-btn-primary)`]: { + borderInlineStartColor: token.colorPrimaryHover, + }, + }, + }, + + [`${componentCls}-affix-wrapper`]: { + borderRadius: 0, + }, + + // fix slight height diff in Firefox: + // https://ant.design/components/auto-complete-cn/#components-auto-complete-demo-certain-category + [`${componentCls}-lg`]: { + lineHeight: token.lineHeightLG - 0.0002, + }, + + [`> ${componentCls}-group`]: { + [`> ${componentCls}-group-addon:last-child`]: { + insetInlineStart: -1, + padding: 0, + border: 0, + + [`${searchPrefixCls}-button`]: { + paddingTop: 0, + paddingBottom: 0, + borderStartStartRadius: 0, + borderStartEndRadius: token.borderRadius, + borderEndEndRadius: token.borderRadius, + borderEndStartRadius: 0, + }, + + [`${searchPrefixCls}-button:not(${antCls}-btn-primary)`]: { + color: token.colorTextDescription, + + '&:hover': { + color: token.colorPrimaryHover, + }, + + '&:active': { + color: token.colorPrimaryActive, + }, + + [`&${antCls}-btn-loading::before`]: { + insetInlineStart: 0, + insetInlineEnd: 0, + insetBlockStart: 0, + insetBlockEnd: 0, + }, + }, + }, + }, + + [`${searchPrefixCls}-button`]: { + height: token.controlHeight, + + '&:hover, &:focus': { + zIndex: 1, + }, + }, + + [`&-large ${searchPrefixCls}-button`]: { + height: token.controlHeightLG, + }, + + [`&-small ${searchPrefixCls}-button`]: { + height: token.controlHeightSM, + }, + + '&-rtl': { + direction: 'rtl', + }, + + // ===================== Compact Item Customized Styles ===================== + [`&${componentCls}-compact-item`]: { + [`&:not(${componentCls}-compact-last-item)`]: { + [`${componentCls}-group-addon`]: { + [`${componentCls}-search-button`]: { + marginInlineEnd: -token.lineWidth, + borderRadius: 0, + }, + }, + }, + + [`&:not(${componentCls}-compact-first-item)`]: { + [`${componentCls},${componentCls}-affix-wrapper`]: { + borderRadius: 0, + }, + }, + + [`> ${componentCls}-group-addon ${componentCls}-search-button, + > ${componentCls}, + ${componentCls}-affix-wrapper`]: { + '&:hover,&:focus,&:active': { + zIndex: 2, + }, + }, + + [`> ${componentCls}-affix-wrapper-focused`]: { + zIndex: 2, + }, + }, + }, + }; +}; + +export function initInputToken(token: T): InputToken { + // @ts-ignore + return mergeToken>(token, { + inputAffixPadding: token.paddingXXS, + inputPaddingVertical: Math.max( + Math.round(((token.controlHeight - token.fontSize * token.lineHeight) / 2) * 10) / 10 - + token.lineWidth, + 3, + ), + inputPaddingVerticalLG: + Math.ceil(((token.controlHeightLG - token.fontSizeLG * token.lineHeightLG) / 2) * 10) / 10 - + token.lineWidth, + inputPaddingVerticalSM: Math.max( + Math.round(((token.controlHeightSM - token.fontSize * token.lineHeight) / 2) * 10) / 10 - + token.lineWidth, + 0, + ), + inputPaddingHorizontal: token.paddingSM - token.lineWidth, + inputPaddingHorizontalSM: token.paddingXS - token.lineWidth, + inputPaddingHorizontalLG: token.controlPaddingHorizontal - token.lineWidth, + inputBorderHoverColor: token.colorPrimaryHover, + inputBorderActiveColor: token.colorPrimaryHover, + }); +} + +const genTextAreaStyle: GenerateStyle = token => { + const { componentCls, inputPaddingHorizontal, paddingLG } = token; + const textareaPrefixCls = `${componentCls}-textarea`; + + return { + [textareaPrefixCls]: { + position: 'relative', + + [`${textareaPrefixCls}-suffix`]: { + position: 'absolute', + top: 0, + insetInlineEnd: inputPaddingHorizontal, + bottom: 0, + zIndex: 1, + display: 'inline-flex', + alignItems: 'center', + margin: 'auto', + }, + + [`&-status-error, + &-status-warning, + &-status-success, + &-status-validating`]: { + [`&${textareaPrefixCls}-has-feedback`]: { + [`${componentCls}`]: { + paddingInlineEnd: paddingLG, + }, + }, + }, + + '&-show-count': { + // https://github.com/ant-design/ant-design/issues/33049 + [`> ${componentCls}`]: { + height: '100%', + }, + + '&::after': { + color: token.colorTextDescription, + whiteSpace: 'nowrap', + content: 'attr(data-count)', + pointerEvents: 'none', + float: 'right', + }, + }, + + '&-rtl': { + '&::after': { + float: 'left', + }, + }, + }, + }; +}; + +// ============================== Export ============================== +export default genComponentStyleHook('Input', token => { + const inputToken = initInputToken>(token); + + return [ + genInputStyle(inputToken), + genTextAreaStyle(inputToken), + genAffixStyle(inputToken), + genGroupStyle(inputToken), + genSearchInputStyle(inputToken), + // ===================================================== + // == Space Compact == + // ===================================================== + genCompactItemStyle(inputToken), + ]; +}); diff --git a/components/style.ts b/components/style.ts index 7a657849b..98a893200 100644 --- a/components/style.ts +++ b/components/style.ts @@ -9,7 +9,7 @@ import './pagination/style'; // import './avatar/style'; // import './badge/style'; import './tabs/style'; -import './input/style'; +// import './input/style'; // import './tooltip/style'; // import './popover/style'; // import './popconfirm/style';