316 lines
10 KiB
JavaScript
316 lines
10 KiB
JavaScript
|
"use client";
|
||
|
|
||
|
import { resetComponent, resetIcon, textEllipsis } from '../../style';
|
||
|
import { genCompactItemStyle } from '../../style/compact-item';
|
||
|
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||
|
import genDropdownStyle from './dropdown';
|
||
|
import genMultipleStyle from './multiple';
|
||
|
import genSingleStyle from './single';
|
||
|
// ============================= Selector =============================
|
||
|
const genSelectorStyle = token => {
|
||
|
const {
|
||
|
componentCls,
|
||
|
selectorBg
|
||
|
} = token;
|
||
|
return {
|
||
|
position: 'relative',
|
||
|
backgroundColor: selectorBg,
|
||
|
border: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`,
|
||
|
transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
|
||
|
input: {
|
||
|
cursor: 'pointer'
|
||
|
},
|
||
|
[`${componentCls}-show-search&`]: {
|
||
|
cursor: 'text',
|
||
|
input: {
|
||
|
cursor: 'auto',
|
||
|
color: 'inherit',
|
||
|
height: '100%'
|
||
|
}
|
||
|
},
|
||
|
[`${componentCls}-disabled&`]: {
|
||
|
color: token.colorTextDisabled,
|
||
|
background: token.colorBgContainerDisabled,
|
||
|
cursor: 'not-allowed',
|
||
|
[`${componentCls}-multiple&`]: {
|
||
|
background: token.multipleSelectorBgDisabled
|
||
|
},
|
||
|
input: {
|
||
|
cursor: 'not-allowed'
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
// ============================== Status ==============================
|
||
|
const genStatusStyle = function (rootSelectCls, token) {
|
||
|
let overwriteDefaultBorder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
||
|
const {
|
||
|
componentCls,
|
||
|
borderHoverColor,
|
||
|
outlineColor,
|
||
|
antCls
|
||
|
} = token;
|
||
|
const overwriteStyle = overwriteDefaultBorder ? {
|
||
|
[`${componentCls}-selector`]: {
|
||
|
borderColor: borderHoverColor
|
||
|
}
|
||
|
} : {};
|
||
|
return {
|
||
|
[rootSelectCls]: {
|
||
|
[`&:not(${componentCls}-disabled):not(${componentCls}-customize-input):not(${antCls}-pagination-size-changer)`]: Object.assign(Object.assign({}, overwriteStyle), {
|
||
|
[`${componentCls}-focused& ${componentCls}-selector`]: {
|
||
|
borderColor: borderHoverColor,
|
||
|
boxShadow: `0 0 0 ${token.controlOutlineWidth}px ${outlineColor}`,
|
||
|
outline: 0
|
||
|
},
|
||
|
[`&:hover ${componentCls}-selector`]: {
|
||
|
borderColor: borderHoverColor
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
// ============================== Styles ==============================
|
||
|
// /* Reset search input style */
|
||
|
const getSearchInputWithoutBorderStyle = token => {
|
||
|
const {
|
||
|
componentCls
|
||
|
} = token;
|
||
|
return {
|
||
|
[`${componentCls}-selection-search-input`]: {
|
||
|
margin: 0,
|
||
|
padding: 0,
|
||
|
background: 'transparent',
|
||
|
border: 'none',
|
||
|
outline: 'none',
|
||
|
appearance: 'none',
|
||
|
fontFamily: 'inherit',
|
||
|
'&::-webkit-search-cancel-button': {
|
||
|
display: 'none',
|
||
|
'-webkit-appearance': 'none'
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
// =============================== Base ===============================
|
||
|
const genBaseStyle = token => {
|
||
|
const {
|
||
|
antCls,
|
||
|
componentCls,
|
||
|
inputPaddingHorizontalBase,
|
||
|
iconCls
|
||
|
} = token;
|
||
|
return {
|
||
|
[componentCls]: Object.assign(Object.assign({}, resetComponent(token)), {
|
||
|
position: 'relative',
|
||
|
display: 'inline-block',
|
||
|
cursor: 'pointer',
|
||
|
[`&:not(${componentCls}-customize-input) ${componentCls}-selector`]: Object.assign(Object.assign({}, genSelectorStyle(token)), getSearchInputWithoutBorderStyle(token)),
|
||
|
// [`&:not(&-disabled):hover ${selectCls}-selector`]: {
|
||
|
// ...genHoverStyle(token),
|
||
|
// },
|
||
|
// ======================== Selection ========================
|
||
|
[`${componentCls}-selection-item`]: Object.assign(Object.assign({
|
||
|
flex: 1,
|
||
|
fontWeight: 'normal',
|
||
|
position: 'relative',
|
||
|
userSelect: 'none'
|
||
|
}, textEllipsis), {
|
||
|
// https://github.com/ant-design/ant-design/issues/40421
|
||
|
[`> ${antCls}-typography`]: {
|
||
|
display: 'inline'
|
||
|
}
|
||
|
}),
|
||
|
// ======================= Placeholder =======================
|
||
|
[`${componentCls}-selection-placeholder`]: Object.assign(Object.assign({}, textEllipsis), {
|
||
|
flex: 1,
|
||
|
color: token.colorTextPlaceholder,
|
||
|
pointerEvents: 'none'
|
||
|
}),
|
||
|
// ========================== Arrow ==========================
|
||
|
[`${componentCls}-arrow`]: Object.assign(Object.assign({}, resetIcon()), {
|
||
|
position: 'absolute',
|
||
|
top: '50%',
|
||
|
insetInlineStart: 'auto',
|
||
|
insetInlineEnd: inputPaddingHorizontalBase,
|
||
|
height: token.fontSizeIcon,
|
||
|
marginTop: -token.fontSizeIcon / 2,
|
||
|
color: token.colorTextQuaternary,
|
||
|
fontSize: token.fontSizeIcon,
|
||
|
lineHeight: 1,
|
||
|
textAlign: 'center',
|
||
|
pointerEvents: 'none',
|
||
|
display: 'flex',
|
||
|
alignItems: 'center',
|
||
|
[iconCls]: {
|
||
|
verticalAlign: 'top',
|
||
|
transition: `transform ${token.motionDurationSlow}`,
|
||
|
'> svg': {
|
||
|
verticalAlign: 'top'
|
||
|
},
|
||
|
[`&:not(${componentCls}-suffix)`]: {
|
||
|
pointerEvents: 'auto'
|
||
|
}
|
||
|
},
|
||
|
[`${componentCls}-disabled &`]: {
|
||
|
cursor: 'not-allowed'
|
||
|
},
|
||
|
'> *:not(:last-child)': {
|
||
|
marginInlineEnd: 8 // FIXME: magic
|
||
|
}
|
||
|
}),
|
||
|
|
||
|
// ========================== Clear ==========================
|
||
|
[`${componentCls}-clear`]: {
|
||
|
position: 'absolute',
|
||
|
top: '50%',
|
||
|
insetInlineStart: 'auto',
|
||
|
insetInlineEnd: inputPaddingHorizontalBase,
|
||
|
zIndex: 1,
|
||
|
display: 'inline-block',
|
||
|
width: token.fontSizeIcon,
|
||
|
height: token.fontSizeIcon,
|
||
|
marginTop: -token.fontSizeIcon / 2,
|
||
|
color: token.colorTextQuaternary,
|
||
|
fontSize: token.fontSizeIcon,
|
||
|
fontStyle: 'normal',
|
||
|
lineHeight: 1,
|
||
|
textAlign: 'center',
|
||
|
textTransform: 'none',
|
||
|
background: token.clearBg,
|
||
|
cursor: 'pointer',
|
||
|
opacity: 0,
|
||
|
transition: `color ${token.motionDurationMid} ease, opacity ${token.motionDurationSlow} ease`,
|
||
|
textRendering: 'auto',
|
||
|
'&:before': {
|
||
|
display: 'block'
|
||
|
},
|
||
|
'&:hover': {
|
||
|
color: token.colorTextTertiary
|
||
|
}
|
||
|
},
|
||
|
'&:hover': {
|
||
|
[`${componentCls}-clear`]: {
|
||
|
opacity: 1
|
||
|
}
|
||
|
}
|
||
|
}),
|
||
|
// ========================= Feedback ==========================
|
||
|
[`${componentCls}-has-feedback`]: {
|
||
|
[`${componentCls}-clear`]: {
|
||
|
insetInlineEnd: inputPaddingHorizontalBase + token.fontSize + token.paddingXS
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
};
|
||
|
// ============================== Styles ==============================
|
||
|
const genSelectStyle = token => {
|
||
|
const {
|
||
|
componentCls
|
||
|
} = token;
|
||
|
return [{
|
||
|
[componentCls]: {
|
||
|
// ==================== BorderLess ====================
|
||
|
[`&-borderless ${componentCls}-selector`]: {
|
||
|
backgroundColor: `transparent !important`,
|
||
|
borderColor: `transparent !important`,
|
||
|
boxShadow: `none !important`
|
||
|
},
|
||
|
// ==================== In Form ====================
|
||
|
[`&${componentCls}-in-form-item`]: {
|
||
|
width: '100%'
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
// =====================================================
|
||
|
// == LTR ==
|
||
|
// =====================================================
|
||
|
// Base
|
||
|
genBaseStyle(token),
|
||
|
// Single
|
||
|
genSingleStyle(token),
|
||
|
// Multiple
|
||
|
genMultipleStyle(token),
|
||
|
// Dropdown
|
||
|
genDropdownStyle(token),
|
||
|
// =====================================================
|
||
|
// == RTL ==
|
||
|
// =====================================================
|
||
|
{
|
||
|
[`${componentCls}-rtl`]: {
|
||
|
direction: 'rtl'
|
||
|
}
|
||
|
},
|
||
|
// =====================================================
|
||
|
// == Status ==
|
||
|
// =====================================================
|
||
|
genStatusStyle(componentCls, mergeToken(token, {
|
||
|
borderHoverColor: token.colorPrimaryHover,
|
||
|
outlineColor: token.controlOutline
|
||
|
})), genStatusStyle(`${componentCls}-status-error`, mergeToken(token, {
|
||
|
borderHoverColor: token.colorErrorHover,
|
||
|
outlineColor: token.colorErrorOutline
|
||
|
}), true), genStatusStyle(`${componentCls}-status-warning`, mergeToken(token, {
|
||
|
borderHoverColor: token.colorWarningHover,
|
||
|
outlineColor: token.colorWarningOutline
|
||
|
}), true),
|
||
|
// =====================================================
|
||
|
// == Space Compact ==
|
||
|
// =====================================================
|
||
|
genCompactItemStyle(token, {
|
||
|
borderElCls: `${componentCls}-selector`,
|
||
|
focusElCls: `${componentCls}-focused`
|
||
|
})];
|
||
|
};
|
||
|
// ============================== Export ==============================
|
||
|
export default genComponentStyleHook('Select', (token, _ref) => {
|
||
|
let {
|
||
|
rootPrefixCls
|
||
|
} = _ref;
|
||
|
const selectToken = mergeToken(token, {
|
||
|
rootPrefixCls,
|
||
|
inputPaddingHorizontalBase: token.paddingSM - 1,
|
||
|
multipleSelectItemHeight: token.multipleItemHeight,
|
||
|
selectHeight: token.controlHeight
|
||
|
});
|
||
|
return [genSelectStyle(selectToken)];
|
||
|
}, token => {
|
||
|
const {
|
||
|
fontSize,
|
||
|
lineHeight,
|
||
|
controlHeight,
|
||
|
controlPaddingHorizontal,
|
||
|
zIndexPopupBase,
|
||
|
colorText,
|
||
|
fontWeightStrong,
|
||
|
controlItemBgActive,
|
||
|
controlItemBgHover,
|
||
|
colorBgContainer,
|
||
|
colorFillSecondary,
|
||
|
controlHeightLG,
|
||
|
controlHeightSM,
|
||
|
colorBgContainerDisabled,
|
||
|
colorTextDisabled
|
||
|
} = token;
|
||
|
return {
|
||
|
zIndexPopup: zIndexPopupBase + 50,
|
||
|
optionSelectedColor: colorText,
|
||
|
optionSelectedFontWeight: fontWeightStrong,
|
||
|
optionSelectedBg: controlItemBgActive,
|
||
|
optionActiveBg: controlItemBgHover,
|
||
|
optionPadding: `${(controlHeight - fontSize * lineHeight) / 2}px ${controlPaddingHorizontal}px`,
|
||
|
optionFontSize: fontSize,
|
||
|
optionLineHeight: lineHeight,
|
||
|
optionHeight: controlHeight,
|
||
|
selectorBg: colorBgContainer,
|
||
|
clearBg: colorBgContainer,
|
||
|
singleItemHeightLG: controlHeightLG,
|
||
|
multipleItemBg: colorFillSecondary,
|
||
|
multipleItemBorderColor: 'transparent',
|
||
|
multipleItemHeight: controlHeightSM,
|
||
|
multipleItemHeightLG: controlHeight,
|
||
|
multipleSelectorBgDisabled: colorBgContainerDisabled,
|
||
|
multipleItemColorDisabled: colorTextDisabled,
|
||
|
multipleItemBorderColorDisabled: 'transparent'
|
||
|
};
|
||
|
});
|