From 97ce9863f407a91519888afe107a1dc6e86b18c4 Mon Sep 17 00:00:00 2001 From: kostasdano Date: Mon, 12 Jun 2023 15:52:25 +0300 Subject: [PATCH 001/120] feat: TextInputBase new tokens --- .../TextInputBase/TextInputBase.tokens.ts | 12 ++ .../tokens/components/variables/field.ts | 175 ++++++++++++++++++ .../tokens/semantic/variables/borderColor.ts | 8 +- 3 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 src/components/TextInputBase/TextInputBase.tokens.ts create mode 100644 src/theme/tokens/components/variables/field.ts diff --git a/src/components/TextInputBase/TextInputBase.tokens.ts b/src/components/TextInputBase/TextInputBase.tokens.ts new file mode 100644 index 000000000..e60c616aa --- /dev/null +++ b/src/components/TextInputBase/TextInputBase.tokens.ts @@ -0,0 +1,12 @@ +import field from 'theme/tokens/components/variables/field'; +import { getComponentTokens, DotKeys } from 'theme/tokens/utils'; + +import { Theme } from '../../theme'; + +export type TextInputBaseTokens = DotKeys; + +export const getTextInputBaseTokens = ( + theme: Theme +): ((path: TextInputBaseTokens, fn?: (val: string) => any) => string) => { + return getComponentTokens(field, theme); +}; diff --git a/src/theme/tokens/components/variables/field.ts b/src/theme/tokens/components/variables/field.ts new file mode 100644 index 000000000..2d8e2aa08 --- /dev/null +++ b/src/theme/tokens/components/variables/field.ts @@ -0,0 +1,175 @@ +const field = { + hintPadding: { + value: '{spacing.4}', + type: 'spacing', + description: 'sets vertical padding between an input field container and its hint (if used)', + }, + placeholder: { + value: '{sem.typography.body02}', + type: 'typography', + description: 'Sets text for input field placeholder label', + }, + input: { + value: '{sem.typography.body02}', + type: 'typography', + description: 'Sets text for field input', + }, + label: { + value: '{sem.typography.label03}', + type: 'typography', + description: 'Sets text for input field label', + }, + hint: { + value: '{sem.typography.body03}', + type: 'typography', + errorHintColor: { + value: '{sem.textColor.main.error}', + type: 'color', + description: 'Sets textColor for a field error hint', + }, + hintColor: { + value: '{sem.textColor.main.secondary}', + type: 'color', + description: 'Sets text color for a field hint', + }, + description: 'Sets text for input field hint', + }, + backgroundColor: { + default: { + value: '{sem.palette.systemic.tertiary.light}', + type: 'color', + description: 'Sets backgroundColor for default input field container', + }, + hover: { + type: 'color', + value: '{sem.palette.systemic.tertiary.main}', + description: 'Sets backgroundColor for hovered input field container', + }, + focused: { + type: 'color', + value: '{sem.palette.systemic.tertiary.main}', + description: 'Sets backgroundColor for focused input field container', + }, + error: { + value: '{sem.palette.systemic.error.light}', + type: 'color', + description: 'Sets backgroundColor for error input field container', + }, + errorHover: { + value: '{sem.palette.systemic.error.main}', + type: 'color', + description: 'Sets backgroundColor for hoveredError input field container', + }, + readOnly: { + value: '{sem.palette.systemic.tertiary.main}', + type: 'color', + description: 'Sets backgroundColor for read only input field container', + }, + }, + borderColor: { + default: { + type: 'color', + value: '{sem.borderColor.interactive.default}', + description: 'Sets borderColor for default/hovered input field container', + }, + focused: { + type: 'color', + value: '{sem.borderColor.interactive.active}', + description: 'Sets borderColor for focused input field container', + }, + error: { + type: 'color', + value: '{sem.borderColor.interactive.error}', + description: 'Sets borderColor for error input field container', + }, + readOnly: { + type: 'color', + value: '{sem.borderColor.interactive.defaultAlt}', + description: 'Sets borderColor for read only input field container', + }, + }, + textColor: { + inputColor: { + value: '{sem.textColor.light.primary}', + type: 'color', + description: 'Sets textColor for a field input', + }, + inputColorAlt: { + type: 'color', + value: '{sem.textColor.light.secondary}', + description: + 'Sets textColor for field label, hint, text placehodler and locked field contnet ', + }, + errorHintColor: { + type: 'color', + value: '{sem.textColor.light.error}', + description: 'Sets textColor for error input field hint', + }, + labelActive: { + type: 'color', + value: '{sem.textColor.light.active}', + description: 'Sets textColor for an active field label', + }, + labelError: { + type: 'color', + value: '{sem.textColor.light.error}', + description: 'Sets textColor for an error field label', + }, + }, + iconColor: { + default: { + value: '{sem.textColor.light.secondary}', + type: 'color', + description: 'Sets color for a field icon/suffix (if used)', + }, + errorIcon: { + value: '{sem.textColor.light.error}', + type: 'color', + description: 'Sets color for an error input field icon', + }, + textAreaIconColor: { + value: '{sem.palette.accents.lightPurple.main}', + type: 'color', + description: "Sets backgroundColor for a text area field's 'resize' icon", + }, + }, + paddingContentLeft: { + value: '{spacing.5}', + type: 'spacing', + description: 'Sets left padding between content and container', + }, + paddingContentRight: { + value: '{spacing.5}', + type: 'spacing', + description: 'Sets right padding between content and addOn', + }, + container: { + value: '{sizing.13}', + type: 'sizing', + description: 'Sets fixed height for field content container', + }, + borderWidth: { + '1': { + value: '{borderWidth.1}', + type: 'borderWidth', + description: "Sets border width for slider's input field", + }, + '2': { + value: '{borderWidth.2}', + type: 'borderWidth', + description: "Sets border width for slider's input field for focused and error state", + }, + }, + borderRadius: { + value: '{borderRadius.2}', + type: 'borderRadius', + description: 'Sets field border radius', + }, + hintGap: { + value: '{spacing.3}', + type: 'spacing', + description: 'Sets spacing between icon and hint text', + }, +} as const; + +export default field; diff --git a/src/theme/tokens/semantic/variables/borderColor.ts b/src/theme/tokens/semantic/variables/borderColor.ts index c60c1cb09..04ec6e224 100644 --- a/src/theme/tokens/semantic/variables/borderColor.ts +++ b/src/theme/tokens/semantic/variables/borderColor.ts @@ -27,15 +27,15 @@ const borderColor = { }, }, interactive: { - inactive: { + default: { value: '{colors.blue.200}', type: 'color', - description: 'Used in inactive components', + description: 'Used in default components', }, - inactiveAlt: { + defaultAlt: { value: '{colors.lightPurple.150}', type: 'color', - description: 'inactive borderColor alt variant', + description: 'default borderColor alt variant', }, active: { value: '{colors.blue.500}', From 7effa3fbd19284235452db1ad46ccc61fbd60885 Mon Sep 17 00:00:00 2001 From: kostasdano Date: Mon, 12 Jun 2023 15:54:06 +0300 Subject: [PATCH 002/120] feat: TextInputBase props and styles update --- src/components/Icon/assets/warning.svg | 6 +- .../TextInputBase/TextInputBase.style.ts | 185 +++++++++--------- .../TextInputBase/TextInputBase.tsx | 74 +++---- src/components/TextInputBase/config.ts | 2 +- src/utils/size-utils.ts | 48 ----- src/utils/tests/size-utils.test.ts | 26 --- 6 files changed, 125 insertions(+), 216 deletions(-) delete mode 100644 src/utils/size-utils.ts delete mode 100644 src/utils/tests/size-utils.test.ts diff --git a/src/components/Icon/assets/warning.svg b/src/components/Icon/assets/warning.svg index f463f8024..727c4c8a9 100644 --- a/src/components/Icon/assets/warning.svg +++ b/src/components/Icon/assets/warning.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/src/components/TextInputBase/TextInputBase.style.ts b/src/components/TextInputBase/TextInputBase.style.ts index ec8e056d3..4380aff44 100644 --- a/src/components/TextInputBase/TextInputBase.style.ts +++ b/src/components/TextInputBase/TextInputBase.style.ts @@ -1,57 +1,52 @@ import { css, SerializedStyles } from '@emotion/react'; import { Theme } from 'theme'; import { rem } from 'theme/utils'; -import { DEFAULT_SIZE, getTextFieldSize } from 'utils/size-utils'; -import { textInputConfig } from './config'; +import { MIN_WIDTH } from './config'; import { TextInputBaseProps } from './TextInputBase'; -import { getDisabled, getHover, getPressed } from '../../theme/states'; +import { getTextInputBaseTokens, TextInputBaseTokens } from './TextInputBase.tokens'; import { ColorScheme } from '../../theme/types'; import { LABEL_TRANSFORM_LEFT_SPACING } from 'components/Label/Label.style'; +import { body02, body03 } from 'components/Typography/Typography.config.styles'; const wrapperStyleSwitch = ({ theme, - colorScheme = 'semantic', - isLean, hasError, + isLocked, isDisabled, }: { theme: Theme; colorScheme: ColorScheme; + isLocked?: boolean; hasError?: boolean; -} & Pick) => { - if (isLean) { - return { - backgroundColor: 'transparent', - }; - } - const borderConfig = textInputConfig.types[colorScheme].outlined.border; - - const backgroundColor = - colorScheme === 'dark' ? theme.utils.getColor('darkGrey', 700) : theme.globals.colors.white; - const borderColorName = !hasError - ? borderConfig.color.pressed.name - : borderConfig.color.error.name; - const borderColorShade = !hasError - ? borderConfig.color.pressed.shade - : borderConfig.color.error.shade; +} & Pick) => { + const tokens = getTextInputBaseTokens(theme); + + const borderColor = isLocked ? tokens('borderColor.readOnly') : tokens('borderColor.focused'); + + const backgroundColor = hasError + ? tokens('backgroundColor.error') + : isLocked + ? tokens('backgroundColor.readOnly') + : tokens('backgroundColor.default'); + + const backgroundHoveredColor = hasError + ? tokens('backgroundColor.errorHover') + : tokens('backgroundColor.hover'); const events = isDisabled ? { '&:focus-within': { - boxShadow: `0 0 0 ${rem(1)} transparent`, + boxShadow: `0 0 0 ${tokens('borderWidth.2')} transparent`, }, } : { '&:hover': { - backgroundColor: getHover({ theme }).backgroundColor, + backgroundColor: backgroundHoveredColor, }, '&:focus-within': { - boxShadow: `0 0 0 ${rem(borderConfig.width + 1)} ${theme.utils.getColor( - borderColorName, - borderColorShade - )}`, - backgroundColor: getPressed({ theme }).backgroundColor, + boxShadow: `0 0 0 ${tokens('borderWidth.2')} ${borderColor}`, + backgroundColor: tokens('backgroundColor.focused'), }, }; @@ -66,53 +61,55 @@ const wrapperStyleSwitch = ({ * in custom implementation needed eg: datepicker * */ export const wrapperStyle = - ({ - isDisabled, - isLocked, - status, - isLean, - isDark, - size, - sx, - hasMinWidthCompat, - }: TextInputBaseProps) => + ({ isDisabled, status, sx }: TextInputBaseProps) => (theme: Theme): SerializedStyles => { - const colorScheme = isDark ? 'dark' : theme.colorScheme; - const hasError = status === 'error'; - const textFieldSize = !isLean - ? getTextFieldSize(hasMinWidthCompat, size) - : getTextFieldSize(hasMinWidthCompat); - const borderConfig = textInputConfig.types[colorScheme].outlined.border; + const colorScheme = theme.colorScheme; + const isLocked = status?.type === 'read-only'; + const hasError = status?.type === 'error'; + + const tokens = getTextInputBaseTokens(theme); + + const borderColor = hasError + ? tokens('borderColor.error') + : isLocked + ? tokens('borderColor.readOnly') + : tokens('borderColor.default'); return css({ display: 'flex', alignItems: 'center', position: 'relative', transition: `background-color 0.25s, box-shadow 0.25s, border-color 0.25s`, - boxShadow: `0 0 0 ${rem(borderConfig.width)} ${ - hasError - ? theme.utils.getColor(borderConfig.color.error.name, borderConfig.color.error.shade) - : theme.utils.getColor(borderConfig.color.default.name, borderConfig.color.default.shade) - }`, - borderRadius: theme.globals.spacing.get('3'), + + boxShadow: `0 0 0 ${tokens( + `borderWidth.${hasError ? 2 : 1}` as TextInputBaseTokens + )} ${borderColor}`, + borderRadius: tokens('borderRadius'), userSelect: 'none', - opacity: isDisabled ? getDisabled().opacity : 1, - cursor: isDisabled || isLocked ? getDisabled().cursor : 'auto', - ...textFieldSize, + opacity: isDisabled ? theme.tokens.disabledState.get('default') : 1, + cursor: isDisabled || isLocked ? 'not-allowed' : 'auto', + height: tokens('container'), + /** + * TODO: every Field component will have its own min-width, will need configuration once + * Field components start to get implemented + */ + minWidth: rem(MIN_WIDTH), ...wrapperStyleSwitch({ theme, colorScheme, - isLean, hasError, - isDisabled: Boolean(isDisabled || isLocked), + isLocked, + isDisabled, }), ...sx?.wrapper, }); }; export const textFieldStyle = - ({ isLean, sx }: TextInputBaseProps) => + ({ sx }: TextInputBaseProps) => (theme: Theme): SerializedStyles => { + const tokens = getTextInputBaseTokens(theme); + return css({ position: 'relative', display: 'inline-flex', @@ -120,7 +117,8 @@ export const textFieldStyle = alignItems: 'center', verticalAlign: 'top', width: 'fill-available', - padding: !isLean ? `0 ${theme.globals.spacing.get('6')}` : '', + /** TODO: revisit this when TextField's add-on is implemented */ + padding: `0 0 0 ${tokens('paddingContentLeft')}`, '> div': { position: 'relative', @@ -131,34 +129,32 @@ export const textFieldStyle = }; export const inputStyle = - ({ label, placeholder, size = DEFAULT_SIZE, isDark, sx }: TextInputBaseProps) => - (theme: Theme): SerializedStyles => - css({ + ({ label, placeholder, sx }: TextInputBaseProps) => + (theme: Theme): SerializedStyles => { + const tokens = getTextInputBaseTokens(theme); + + return css(body02(theme), { background: 'transparent', border: 'none', - color: - theme.colorScheme === 'dark' || isDark - ? theme.globals.colors.white - : theme.utils.getColor('darkGrey', 850), + color: tokens('textColor.inputColor'), display: 'block', position: 'relative', + /** + * TODO revisit this when field components are implemented, Label is part of (Multi)TextField component + */ top: label ? rem(7) : undefined, zIndex: 1, - fontSize: theme.globals.typography.fontSize[size === 'md' ? '15' : '13'], textOverflow: 'ellipsis', width: 0, minWidth: '100%', - '& + label': { - fontSize: theme.globals.typography.fontSize[size === 'md' ? '15' : '13'], - }, - '&:focus': { outline: 'none', }, '&::placeholder': { - color: !label && placeholder ? theme.utils.getColor('lightGrey', 650) : 'transparent', + color: !label && placeholder ? tokens('textColor.inputColorAlt') : 'transparent', + ...(!label && placeholder ? body02(theme) : {}), }, '&:not(:focus):placeholder-shown': { @@ -167,37 +163,46 @@ export const inputStyle = }, }, - '&:focus, &:not(:placeholder-shown)': { + '&:focus-within, &:not(:placeholder-shown)': { '& + label': { transform: `translate(${LABEL_TRANSFORM_LEFT_SPACING}, -35%) scale(0.8)`, fontWeight: theme.globals.typography.fontWeight.get('bold'), }, }, + '&:focus-within': { + '& + label': { + color: tokens('textColor.labelActive'), + }, + }, + '&:disabled': { cursor: 'not-allowed', }, ...sx?.input, }); + }; -export const errorMsgStyle = +export const hintMessageStyle = ({ status }: TextInputBaseProps) => - (theme: Theme): SerializedStyles => - css({ - display: 'flex', - color: - status === 'error' - ? theme.utils.getColor('error', 550, 'normal') - : theme.utils.getColor('lightGrey', 650), - fontSize: theme.globals.typography.fontSize.get('2'), - lineHeight: 1, - padding: `${rem(8)} 0 0`, - svg: { - padding: `0 ${rem(2)}`, - }, - - span: { - alignItems: 'stretch', - padding: `0 ${rem(2)}`, + (theme: Theme): SerializedStyles => { + const tokens = getTextInputBaseTokens(theme); + + return css( + { + display: 'flex', + alignItems: 'center', + gap: rem(4), + color: + status?.type === 'error' + ? tokens('textColor.errorHintColor') + : tokens('textColor.inputColorAlt'), + padding: `${tokens('hintPadding')} 0 0`, + span: { + alignItems: 'stretch', + padding: 0, + }, }, - }); + body03(theme) + ); + }; diff --git a/src/components/TextInputBase/TextInputBase.tsx b/src/components/TextInputBase/TextInputBase.tsx index a9e807326..52ec80b60 100644 --- a/src/components/TextInputBase/TextInputBase.tsx +++ b/src/components/TextInputBase/TextInputBase.tsx @@ -1,11 +1,9 @@ import { CSSObject } from '@emotion/serialize'; import useTheme from 'hooks/useTheme'; import React, { FC } from 'react'; -import { formFieldStyles } from 'theme/palette'; -import { DEFAULT_SIZE } from 'utils/size-utils'; -import { textInputSizes } from './config'; -import { errorMsgStyle, textFieldStyle, wrapperStyle } from './TextInputBase.style'; +import { hintMessageStyle, textFieldStyle, wrapperStyle } from './TextInputBase.style'; +import { getTextInputBaseTokens } from './TextInputBase.tokens'; import { generateTestDataId } from '../../utils/helpers'; import { TestProps } from '../../utils/types'; import Icon from 'components/Icon'; @@ -16,68 +14,54 @@ export type TextInputBaseProps = { label?: string; /** The placeholder of the input that will be used. This is shown if no label exists */ placeholder?: string; - /** An optional icon to show to the left - * TODO This prop will be renamed to 'prefix', like: https://ant.design/components/input/#components-input-demo-presuffix */ - leftIcon?: AcceptedIconNames | JSX.Element | null; - /** An optional icon to show to the right - * TODO This prop will be renamed to 'suffix', like: https://ant.design/components/input/#components-input-demo-presuffix */ - rightIcon?: AcceptedIconNames | JSX.Element | null; + /** An optional prefix (element or icon-name) to show to the left */ + prefix?: AcceptedIconNames | JSX.Element | null; + /** An optional suffix (element or icon-name) to show to the left */ + suffix?: AcceptedIconNames | JSX.Element | null; /** If the text field value is required */ isRequired?: boolean; /** If the text field is disabled */ isDisabled?: boolean; - /** If the text field is locked. Locked state is unique to this and the system */ - isLocked?: boolean; - /** dark mode of the text field */ - isDark?: boolean; - /** Error message */ - hintMsg?: React.ReactNode | string; + /** The status of the TextInput with an optional hint message */ + status?: { + type: 'normal' | 'error' | 'read-only'; + hintMessage?: string; + }; /** value of the input */ value?: string | number; - /** if the input will be without default style for use inside the library */ - isLean?: boolean; - /** Style of input field */ - styleType?: formFieldStyles; - /** Sets the size of the textField */ - size?: (typeof textInputSizes)[number]; - /** The status of the button regarding the status which is in - default normal */ - status?: 'success' | 'normal' | 'hint' | 'error'; /** Sx prop to override specific properties */ sx?: { wrapper?: CSSObject; textField?: CSSObject; input?: CSSObject; }; - /** @deprecated This is a compatibility prop that will be removed in the next version, along with the min-width value - * of the TextField. It will be replaced by a fullWidth prop. */ - hasMinWidthCompat?: boolean; } & TestProps; /** This Component is a wrapper for all primitives that hold text like Select, TextArea, TextInput. Here we keep the * logic of all the hover, focus status etc and the styling of these centralized **/ const TextInputBase: FC = ({ - isLean = false, isDisabled, - hintMsg, - styleType = 'filled', dataTestId, - status = 'normal', - isLocked = false, - size = DEFAULT_SIZE, - isDark = false, + status = { type: 'normal' }, children, sx, - hasMinWidthCompat = true, }) => { const theme = useTheme(); - const hintMessageToShow = hintMsg && ( -
+ + const tokens = getTextInputBaseTokens(theme); + + const hintMessageToShow = status.hintMessage && ( +
- {hintMsg} + {status.hintMessage}
); @@ -86,20 +70,14 @@ const TextInputBase: FC = ({
-
{children}
+
{children}
- {hintMsg && status !== 'normal' && hintMessageToShow} + {status.hintMessage && status.type !== 'read-only' && hintMessageToShow} ); }; diff --git a/src/components/TextInputBase/config.ts b/src/components/TextInputBase/config.ts index bf19e695e..345e330b2 100644 --- a/src/components/TextInputBase/config.ts +++ b/src/components/TextInputBase/config.ts @@ -6,7 +6,7 @@ export const SM = 'sm'; export const MD_HEIGHT = 46; export const SM_HEIGHT = 28; -export const MIN_WIDTH = 150; +export const MIN_WIDTH = 140; export const textInputSizes = [MD, SM] as const; export const textInputStates = ['default', 'pressed', 'error'] as const; diff --git a/src/utils/size-utils.ts b/src/utils/size-utils.ts deleted file mode 100644 index 0a57555b9..000000000 --- a/src/utils/size-utils.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { rem } from 'polished'; -import { SpacingKey } from 'theme/globals/spacing'; - -import { Theme } from '../theme'; -import { MD_HEIGHT, MIN_WIDTH, SM_HEIGHT } from 'components/TextInputBase/config'; - -type Size = 'md' | 'sm'; -export const DEFAULT_SIZE: Size = 'md'; - -export const getTextFieldHeight = (size?: Size): string => { - switch (size) { - case 'md': - return rem(MD_HEIGHT); - case 'sm': - return rem(SM_HEIGHT); - default: - return 'auto'; - } -}; - -const getTextFieldWidth = (size?: Size): string => { - switch (size) { - case 'md': - return rem(MIN_WIDTH); - case 'sm': - return rem(MIN_WIDTH); - default: - return 'auto'; - } -}; - -export const getTextFieldSize = ( - hasMinWidthCompat = true, - size?: Size -): { - minWidth?: string; - height: string; -} => { - if (!hasMinWidthCompat) { - return { height: getTextFieldHeight(size) }; - } - - return { minWidth: getTextFieldWidth(size), height: getTextFieldHeight(size) }; -}; - -export const getSpacingBySize: (size: SpacingKey, theme: Theme) => string = (size, theme) => { - return theme.globals.spacing.get(size); -}; diff --git a/src/utils/tests/size-utils.test.ts b/src/utils/tests/size-utils.test.ts deleted file mode 100644 index 16e5cb7bd..000000000 --- a/src/utils/tests/size-utils.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { rem } from 'polished'; - -import { MD_HEIGHT, MIN_WIDTH, SM_HEIGHT } from '../../components/TextInputBase/config'; -import { getTextFieldSize } from '../size-utils'; - -describe('Size utils', () => { - describe('getTextFieldSize', () => { - it('should matches the correct style configuration based on size', () => { - const mockStylesMD = { minWidth: rem(MIN_WIDTH), height: rem(MD_HEIGHT) }; - const mockStylesSM = { minWidth: rem(MIN_WIDTH), height: rem(SM_HEIGHT) }; - const mockStylesAUTO = { minWidth: 'auto', height: 'auto' }; - - expect(getTextFieldSize(true, 'md').minWidth).toBe(mockStylesMD.minWidth); - expect(getTextFieldSize(true, 'md').height).toBe(mockStylesMD.height); - - expect(getTextFieldSize(true, 'sm').minWidth).toBe(mockStylesSM.minWidth); - expect(getTextFieldSize(true, 'sm').height).toBe(mockStylesSM.height); - - expect(getTextFieldSize().minWidth).toBe(mockStylesAUTO.minWidth); - expect(getTextFieldSize().height).toBe(mockStylesAUTO.height); - - expect(getTextFieldSize(false).height).toBe(mockStylesAUTO.height); - expect(getTextFieldSize(false).minWidth).toBeUndefined(); - }); - }); -}); From c16381eca300fd89f9187ba90249359751e78db4 Mon Sep 17 00:00:00 2001 From: kostasdano Date: Mon, 12 Jun 2023 15:56:21 +0300 Subject: [PATCH 003/120] feat: update all components based on new props --- .../DatePickInput/DatePickInput.tsx | 4 +- .../components/SearchInput/SearchInput.tsx | 7 ++- src/components/SearchField/SearchField.tsx | 20 ++------ .../SearchField/SearchFieldShowcase.tsx | 9 ---- src/components/Select/Select.style.ts | 15 +++--- src/components/Select/Select.test.tsx | 2 - src/components/Select/Select.tsx | 26 ++++------- .../MultiselectTextField.style.ts | 6 ++- .../MultiselectTextField.tsx | 32 +++++-------- .../SelectMenu/SelectMenu.style.tsx | 9 ++-- .../components/SelectMenu/SelectMenu.tsx | 7 +-- src/components/Slider/Slider.tsx | 8 +--- src/components/TextArea/TextArea.tsx | 15 ++---- src/components/TextField/TextField.tsx | 46 +++++-------------- .../components/Search/Search.style.ts | 2 - .../storyUtils/ColorUtility/ColorUtility.tsx | 7 +-- .../EdgeCasesSelectShowcase.tsx | 4 -- .../SelectShowcase/MultiSelectShowcase.tsx | 10 ++-- .../SelectShowcase/SelectShowcase.tsx | 1 - 19 files changed, 69 insertions(+), 161 deletions(-) diff --git a/src/components/DatePicker/DatePickInput/DatePickInput.tsx b/src/components/DatePicker/DatePickInput/DatePickInput.tsx index a45986b71..a502e304d 100644 --- a/src/components/DatePicker/DatePickInput/DatePickInput.tsx +++ b/src/components/DatePicker/DatePickInput/DatePickInput.tsx @@ -107,7 +107,7 @@ const DatePickInput = React.forwardRef( onChange={ON_CHANGE_MOCK} placeholder="Date (start) - Date (end)" value={selectedDay.from ? `${formattedFrom} - ${formattedTo}` : ''} - rightIcon={} + suffix={} /> ); } @@ -122,7 +122,7 @@ const DatePickInput = React.forwardRef( onChange={ON_CHANGE_MOCK} placeholder="Select date" value={selectedDay.to ? formattedFrom : ''} - rightIcon={} + suffix={} /> ); }; diff --git a/src/components/Filter/components/SearchInput/SearchInput.tsx b/src/components/Filter/components/SearchInput/SearchInput.tsx index 811351f74..ff801ee35 100644 --- a/src/components/Filter/components/SearchInput/SearchInput.tsx +++ b/src/components/Filter/components/SearchInput/SearchInput.tsx @@ -18,7 +18,7 @@ export type SearchInputProps = { const SearchInput = ({ onChange, value, dataTestId, isLoading }: SearchInputProps) => { const theme = useTheme(); - const rightIcon = useMemo( + const suffix = useMemo( () => (
{isLoading && } @@ -32,13 +32,12 @@ const SearchInput = ({ onChange, value, dataTestId, isLoading }: SearchInputProp
); diff --git a/src/components/SearchField/SearchField.tsx b/src/components/SearchField/SearchField.tsx index 42ea6d913..7c9b1e29e 100644 --- a/src/components/SearchField/SearchField.tsx +++ b/src/components/SearchField/SearchField.tsx @@ -1,6 +1,5 @@ import useTheme from 'hooks/useTheme'; import React from 'react'; -import { DEFAULT_SIZE } from 'utils/size-utils'; import { rem } from '../../theme/utils'; import { TestProps } from '../../utils/types'; @@ -17,16 +16,7 @@ export type SearchFieldProps = { TestProps; const SearchField = React.forwardRef((props, ref) => { - const { - placeholder = 'Search', - isDisabled, - size = DEFAULT_SIZE, - isDark = false, - onClear, - dataTestId, - value = '', - ...rest - } = props; + const { placeholder = 'Search', isDisabled, onClear, dataTestId, value = '', ...rest } = props; const theme = useTheme(); @@ -37,10 +27,8 @@ const SearchField = React.forwardRef((props, @@ -49,7 +37,7 @@ const SearchField = React.forwardRef((props,
setValue(e.target.value)} - onClear={() => setValue('')} - /> - setValue(e.target.value)} onClear={() => setValue('')} diff --git a/src/components/Select/Select.style.ts b/src/components/Select/Select.style.ts index ac35ddbcb..228801a8e 100644 --- a/src/components/Select/Select.style.ts +++ b/src/components/Select/Select.style.ts @@ -14,11 +14,10 @@ export const selectWrapper = } `; -export const rightIconContainer = - (isOpen: boolean, isSearchable: boolean) => (): SerializedStyles => - css` - display: flex; - cursor: pointer; - transform: rotate(${isOpen && !isSearchable ? '180' : '0'}deg); - ${transition(0.2)} - `; +export const suffixContainer = (isOpen: boolean, isSearchable: boolean) => (): SerializedStyles => + css` + display: flex; + cursor: pointer; + transform: rotate(${isOpen && !isSearchable ? '180' : '0'}deg); + ${transition(0.2)} + `; diff --git a/src/components/Select/Select.test.tsx b/src/components/Select/Select.test.tsx index 07e1dd9c3..a0b02ad0a 100644 --- a/src/components/Select/Select.test.tsx +++ b/src/components/Select/Select.test.tsx @@ -36,7 +36,6 @@ describe('Generic Select', () => { )}
diff --git a/src/components/Select/components/SelectMenu/SelectMenu.style.tsx b/src/components/Select/components/SelectMenu/SelectMenu.style.tsx index 1838e6944..c5eb61c5c 100644 --- a/src/components/Select/components/SelectMenu/SelectMenu.style.tsx +++ b/src/components/Select/components/SelectMenu/SelectMenu.style.tsx @@ -12,13 +12,12 @@ export const MAX_SMALL_HEIGHT = 265; export const optionStyle = ({ isSelected, - size, hasNoResultsExist, }: { isSelected: boolean; hasNoResultsExist?: boolean } & Omit) => (theme: Theme): SerializedStyles => { return css` padding: ${theme.globals.spacing.get('6')}; - font-size: ${theme.globals.typography.fontSize.get(size === 'md' ? '4' : '3')}; + font-size: ${theme.globals.typography.fontSize.get('4')}; background-color: ${isSelected ? darken(0.07, theme.globals.colors.white) : theme.globals.colors.white}; @@ -36,16 +35,16 @@ export const optionStyle = }; export const menuStyle = - ({ status, size, isVirtualized }: SelectMenuProps & Omit) => + ({ status, isVirtualized }: SelectMenuProps & Omit) => (theme: Theme): SerializedStyles => css` background-color: ${theme.globals.colors.white}; border-radius: 4px; box-shadow: ${theme.globals.elevation['02']}; - top: ${status !== 'normal' ? '70%' : '110%'}; + top: ${status?.type !== 'normal' ? '70%' : '110%'}; z-index: 500; position: absolute; - max-height: ${rem(size === 'md' ? MAX_LARGE_HEIGHT : MAX_SMALL_HEIGHT)}; + max-height: ${rem(MAX_LARGE_HEIGHT)}; overflow-y: ${isVirtualized ? 'hidden' : 'auto'}; // TODO we need a technique to identify menu position left or right min-width: 100%; diff --git a/src/components/Select/components/SelectMenu/SelectMenu.tsx b/src/components/Select/components/SelectMenu/SelectMenu.tsx index 9548eeaf3..586fff2aa 100644 --- a/src/components/Select/components/SelectMenu/SelectMenu.tsx +++ b/src/components/Select/components/SelectMenu/SelectMenu.tsx @@ -5,12 +5,9 @@ import { SelectOption } from '../../Select'; import List from 'components/List'; import { MAX_NON_VIRTUALIZED_ITEMS_SELECT } from 'components/List/utils'; import { SELECT_ALL_OPTION } from 'components/Select/constants'; +import { TextInputBaseProps } from 'components/TextInputBase'; export type SelectMenuProps = { - /** Sets the size of the menu */ - size?: 'md' | 'sm'; - /** The status of the button regarding the status which is in - default normal */ - status?: 'success' | 'normal' | 'hint' | 'error'; filteredOptions: SelectOption[]; handleOptionClick: (option: SelectOption) => void; selectedOption: string | number; @@ -18,7 +15,7 @@ export type SelectMenuProps = { isVirtualized?: boolean; searchTerm?: string; hasSelectAllOption?: boolean; -}; +} & Pick; const SelectMenu: React.FC = (props) => { const { diff --git a/src/components/Slider/Slider.tsx b/src/components/Slider/Slider.tsx index 8a9a95d3b..a5a38367d 100644 --- a/src/components/Slider/Slider.tsx +++ b/src/components/Slider/Slider.tsx @@ -150,8 +150,6 @@ const Slider: React.FC = ({ ) => { const sanitizedValue = sanitizeValues(parseInt(e?.target.value || '0')); @@ -163,7 +161,7 @@ const Slider: React.FC = ({ onBlur([sanitizedValue, values[1]]); } }} - rightIcon={<>%} + suffix={<>%} sx={{ textField: { color: theme.utils.getColor('lightGrey', 650), @@ -174,8 +172,6 @@ const Slider: React.FC = ({ ) => { const sanitizedValue = sanitizeValues(parseInt(e?.target.value || '100')); @@ -187,7 +183,7 @@ const Slider: React.FC = ({ onBlur([values[0], sanitizedValue]); } }} - rightIcon={<>%} + suffix={<>%} sx={{ textField: { color: theme.utils.getColor('lightGrey', 650), diff --git a/src/components/TextArea/TextArea.tsx b/src/components/TextArea/TextArea.tsx index b2b0b00a0..5dd9d4c30 100644 --- a/src/components/TextArea/TextArea.tsx +++ b/src/components/TextArea/TextArea.tsx @@ -1,11 +1,9 @@ -import { omit } from 'lodash'; import * as React from 'react'; import { sxProp } from './TextArea.style'; import { useTheme } from '../../index'; -import { formFieldStyles } from '../../theme/palette'; import { TestProps } from '../../utils/types'; -import TextInputBase from '../TextInputBase/TextInputBase'; +import TextInputBase, { TextInputBaseProps } from '../TextInputBase/TextInputBase'; import { inputStyle as baseInputStyle } from 'components/TextInputBase/TextInputBase.style'; export type TextAreaProps = { @@ -19,12 +17,6 @@ export type TextAreaProps = { isDisabled?: boolean; /** If the text area can be resized */ isResizeEnabled?: boolean; - /** Style of input field */ - styleType?: formFieldStyles; - /** Error message */ - hintMsg?: React.ReactNode | string; - /** The status of the button regarding the status which is in - default normal */ - status?: 'success' | 'normal' | 'hint' | 'error'; /** Callback fired when the `input` is blurred. */ onBlur?: React.FocusEventHandler; /** Callback fired when the `input` is changed. */ @@ -35,7 +27,8 @@ export type TextAreaProps = { onKeyDown?: React.KeyboardEventHandler; /** Callback fired when the `input` value typed is changed */ onInput?: React.EventHandler; -} & TestProps; +} & Pick & + TestProps; const TextArea = React.forwardRef((props, ref) => { const { @@ -63,7 +56,7 @@ const TextArea = React.forwardRef((props, re required={isRequired} id={id} disabled={isDisabled} - {...omit(rest, ['styleType', 'hintMsg'])} + {...rest} ref={ref} />
diff --git a/src/components/TextField/TextField.tsx b/src/components/TextField/TextField.tsx index c46962b0c..320e5da85 100644 --- a/src/components/TextField/TextField.tsx +++ b/src/components/TextField/TextField.tsx @@ -1,7 +1,6 @@ import useTheme from 'hooks/useTheme'; import { omit } from 'lodash'; import React, { InputHTMLAttributes } from 'react'; -import { DEFAULT_SIZE } from 'utils/size-utils'; import { IconWrapper } from './components/commons'; import { TestProps } from '../../utils/types'; @@ -28,42 +27,26 @@ export type TextFieldProps = { onKeyDown?: React.KeyboardEventHandler; /** Callback fired when the `input` value typed is changed */ onInput?: React.EventHandler; - /** Boolean to make the input readonly. Default to false. */ - isReadOnly?: boolean; - /** @deprecated This is a compatibility prop that will be removed in the next version, along with the min-width value - * of the TextField. It will be replaced by a fullWidth prop. */ - hasMinWidthCompat?: boolean; } & TextInputBaseProps & InputProps & TestProps; -console.warn( - 'Deprecation warning! min-width will be removed from the component in v5 of ictinus. ' + - 'hasMinWidthCompat prop has been added to temporarily disable min-width when necessary' -); - const TextField = React.forwardRef((props, ref) => { const { id = undefined, - rightIcon = null, - leftIcon = null, + suffix = null, + prefix = null, label, placeholder = '', isRequired = false, isDisabled, - isLocked = false, - size = DEFAULT_SIZE, - isDark = false, - isLean, - hintMsg: __hintMsg, - styleType: __styleType, - isReadOnly, status, - hasMinWidthCompat = true, ...rest } = props; const theme = useTheme(); + const isLocked = status?.type === 'read-only'; + const getIcon = (icon: AcceptedIconNames | JSX.Element | null) => icon ? ( typeof icon === 'string' ? ( @@ -79,12 +62,12 @@ const TextField = React.forwardRef((props, ref return ( - - {leftIcon && {getIcon(leftIcon)}} + + {prefix && {getIcon(prefix)}}
((props, ref /> {label && (
- {rightIcon && !isLocked && ( - {getIcon(rightIcon)} - )} + {suffix && !isLocked && {getIcon(suffix)}} {isLocked && ( - + )}
diff --git a/src/components/TopAppBar/components/Search/Search.style.ts b/src/components/TopAppBar/components/Search/Search.style.ts index 560bd264c..3960b9bde 100644 --- a/src/components/TopAppBar/components/Search/Search.style.ts +++ b/src/components/TopAppBar/components/Search/Search.style.ts @@ -42,8 +42,6 @@ export const searchWrapper = export const customInputStyle = (searchPlaceholder: string, isDark: boolean) => (theme: Theme) => { const baseInputStyles = inputStyle({ placeholder: searchPlaceholder, - size: 'sm', - isDark, })(theme); const rest = ` diff --git a/src/components/storyUtils/ColorUtility/ColorUtility.tsx b/src/components/storyUtils/ColorUtility/ColorUtility.tsx index 546bc9843..0bfcb7673 100644 --- a/src/components/storyUtils/ColorUtility/ColorUtility.tsx +++ b/src/components/storyUtils/ColorUtility/ColorUtility.tsx @@ -26,12 +26,7 @@ const ColorUtility = ({ defaultColor }: { defaultColor?: string }) => {
- +
normal : {color.normal}
diff --git a/src/components/storyUtils/EdgeCasesSelectShowcase/EdgeCasesSelectShowcase.tsx b/src/components/storyUtils/EdgeCasesSelectShowcase/EdgeCasesSelectShowcase.tsx index 7227ef687..43f268c03 100644 --- a/src/components/storyUtils/EdgeCasesSelectShowcase/EdgeCasesSelectShowcase.tsx +++ b/src/components/storyUtils/EdgeCasesSelectShowcase/EdgeCasesSelectShowcase.tsx @@ -31,7 +31,6 @@ const EdgeCasesSelectShowcase: React.FC = () => { ]} selectedOption={defaultValue} handleSelectedOption={handleSelectedOption} - styleType={'filled'} />
- - - + - - + ### Select with Label and Statuses -Select with Label and Statuses. Error and Hint are shown below for all 3 types filled, outlined, elevated +Select with Label and Statuses - - - - - + @@ -314,7 +237,6 @@ Simple select component where searched term is highlighted in options label={'Flavour'} options={options} handleSelectedOption={handleSelectedOption} - styleType={'filled'} /> @@ -332,7 +254,6 @@ Simple select component with grouped data and searchable input options={groupOptions} defaultValue={defaultGroupValue} handleSelectedOption={handleSelectedOption} - styleType={'filled'} hasHighlightSearch /> @@ -351,21 +272,6 @@ Not Searchable Select label={'Flavour'} options={options} handleSelectedOption={handleSelectedOption} - styleType={'filled'} - /> - @@ -383,21 +289,6 @@ Disabled option with helper text label={'Flavour'} options={optionsWithHelperInDisabled} handleSelectedOption={handleSelectedOption} - styleType={'filled'} - /> - diff --git a/src/components/TextArea/TextArea.stories.mdx b/src/components/TextArea/TextArea.stories.mdx index 7d51fbb37..e59fe961d 100644 --- a/src/components/TextArea/TextArea.stories.mdx +++ b/src/components/TextArea/TextArea.stories.mdx @@ -39,20 +39,6 @@ import { TextArea } from '@orfium/ictinus'; -# Text Area Types - -Regular TextArea and the 3 available types - filled, outlined, elevated - - - - -