From ca0215d0a5257a044b388da231a6746b2bd21851 Mon Sep 17 00:00:00 2001 From: Joanna S <37884374+JoannaSikora@users.noreply.github.com> Date: Thu, 30 Jan 2025 09:49:23 +0100 Subject: [PATCH 01/11] feat(Icons): add new icon WhatsAppColored (#1504) --- packages/icons/svg/whats-app-colored.svg | 26 +++++++++++++++++++ .../components/Icon/IconsShowcase/constans.ts | 11 ++++---- 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 packages/icons/svg/whats-app-colored.svg diff --git a/packages/icons/svg/whats-app-colored.svg b/packages/icons/svg/whats-app-colored.svg new file mode 100644 index 000000000..1559a3509 --- /dev/null +++ b/packages/icons/svg/whats-app-colored.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/react-components/src/components/Icon/IconsShowcase/constans.ts b/packages/react-components/src/components/Icon/IconsShowcase/constans.ts index 8d4067d0d..5b67df9c7 100644 --- a/packages/react-components/src/components/Icon/IconsShowcase/constans.ts +++ b/packages/react-components/src/components/Icon/IconsShowcase/constans.ts @@ -42,6 +42,8 @@ export const IconsData: Record = { CaretDownFilled: IconGroup.Arrows, CaretUp: IconGroup.Arrows, CaretUpFilled: IconGroup.Arrows, + ArrowsDiagonalMinimize: IconGroup.Arrows, + ArrowsDiagonal: IconGroup.Arrows, //FileType FiletypeExe: IconGroup.FileType, @@ -457,6 +459,9 @@ export const IconsData: Record = { TrendingUp: IconGroup.General, ZoomIn: IconGroup.General, ZoomOut: IconGroup.General, + LayoutSidebarLeft: IconGroup.General, + SquareRoundedPlusFilled: IconGroup.General, + SquareRoundedPlus: IconGroup.General, //Brands ChipCopilotColored: IconGroup.Brands, @@ -527,12 +532,8 @@ export const IconsData: Record = { Hubspot: IconGroup.Brands, Stripe: IconGroup.Brands, Mailchimp: IconGroup.Brands, - LayoutSidebarLeft: IconGroup.General, + WhatsAppColored: IconGroup.Brands, TextAccounts: IconGroup.Brands, TextLogoFull: IconGroup.Brands, TextPlatform: IconGroup.Brands, - SquareRoundedPlusFilled: IconGroup.General, - SquareRoundedPlus: IconGroup.General, - ArrowsDiagonalMinimize: IconGroup.Arrows, - ArrowsDiagonal: IconGroup.Arrows, }; From 009a88a42ff477b10d49985011da535210e4d7bc Mon Sep 17 00:00:00 2001 From: Joanna S <37884374+JoannaSikora@users.noreply.github.com> Date: Thu, 30 Jan 2025 10:11:40 +0100 Subject: [PATCH 02/11] feat(Typography): add 3xs heading size (#1503) --- .../src/components/Typography/Heading.tsx | 2 ++ .../src/components/Typography/Typography.module.scss | 12 ++++++++++++ .../src/components/Typography/index.ts | 1 + .../src/components/Typography/types.ts | 11 ++++++++++- .../Typography/components/HeadingExamples.tsx | 12 +++++------- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/react-components/src/components/Typography/Heading.tsx b/packages/react-components/src/components/Typography/Heading.tsx index b8e161426..0778a6378 100644 --- a/packages/react-components/src/components/Typography/Heading.tsx +++ b/packages/react-components/src/components/Typography/Heading.tsx @@ -13,6 +13,8 @@ const SIZE_TO_ELEMENT_MAP = { sm: 'h4', xs: 'h5', ['2xs']: 'h6', + // HTML only provides h1-h6 elements, so smaller heading sizes reuse h6 + ['3xs']: 'h6', }; interface IProps extends React.HTMLAttributes { diff --git a/packages/react-components/src/components/Typography/Typography.module.scss b/packages/react-components/src/components/Typography/Typography.module.scss index dcf210815..5168ab030 100644 --- a/packages/react-components/src/components/Typography/Typography.module.scss +++ b/packages/react-components/src/components/Typography/Typography.module.scss @@ -46,6 +46,14 @@ font-style: normal; } +@mixin heading-3xs { + line-height: 20px; + letter-spacing: 0.2px; + font-size: 10px; + font-weight: 400; + font-style: normal; +} + @mixin heading-uppercase { text-transform: uppercase; letter-spacing: 0.2px; @@ -137,6 +145,10 @@ @include heading-2xs; } +.heading-3xs { + @include heading-3xs; +} + .heading-uppercase { @include heading-uppercase; } diff --git a/packages/react-components/src/components/Typography/index.ts b/packages/react-components/src/components/Typography/index.ts index bd624ec78..3259246ba 100644 --- a/packages/react-components/src/components/Typography/index.ts +++ b/packages/react-components/src/components/Typography/index.ts @@ -2,3 +2,4 @@ export { Heading } from './Heading'; export { Text } from './Text'; export { Display } from './Display'; export type { THeadingSize, TTextSize, TDisplaySize } from './types'; +export { HEADING_SIZES } from './types'; diff --git a/packages/react-components/src/components/Typography/types.ts b/packages/react-components/src/components/Typography/types.ts index 4beed1c3f..19ee33870 100644 --- a/packages/react-components/src/components/Typography/types.ts +++ b/packages/react-components/src/components/Typography/types.ts @@ -1,4 +1,13 @@ export type TTextSize = 'xs' | 'sm' | 'md' | 'lg'; -export type THeadingSize = '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'; +export const HEADING_SIZES = [ + 'xl', + 'lg', + 'md', + 'sm', + 'xs', + '2xs', + '3xs', +] as const; +export type THeadingSize = (typeof HEADING_SIZES)[number]; export type TDisplaySize = 'sm' | 'md' | 'lg' | 'max'; export type TTextAlign = 'left' | 'right' | 'center' | 'justify'; diff --git a/packages/react-components/src/stories/foundations/Typography/components/HeadingExamples.tsx b/packages/react-components/src/stories/foundations/Typography/components/HeadingExamples.tsx index 5e2ea1136..b64f6e568 100644 --- a/packages/react-components/src/stories/foundations/Typography/components/HeadingExamples.tsx +++ b/packages/react-components/src/stories/foundations/Typography/components/HeadingExamples.tsx @@ -1,15 +1,13 @@ import * as React from 'react'; -import { Heading, THeadingSize } from '../../../../components/Typography'; - -const SIZES_MAP = ['xl', 'lg', 'md', 'sm', 'xs', '2xs'] as THeadingSize[]; +import { Heading, HEADING_SIZES } from '../../../../components/Typography'; export const HeadingExamples: React.FC = () => { - const elements = SIZES_MAP.map((size) => { + const elements = HEADING_SIZES.map((size) => { return ( - <> + Heading {size.toUpperCase()} - {size === '2xs' && ( + {['2xs', '3xs'].includes(size) && ( <> Heading {size.toUpperCase()} with uppercase @@ -19,7 +17,7 @@ export const HeadingExamples: React.FC = () => { )} - + ); }); From 090918a421d6db8dd2390434a42b9690074c9fa0 Mon Sep 17 00:00:00 2001 From: Joanna S <37884374+JoannaSikora@users.noreply.github.com> Date: Thu, 30 Jan 2025 11:28:36 +0100 Subject: [PATCH 03/11] feat(FormField, Input, NumericInput, TagInput, Picker, Textarea, Autocomplete): add readonly state (#1497) --- .../AutoComplete/AutoComplete.stories.tsx | 9 ++ .../components/AutoComplete/AutoComplete.tsx | 14 +++ .../src/components/AutoComplete/types.ts | 4 + .../components/Checkbox/Checkbox.module.scss | 21 ++++ .../components/Checkbox/Checkbox.stories.tsx | 14 +++ .../src/components/Checkbox/Checkbox.tsx | 9 ++ .../FormField/FormField.module.scss | 12 +- .../FormField/FormField.stories.tsx | 114 ++++++++++++++++++ .../src/components/FormField/FormField.tsx | 40 +++++- .../src/components/Input/Input.module.scss | 5 - .../src/components/Input/Input.stories.tsx | 10 ++ .../src/components/Input/Input.tsx | 15 ++- .../src/components/Input/types.ts | 4 + .../NumericInput/NumericInput.stories.tsx | 5 + .../components/NumericInput/NumericInput.tsx | 15 +++ .../src/components/Picker/Picker.stories.tsx | 11 ++ .../src/components/Picker/Picker.tsx | 18 +++ .../src/components/Picker/types.ts | 4 + .../RadioButton/RadioButton.module.scss | 20 ++- .../RadioButton/RadioButton.stories.tsx | 23 ++++ .../components/RadioButton/RadioButton.tsx | 6 + .../components/ReadOnlyText/ReadOnlyText.tsx | 38 ++++++ .../src/components/ReadOnlyText/index.ts | 2 + .../components/TagInput/TagInput.stories.tsx | 6 + .../src/components/TagInput/TagInput.tsx | 19 +++ .../src/components/TagInput/types.ts | 4 + .../components/Textarea/Textarea.stories.tsx | 3 + .../src/components/Textarea/Textarea.tsx | 19 ++- .../providers/ReadOnlyFormFieldProvider.tsx | 43 +++++++ 29 files changed, 492 insertions(+), 15 deletions(-) create mode 100644 packages/react-components/src/components/ReadOnlyText/ReadOnlyText.tsx create mode 100644 packages/react-components/src/components/ReadOnlyText/index.ts create mode 100644 packages/react-components/src/providers/ReadOnlyFormFieldProvider.tsx diff --git a/packages/react-components/src/components/AutoComplete/AutoComplete.stories.tsx b/packages/react-components/src/components/AutoComplete/AutoComplete.stories.tsx index bdac8785e..1501fd231 100644 --- a/packages/react-components/src/components/AutoComplete/AutoComplete.stories.tsx +++ b/packages/react-components/src/components/AutoComplete/AutoComplete.stories.tsx @@ -126,6 +126,15 @@ export const Examples = (): React.ReactElement => { + + + + ); }; diff --git a/packages/react-components/src/components/AutoComplete/AutoComplete.tsx b/packages/react-components/src/components/AutoComplete/AutoComplete.tsx index 4e25a1fba..ecc042da5 100644 --- a/packages/react-components/src/components/AutoComplete/AutoComplete.tsx +++ b/packages/react-components/src/components/AutoComplete/AutoComplete.tsx @@ -2,12 +2,14 @@ import * as React from 'react'; import { FloatingNode, FloatingPortal } from '@floating-ui/react'; +import { useReadOnlyFormFieldContext } from '../../providers/ReadOnlyFormFieldProvider'; import noop from '../../utils/noop'; import { Input } from '../Input'; import { IPickerListItem, PickerList } from '../Picker'; import { DEFAULT_LIST_HEIGHT, MIN_LIST_HEIGHT } from '../Picker/constants'; import { useFloatingPicker } from '../Picker/hooks/useFloatingPicker'; import { usePickerItems } from '../Picker/hooks/usePickerItems'; +import { ReadOnlyText } from '../ReadOnlyText'; import { areAllOptionsStrings, @@ -44,11 +46,14 @@ export const AutoComplete = React.forwardRef< single, alwaysShowAllOptions, hideIfExactMatch = true, + noDataFallbackText = 'No data', ...inputProps }, ref ) => { const inputRef = React.useRef(null); + const { readOnly: readOnlyContext } = useReadOnlyFormFieldContext(); + const computedReadOnly = readOnlyContext || readOnly; React.useImperativeHandle(ref, () => inputRef.current!, []); @@ -158,6 +163,15 @@ export const AutoComplete = React.forwardRef< floatingStrategy, }); + if (computedReadOnly) { + return ( + + ); + } + return (
{ single?: boolean; /** If true, the option list will be hidden if there is only one option and it is an exact match to the input value. */ hideIfExactMatch?: boolean; + /** + * Set the text to display with read-only state when there is no data. Default to 'No data' + */ + noDataFallbackText?: string; } diff --git a/packages/react-components/src/components/Checkbox/Checkbox.module.scss b/packages/react-components/src/components/Checkbox/Checkbox.module.scss index e54e7ee46..ec3e80440 100644 --- a/packages/react-components/src/components/Checkbox/Checkbox.module.scss +++ b/packages/react-components/src/components/Checkbox/Checkbox.module.scss @@ -98,6 +98,27 @@ } } + &--read-only { + .checkbox { + &__input { + border-color: var(--border-basic-secondary); + background-color: var(--surface-primary-default); + + &::after { + background-color: var(--content-basic-primary); + } + } + + &__label, + &__input, + &__helper, + &__text { + cursor: default; + pointer-events: none; + } + } + } + &--selected { &:hover { .checkbox__input:checked + .checkbox__square { diff --git a/packages/react-components/src/components/Checkbox/Checkbox.stories.tsx b/packages/react-components/src/components/Checkbox/Checkbox.stories.tsx index 3dcb0c7c1..9f8fa6a84 100644 --- a/packages/react-components/src/components/Checkbox/Checkbox.stories.tsx +++ b/packages/react-components/src/components/Checkbox/Checkbox.stories.tsx @@ -38,6 +38,9 @@ export const States = (): React.ReactElement => ( Checkbox label + + Checkbox label + @@ -46,6 +49,9 @@ export const States = (): React.ReactElement => ( Checkbox label + + Checkbox label + ( > Checkbox label + + Checkbox label + ); diff --git a/packages/react-components/src/components/Checkbox/Checkbox.tsx b/packages/react-components/src/components/Checkbox/Checkbox.tsx index 5d294663a..2b8473625 100644 --- a/packages/react-components/src/components/Checkbox/Checkbox.tsx +++ b/packages/react-components/src/components/Checkbox/Checkbox.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import cx from 'clsx'; +import { useReadOnlyFormFieldContext } from '../../providers/ReadOnlyFormFieldProvider'; import { FieldDescription } from '../FieldDescription'; import { Text } from '../Typography'; @@ -12,6 +13,10 @@ export interface CheckboxProps extends React.HTMLAttributes { * Specify whether the checkbox should be disabled */ disabled?: boolean; + /** + * Specify whether the checkbox should be read only + */ + readOnly?: boolean; /** * Specify whether the checkbox should be checked */ @@ -41,12 +46,16 @@ export const Checkbox = React.forwardRef( }, ref ) => { + const { readOnly } = useReadOnlyFormFieldContext(); + const computedReadOnly = readOnly || restInputProps.readOnly; + return (