feat: css-in-js for Space.Compact (#38227)

* feat: css-in-js for Space.Compact

* chore: remove useless less files

* fix: lint issue

* refactor: improve code style

* chore: add bundlesize
This commit is contained in:
Yuki Zhang 2022-10-28 16:09:38 +08:00 committed by GitHub
parent 5913a707ab
commit 87b1a32aca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 269 additions and 331 deletions

View File

@ -3,6 +3,8 @@ import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import genGroupStyle from './group';
import { genFocusStyle } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {}
@ -51,6 +53,50 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
'&:not(:disabled)': {
...genFocusStyle(token),
},
...genCompactItemStyle(token, componentCls),
...genCompactItemVerticalStyle(token, componentCls),
// make `btn-icon-only` not too narrow
'&-icon-only&-compact-item': {
flex: 'none',
},
// Special styles for Primary Button
[`&-compact-item${componentCls}-primary`]: {
'&:not([disabled]) + &:not([disabled])': {
position: 'relative',
'&:after': {
position: 'absolute',
top: -token.controlLineWidth,
insetInlineStart: -token.controlLineWidth,
display: 'inline-block',
width: token.controlLineWidth,
height: `calc(100% + ${token.controlLineWidth * 2}px)`,
backgroundColor: token.colorPrimaryBorder,
content: '""',
},
},
},
// Special styles for Primary Button
'&-compact-vertical-item': {
[`&${componentCls}-primary`]: {
'&:not([disabled]) + &:not([disabled])': {
position: 'relative',
'&:after': {
position: 'absolute',
top: -token.controlLineWidth,
insetInlineStart: -token.controlLineWidth,
display: 'inline-block',
width: `calc(100% + ${token.controlLineWidth * 2}px)`,
height: token.controlLineWidth,
backgroundColor: token.colorPrimaryBorder,
content: '""',
},
},
},
},
},
};
};

View File

