-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add high density for textinput [CFCX-958] (#2659)
* feat: add high density for textinput * feat: update styles for high density IconButton and InputGroup * docs: add text about support for high density to TextInput * chore: add changeset * refactor: replace hardcoded values with tokens * feat: add InputGroup story and fixes styles for copyButton * refactor: improve invalid and disabled styles * Update packages/components/forms/src/TextInput/input-group/InputGroup.tsx Co-authored-by: Rémy Lenoir <103024358+cf-remylenoir@users.noreply.github.com> * refactor: remove variables and duplicated code * refactor: remove unecessary minHeight * refactor: correct size for high density small button * fix: padding of textarea * refactor: use typography tokens Co-authored-by: Rémy Lenoir <103024358+cf-remylenoir@users.noreply.github.com> --------- Co-authored-by: Rémy Lenoir <103024358+cf-remylenoir@users.noreply.github.com>
- Loading branch information
1 parent
dbcab07
commit 54188ad
Showing
14 changed files
with
535 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'@contentful/f36-button': minor | ||
'@contentful/f36-forms': minor | ||
--- | ||
|
||
Add high density support for TextInput and InputGroup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
184 changes: 112 additions & 72 deletions
184
packages/components/forms/src/BaseInput/BaseInput.styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,140 @@ | ||
import { css } from 'emotion'; | ||
import tokens from '@contentful/f36-tokens'; | ||
import type { CSSObject } from '@emotion/serialize'; | ||
import type { Density } from '@contentful/f36-utils'; | ||
import { BaseInputInternalProps } from './types'; | ||
|
||
const getSizeStyles = ({ size }): CSSObject => { | ||
type getSizeStylesProps = Pick<BaseInputInternalProps, 'size'> & { | ||
density?: Density; | ||
}; | ||
|
||
const getSizeStyles = ({ size, density }: getSizeStylesProps): CSSObject => { | ||
const isHighDensity = density === 'high'; | ||
if (size === 'small') { | ||
return { | ||
padding: `${tokens.spacing2Xs} ${tokens.spacingXs}`, | ||
height: '32px', | ||
maxHeight: '32px', | ||
padding: tokens.spacingXs, | ||
minHeight: isHighDensity ? tokens.spacingL : tokens.spacingXl, | ||
maxHeight: isHighDensity ? tokens.spacingL : tokens.spacingXl, | ||
}; | ||
} | ||
|
||
return { | ||
height: '40px', | ||
maxHeight: '40px', | ||
padding: isHighDensity ? tokens.spacingXs : `10px ${tokens.spacingS}`, | ||
minHeight: isHighDensity ? tokens.spacingXl : '40px', | ||
maxHeight: isHighDensity ? tokens.spacingXl : '40px', | ||
}; | ||
}; | ||
|
||
const getZIndex = ({ | ||
isDisabled, | ||
isInvalid, | ||
zIndexBase = tokens.zIndexDefault, | ||
}: { | ||
isDisabled?: boolean; | ||
isInvalid?: boolean; | ||
zIndexBase?: number; | ||
}) => (isDisabled || isInvalid ? zIndexBase + 1 : zIndexBase); | ||
|
||
const getStyles = ({ as, isDisabled, isInvalid, size, resize }) => ({ | ||
rootComponentWithIcon: css({ | ||
position: 'relative', | ||
display: 'flex', | ||
width: '100%', | ||
zIndex: getZIndex({ isDisabled, isInvalid }), | ||
}), | ||
input: css({ | ||
outline: 'none', | ||
boxShadow: tokens.insetBoxShadowDefault, | ||
boxSizing: 'border-box', | ||
backgroundColor: isDisabled ? tokens.gray100 : tokens.colorWhite, | ||
border: `1px solid ${isInvalid ? tokens.red600 : tokens.gray300}`, | ||
borderRadius: tokens.borderRadiusMedium, | ||
color: tokens.gray700, | ||
fontFamily: tokens.fontStackPrimary, | ||
fontSize: tokens.fontSizeM, | ||
lineHeight: tokens.lineHeightM, | ||
padding: `10px ${tokens.spacingS}`, | ||
margin: 0, | ||
cursor: isDisabled ? 'not-allowed' : 'auto', | ||
width: '100%', | ||
zIndex: getZIndex({ isDisabled, isInvalid }), | ||
type getInputStylesProps = Pick< | ||
BaseInputInternalProps, | ||
'as' | 'isDisabled' | 'isInvalid' | 'size' | 'resize' | ||
> & { | ||
density?: Density; | ||
}; | ||
|
||
// if the input is a textarea, the resize prop is applied and size should be ignored | ||
...(as === 'textarea' ? { resize } : getSizeStyles({ size })), | ||
const getInvalidOrDisabledStyles = ({ | ||
isDisabled, | ||
isInvalid, | ||
}: { | ||
isDisabled?: boolean; | ||
isInvalid?: boolean; | ||
}) => { | ||
if (isDisabled) { | ||
return { | ||
borderColor: tokens.gray300, | ||
boxShadow: 'none', | ||
}; | ||
} | ||
if (isInvalid) { | ||
return { | ||
borderColor: tokens.red600, | ||
boxShadow: tokens.glowNegative, | ||
}; | ||
} | ||
return {}; | ||
}; | ||
|
||
'&::placeholder': { | ||
color: tokens.gray500, | ||
const getStyles = ({ | ||
as, | ||
isDisabled, | ||
isInvalid, | ||
size, | ||
resize, | ||
density = 'low', | ||
}: getInputStylesProps) => { | ||
const densityStyles = { | ||
low: { | ||
borderRadius: tokens.borderRadiusMedium, | ||
lineHeight: tokens.lineHeightM, | ||
fontSize: tokens.fontSizeM, | ||
}, | ||
|
||
'&:active, &:active:hover': { | ||
borderColor: isInvalid | ||
? tokens.red600 | ||
: isDisabled | ||
? tokens.gray300 | ||
: tokens.blue600, | ||
boxShadow: isInvalid | ||
? tokens.glowNegative | ||
: isDisabled | ||
? 'none' | ||
: tokens.glowPrimary, | ||
high: { | ||
borderRadius: tokens.borderRadiusSmall, | ||
lineHeight: tokens.lineHeightMHigh, | ||
fontSize: tokens.fontSizeMHigh, | ||
}, | ||
}; | ||
|
||
'&:focus': { | ||
borderColor: isInvalid | ||
? tokens.red600 | ||
: isDisabled | ||
? tokens.gray300 | ||
: tokens.blue600, | ||
boxShadow: isInvalid | ||
? tokens.glowNegative | ||
: isDisabled | ||
? 'none' | ||
: tokens.glowPrimary, | ||
}, | ||
}), | ||
return { | ||
rootComponentWithIcon: css({ | ||
position: 'relative', | ||
display: 'flex', | ||
width: '100%', | ||
zIndex: getZIndex({ isDisabled, isInvalid }), | ||
}), | ||
input: css({ | ||
outline: 'none', | ||
boxShadow: tokens.insetBoxShadowDefault, | ||
boxSizing: 'border-box', | ||
backgroundColor: isDisabled ? tokens.gray100 : tokens.colorWhite, | ||
border: `1px solid ${isInvalid ? tokens.red600 : tokens.gray300}`, | ||
color: tokens.gray700, | ||
fontFamily: tokens.fontStackPrimary, | ||
margin: 0, | ||
cursor: isDisabled ? 'not-allowed' : 'auto', | ||
width: '100%', | ||
zIndex: getZIndex({ isDisabled, isInvalid }), | ||
...densityStyles[density], | ||
|
||
inputWithIcon: css({ | ||
paddingLeft: size === 'small' ? tokens.spacingXl : '38px', | ||
}), | ||
// if the input is a textarea, the resize prop is applied and size should be ignored | ||
...(as === 'textarea' ? { resize } : getSizeStyles({ size, density })), | ||
|
||
iconPlaceholder: css({ | ||
position: 'absolute', | ||
pointerEvents: 'none', | ||
top: 0, | ||
bottom: 0, | ||
left: size === 'small' ? tokens.spacingXs : tokens.spacingS, | ||
display: 'flex', | ||
alignItems: 'center', | ||
zIndex: tokens.zIndexDefault, | ||
}), | ||
}); | ||
'&::placeholder': { | ||
color: tokens.gray500, | ||
}, | ||
|
||
'&:active, &:active:hover, &:focus': { | ||
borderColor: tokens.blue600, | ||
boxShadow: tokens.glowPrimary, | ||
...getInvalidOrDisabledStyles({ isDisabled, isInvalid }), | ||
}, | ||
}), | ||
|
||
inputWithIcon: css({ | ||
paddingLeft: tokens.spacingXl, | ||
}), | ||
|
||
iconPlaceholder: css({ | ||
position: 'absolute', | ||
pointerEvents: 'none', | ||
top: 0, | ||
bottom: 0, | ||
left: size === 'small' ? tokens.spacingXs : tokens.spacingS, | ||
display: 'flex', | ||
alignItems: 'center', | ||
zIndex: tokens.zIndexDefault, | ||
}), | ||
}; | ||
}; | ||
|
||
export default getStyles; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import type { SpacingTokens } from '@contentful/f36-tokens'; | ||
import type { Density } from '@contentful/f36-utils'; | ||
|
||
export type InputGroupSpacing = SpacingTokens | 'none'; | ||
|
||
export type GetStyleArguments = { | ||
spacing: InputGroupSpacing; | ||
density: Density; | ||
}; |
Oops, something went wrong.