@ -1,88 +0,0 @@
@import '../../style/mixins/index';
@btn-prefix-cls: ~'@{ant-prefix}-btn';
// Button in Space.Compact
.@{btn-prefix-cls} {
.compact-item(@btn-prefix-cls);
// make `btn-icon-only` not too narrow
&-icon-only&-compact-item {
flex: none;
}
// Special styles for Primary Button
&-compact-item.@{btn-prefix-cls}-primary {
&:not([disabled]) + &:not([disabled]) {
position: relative;
&::after {
position: absolute;
top: -@border-width-base;
left: -@border-width-base;
display: inline-block;
width: @border-width-base;
height: calc(100% + @border-width-base * 2);
background-color: @btn-group-border;
content: ' ';
}
}
}
// ----------RTL----------
&-compact-item-rtl {
&.@{btn-prefix-cls}-compact-first-item&:not(.@{btn-prefix-cls}-compact-last-item) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
&.@{btn-prefix-cls}-compact-last-item&:not(.@{btn-prefix-cls}-compact-first-item) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&.@{btn-prefix-cls}-sm {
&.@{btn-prefix-cls}-compact-first-item&:not(.@{btn-prefix-cls}-compact-last-item) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
&.@{btn-prefix-cls}-compact-last-item&:not(.@{btn-prefix-cls}-compact-first-item) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
// ----------RTL Special styles for Primary Button----------
&.@{btn-prefix-cls}-primary {
&:not([disabled]) + &:not([disabled]) {
&::after {
right: -@border-width-base;
}
}
}
}
// Button in Space.Compact when direction=vertical
.compact-item-vertical(@btn-prefix-cls);
// Special styles for Primary Button
&-compact-vertical-item {
&.@{btn-prefix-cls}-primary {
&:not([disabled]) + &:not([disabled]) {
position: relative;
&::after {
position: absolute;
top: -@border-width-base;
left: -@border-width-base;
display: inline-block;
width: calc(100% + @border-width-base * 2);
height: @border-width-base;
background-color: @btn-group-border;
content: ' ';
}
}
}
}
}

View File

@ -1,6 +1,7 @@
import { getStyle as getCheckboxStyle } from '../../checkbox/style';
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook } from '../../theme';
import { genCompactItemStyle } from '../../style/compact-item';
export interface ComponentToken {
controlWidth: number;
@ -30,9 +31,9 @@ const genBaseStyle: GenerateStyle<CascaderToken> = token => {
{
[componentCls]: {
width: token.controlWidth,
...genCompactItemStyle(token, componentCls),
},
},
// =====================================================
// == Popup ==
// =====================================================

View File

@ -13,6 +13,7 @@ import { genComponentStyleHook, mergeToken } from '../../theme';
import type { GlobalToken } from '../../theme/interface';
import type { TokenWithCommonCls } from '../../theme/util/genComponentStyleHook';
import { resetComponent, roundedArrow } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
export interface ComponentToken {
zIndexPopup: number;
@ -848,6 +849,8 @@ const genPickerStyle: GenerateStyle<PickerToken> = token => {
border: `${token.controlLineWidth}px ${token.controlLineType} ${token.colorBorder}`,
borderRadius: token.controlRadius,
transition: `border ${token.motionDurationFast}, box-shadow ${token.motionDurationFast}`,
// Space.Compact
...genCompactItemStyle(token, componentCls, '', `${componentCls}-focused`),
'&:hover, &-focused': {
...genHoverStyle(token),

View File

@ -12,6 +12,7 @@ import {
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook } from '../../theme';
import { resetComponent, resetIcon } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
export interface ComponentToken {
controlWidth: number;
@ -63,6 +64,8 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
border: `${controlLineWidth}px ${controlLineType} ${colorBorder}`,
borderRadius: controlRadius,
...genCompactItemStyle(token, componentCls),
'&-rtl': {
direction: 'rtl',

View File

@ -3,6 +3,7 @@ import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook, mergeToken } from '../../theme';
import type { GlobalToken } from '../../theme/interface';
import { clearFix, resetComponent } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
export type InputToken<T extends GlobalToken = FullToken<'Input'>> = T & {
inputAffixPadding: number;
@ -506,6 +507,7 @@ const genInputStyle: GenerateStyle<InputToken> = (token: InputToken) => {
...resetComponent(token),
...genBasicInputStyle(token),
...genStatusStyle(token),
...genCompactItemStyle(token, prefixCls),
'&[type="color"]': {
height: token.controlHeight,
@ -802,6 +804,36 @@ const genSearchInputStyle: GenerateStyle<InputToken> = (token: InputToken) => {
'&-rtl': {
direction: 'rtl',
},
// ===================== Compact Item Customized Styles =====================
[`&.${prefixCls}-compact-item`]: {
[`&:not(.${prefixCls}-compact-last-item)`]: {
[`.${prefixCls}-group-addon`]: {
[`.${prefixCls}-search-button`]: {
marginInlineEnd: -token.controlLineWidth,
borderRadius: 0,
},
},
},
[`&:not(.${prefixCls}-compact-first-item)`]: {
[`.${prefixCls},.${prefixCls}-affix-wrapper`]: {
borderRadius: 0,
},
},
[`> .${prefixCls}-group-addon .${prefixCls}-search-button,
> .${prefixCls},
.${prefixCls}-affix-wrapper`]: {
'&:hover,&:focus,&:active': {
zIndex: 2,
},
},
[`> .${prefixCls}-affix-wrapper-focused`]: {
zIndex: 2,
},
},
},
};
};

View File

@ -5,6 +5,7 @@ import genDropdownStyle from './dropdown';
import genMultipleStyle from './multiple';
import genSingleStyle from './single';
import { resetComponent, resetIcon } from '../../style';
import { genCompactItemStyle } from '../../style/compact-item';
export interface ComponentToken {
zIndexPopup: number;
@ -264,6 +265,13 @@ const genSelectStyle: GenerateStyle<SelectToken> = token => {
'&&-in-form-item': {
width: '100%',
},
// Space.Compact
...genCompactItemStyle(
token,
componentCls,
`${componentCls}-selector`,
`${componentCls}-focused`,
),
},
},

View File

@ -6,6 +6,8 @@ import type { DirectionType } from '../config-provider';
import { ConfigContext } from '../config-provider';
import type { SizeType } from '../config-provider/SizeContext';
import useStyle from './style';
export interface SpaceCompactItemContextType {
compactSize?: SizeType;
compactDirection?: 'horizontal' | 'vertical';
@ -73,8 +75,10 @@ const Compact: React.FC<SpaceCompactProps> = props => {
} = props;
const prefixCls = getPrefixCls('space-compact', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
const clx = classNames(
prefixCls,
hashId,
{
[`${prefixCls}-rtl`]: directionConfig === 'rtl',
[`${prefixCls}-block`]: block,
@ -113,10 +117,10 @@ const Compact: React.FC<SpaceCompactProps> = props => {
return null;
}
return (
return wrapSSR(
<div className={clx} {...restProps}>
{nodes}
</div>
</div>,
);
};

View File

@ -1,17 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@space-compact-prefix-cls: ~'@{ant-prefix}-space-compact';
.@{space-compact-prefix-cls} {
display: inline-flex;
&-block {
display: flex;
width: 100%;
}
&-vertical {
flex-direction: column;
}
}

View File

@ -0,0 +1,29 @@
import type { FullToken, GenerateStyle } from '../../theme';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
// Component token here
}
interface SpaceToken extends FullToken<'Space'> {
// Custom token here
}
const genSpaceCompactStyle: GenerateStyle<SpaceToken> = token => {
const { componentCls } = token;
return {
[componentCls]: {
display: 'inline-flex',
'&-block': {
display: 'flex',
width: '100%',
},
'&-vertical': {
flexDirection: 'column',
},
},
};
};
// ============================== Export ==============================
export default genSpaceCompactStyle;

View File

@ -1,5 +1,6 @@
import type { FullToken, GenerateStyle } from '../../theme';
import { genComponentStyleHook } from '../../theme';
import genSpaceCompactStyle from './compact';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
@ -47,4 +48,7 @@ const genSpaceStyle: GenerateStyle<SpaceToken> = token => {
};
// ============================== Export ==============================
export default genComponentStyleHook('Space', token => [genSpaceStyle(token)]);
export default genComponentStyleHook('Space', token => [
genSpaceStyle(token),
genSpaceCompactStyle(token),
]);

View File

@ -0,0 +1,53 @@
/* eslint-disable import/prefer-default-export */
import type { CSSObject } from '@ant-design/cssinjs';
import type { DerivativeToken } from '../theme';
function compactItemVerticalBorder(token: DerivativeToken): CSSObject {
return {
// border collapse
'&-item:not(&-last-item)': {
marginBottom: -token.controlLineWidth,
},
'&-item': {
'&:hover,&:focus,&:active': {
zIndex: 2,
},
'&[disabled]': {
zIndex: 0,
},
},
};
}
function compactItemBorderVerticalRadius(prefixCls: string): CSSObject {
return {
'&-item:not(&-first-item):not(&-last-item)': {
borderRadius: 0,
},
'&-item&-first-item': {
[`&, &${prefixCls}-sm, &${prefixCls}-lg`]: {
borderEndEndRadius: 0,
borderEndStartRadius: 0,
},
},
'&-item&-last-item': {
[`&, &${prefixCls}-sm, &${prefixCls}-lg`]: {
borderStartStartRadius: 0,
borderStartEndRadius: 0,
},
},
};
}
export function genCompactItemVerticalStyle(token: DerivativeToken, prefixCls: string): CSSObject {
return {
'&-compact-vertical': {
...compactItemVerticalBorder(token),
...compactItemBorderVerticalRadius(prefixCls),
},
};
}

View File

@ -0,0 +1,81 @@
/* eslint-disable import/prefer-default-export */
import type { CSSObject } from '@ant-design/cssinjs';
import type { DerivativeToken } from '../theme';
// handle border collapse
function compactItemBorder(
token: DerivativeToken,
borderedItemCls?: string,
popoverFocusedCls?: string,
): CSSObject {
const childCombinator = borderedItemCls ? '> *' : '';
return {
'&-item:not(&-last-item)': {
marginInlineEnd: -token.controlLineWidth,
},
'&-item': {
[`&:hover ${childCombinator}, &:focus ${childCombinator}, &:active ${childCombinator}`]: {
zIndex: 2,
},
...(popoverFocusedCls
? {
[`&${popoverFocusedCls}`]: {
zIndex: 2,
},
}
: {}),
[`&[disabled] ${childCombinator}`]: {
zIndex: 0,
},
},
};
}
// handle border-radius
function compactItemBorderRadius(prefixCls: string, borderedElementCls?: string): CSSObject {
const childCombinator = borderedElementCls ? `> ${borderedElementCls}` : '';
return {
[`&-item:not(&-first-item):not(&-last-item) ${childCombinator}`]: {
borderRadius: 0,
},
'&-item&-first-item': {
[`& ${childCombinator}, &${prefixCls}-sm ${childCombinator}, &${prefixCls}-lg ${childCombinator}`]:
{
borderStartEndRadius: 0,
borderEndEndRadius: 0,
},
},
'&-item&-last-item': {
[`& ${childCombinator}, &${prefixCls}-sm ${childCombinator}, &${prefixCls}-lg ${childCombinator}`]:
{
borderStartStartRadius: 0,
borderEndStartRadius: 0,
},
},
};
}
export function genCompactItemStyle(
token: DerivativeToken,
prefixCls: string,
/** Some component borders are implemented on child elements like `Select` */
borderedElementCls?: string,
/**
* Some components have special `focus` className especially with popovers like `Select` and
* `DatePicker`
*/
popoverFocusedCls?: string,
): CSSObject {
return {
'&-compact': {
...compactItemBorder(token, borderedElementCls, popoverFocusedCls),
...compactItemBorderRadius(prefixCls, borderedElementCls),
},
};
}

View File

@ -1,51 +0,0 @@
.compact-item-vertical-border-radius(@prefix-cls) {
&-item:not(&-first-item):not(&-last-item) {
border-radius: 0;
}
&-item&-first-item {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
.@{prefix-cls}-sm & {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
}
&-item&-last-item {
border-top-left-radius: 0;
border-top-right-radius: 0;
.@{prefix-cls}-sm & {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
}
.compact-item-vertical-border(@prefix-cls) {
// border collapse
&-item:not(&-last-item) {
margin-bottom: -@border-width-base;
}
&-item {
&:hover,
&:focus,
&:active {
z-index: 2;
}
&[disabled] {
z-index: 0;
}
}
}
.compact-item-vertical(@prefix-cls) {
&-compact-vertical {
.compact-item-vertical-border(@prefix-cls);
.compact-item-vertical-border-radius(@prefix-cls);
}
}

View File

@ -1,170 +0,0 @@
.compact-item-border-radius(@prefix-cls, @bordered-item-cls: null) {
& when (@bordered-item-cls = null) {
// border-radius
&-item:not(&-first-item):not(&-last-item).@{prefix-cls} {
border-radius: 0;
}
&-item.@{prefix-cls}&-first-item:not(&-item-rtl) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
.@{prefix-cls}-sm & {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
&-item.@{prefix-cls}&-last-item:not(&-item-rtl) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
.@{prefix-cls}-sm & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
// ----------rtl for first item----------
&-item.@{prefix-cls}&-item-rtl&-first-item {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
.@{prefix-cls}-sm & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
// ----------rtl for last item----------
&-item.@{prefix-cls}&-item-rtl&-last-item {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
.@{prefix-cls}-sm & {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
}
& when (not (@bordered-item-cls = null)) {
// border-radius
&-item:not(&-first-item):not(&-last-item).@{prefix-cls} > .@{bordered-item-cls} {
border-radius: 0;
}
&-item&-first-item.@{prefix-cls}:not(&-item-rtl) > .@{bordered-item-cls} {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
.@{prefix-cls}-sm & {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
&-item&-last-item.@{prefix-cls}:not(&-item-rtl) > .@{bordered-item-cls} {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
.@{prefix-cls}-sm & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
// ----------rtl for first item----------
&-item.@{prefix-cls}&-first-item&-item-rtl > .@{bordered-item-cls} {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
.@{prefix-cls}-sm & {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
// ----------rtl for last item----------
&-item.@{prefix-cls}&-last-item&-item-rtl > .@{bordered-item-cls} {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
.@{prefix-cls}-sm & {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
}
}
.compact-item-border(@prefix-cls, @bordered-item-cls: null, @special-open-cls) {
& when (@bordered-item-cls = null) {
// border collapse
&-item:not(&-last-item):not(&-item-rtl) {
margin-right: -@border-width-base;
}
// rtl border collapse
&-item:not(&-last-item)&-item-rtl {
margin-left: -@border-width-base;
}
&-item {
&:hover,
&:focus,
&:active {
z-index: 2;
}
// Select has an extra focus className
& when (not (@special-item-cls = null)) {
&.@{special-item-cls} {
z-index: 2;
}
}
&[disabled] {
z-index: 0;
}
}
}
& when (not (@bordered-item-cls = null)) {
// border collapse
&-item:not(&-last-item) {
margin-right: -@border-width-base;
&.@{prefix-cls}-compact-item-rtl {
margin-right: 0;
margin-left: -@border-width-base;
}
}
&-item {
&:hover,
&:focus,
&:active {
> * {
z-index: 2;
}
}
// Select has an special focus-item
& when (not (@special-item-cls = null)) {
&.@{special-item-cls} > * {
z-index: 2;
}
}
&[disabled] > * {
z-index: 0;
}
}
}
}
.compact-item(@prefix-cls, @bordered-item-cls: null, @special-item-cls: null) {
&-compact {
.compact-item-border(@prefix-cls, @bordered-item-cls, @special-item-cls);
.compact-item-border-radius(@prefix-cls, @bordered-item-cls);
}
}

View File

@ -314,7 +314,7 @@
"bundlesize": [
{
"path": "./dist/antd.min.js",
"maxSize": "373.5 kB"
"maxSize": "374.5 kB"
}
],
"tnpm": {