diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e07e074f..14209689 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,6 +1,6 @@ module.exports = { extends: ['@deriv-com/eslint-config-deriv', 'eslint:recommended', 'plugin:react/recommended'], - plugins: ['simple-import-sort','sort-destructure-keys', 'typescript-sort-keys' ], + plugins: ['simple-import-sort', 'sort-destructure-keys', 'typescript-sort-keys'], rules: { 'global-require': 'off', '@typescript-eslint/array-type': 'error', diff --git a/.prettierrc b/.prettierrc index eac607cc..4ace530d 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,11 +1,11 @@ { - "endOfLine": "lf", - "singleQuote": true, - "useTabs": false, - "tabWidth": 4, - "trailingComma": "es5", - "printWidth": 120, - "jsxSingleQuote": true, - "arrowParens": "avoid", - "proseWrap": "preserve" + "endOfLine": "lf", + "singleQuote": true, + "useTabs": false, + "tabWidth": 4, + "trailingComma": "es5", + "printWidth": 120, + "jsxSingleQuote": true, + "arrowParens": "avoid", + "proseWrap": "preserve" } diff --git a/package-lock.json b/package-lock.json index 8cc059ee..fab5ffa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@babel/preset-env": "^7.24.5", "@deriv-com/api-hooks": "^0.1.19", - "@deriv-com/translations": "^1.2.0", + "@deriv-com/translations": "^1.2.3", "@deriv-com/ui": "^1.21.1", "@deriv-com/utils": "latest", "@deriv/deriv-api": "^1.0.15", @@ -2654,9 +2654,9 @@ } }, "node_modules/@deriv-com/translations": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@deriv-com/translations/-/translations-1.2.0.tgz", - "integrity": "sha512-iRM0Nv8eJjlauGhmIvHtX/ZGP5A6X4TFQvJWTwuSBn4xdVaEJ5s8aCdebNYYI24ITw6mKKxy2RzLjrc5cDcGAA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@deriv-com/translations/-/translations-1.2.3.tgz", + "integrity": "sha512-NVZ2Ut8e+rG2eYjQhzI0nESmENx5U6wkaVoTZhAfFwswKJfTwDcOJYtmLPpUgAPUcgUNrWRx1iH0o5zGhLTOxg==", "dependencies": { "@xmldom/xmldom": "^0.8.10", "commander": "^12.0.0", @@ -22647,9 +22647,9 @@ "requires": {} }, "@deriv-com/translations": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@deriv-com/translations/-/translations-1.2.0.tgz", - "integrity": "sha512-iRM0Nv8eJjlauGhmIvHtX/ZGP5A6X4TFQvJWTwuSBn4xdVaEJ5s8aCdebNYYI24ITw6mKKxy2RzLjrc5cDcGAA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@deriv-com/translations/-/translations-1.2.3.tgz", + "integrity": "sha512-NVZ2Ut8e+rG2eYjQhzI0nESmENx5U6wkaVoTZhAfFwswKJfTwDcOJYtmLPpUgAPUcgUNrWRx1iH0o5zGhLTOxg==", "requires": { "@rollup/rollup-linux-x64-gnu": "^4.17.1", "@xmldom/xmldom": "^0.8.10", diff --git a/package.json b/package.json index 50f91b17..1daa2d89 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "@babel/preset-env": "^7.24.5", "@deriv-com/api-hooks": "^0.1.19", - "@deriv-com/translations": "^1.2.0", + "@deriv-com/translations": "^1.2.3", "@deriv-com/ui": "^1.21.1", "@deriv-com/utils": "latest", "@deriv/deriv-api": "^1.0.15", diff --git a/postcss.config.cjs b/postcss.config.cjs index 4df9d3ba..aa03a623 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -1,6 +1,6 @@ module.exports = { - plugins: { - autoprefixer: {}, - tailwindcss: {}, - }, + plugins: { + autoprefixer: {}, + tailwindcss: {}, + }, }; diff --git a/src/App.tsx b/src/App.tsx index d8604477..18cbc2ff 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ const App = () => { return ( - + {isDesktop && } diff --git a/src/components/Dropdown/Dropdown.scss b/src/components/Dropdown/Dropdown.scss deleted file mode 100644 index 66f5c6f1..00000000 --- a/src/components/Dropdown/Dropdown.scss +++ /dev/null @@ -1,144 +0,0 @@ -.dropdown { - width: 100%; - position: relative; - cursor: pointer; - - &--disabled { - pointer-events: none; - - & label { - color: var(--system-light-5-active-background, #999); - } - } - - &__button { - all: unset; - right: 1.6rem; - transform: rotate(0); - transform-origin: 50% 45%; - transition: transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); - - &--active { - transform: rotate(180deg); - } - } - - &__content { - width: 100%; - background: var(--system-light-8-primary-background, #fff); - display: flex; - align-items: center; - - .textfield__field { - cursor: pointer; - } - } - - &__field { - position: absolute; - inset: 0; - min-width: 0; /* this is required to reset input's default width */ - padding-left: 2rem; - display: flex; - flex-grow: 1; - font-family: inherit; - outline: 0; - font-size: 1.4rem; - background-color: transparent; - color: var(--system-light-2-general-text, #333); - transition: border-color 0.2s; - cursor: unset; - user-select: none; - &::selection { - background-color: transparent; - } - - &::placeholder { - color: transparent; - } - } - - &__field:placeholder-shown ~ &__label { - font-size: 1.4rem; - cursor: text; - top: 30%; - padding: 0; - } - - &__field:placeholder-shown ~ &__label--with-icon { - left: 4.4rem; - } - - label, - &__field:focus ~ &__label { - position: absolute; - top: -0.5rem; - display: block; - transition: 0.2s; - font-size: 1rem; - color: var(--system-light-3-less-prominent-text, #999); - background: var(--system-light-8-primary-background, #fff); - padding-inline: 0.4rem; - left: 1.6rem; - } - - &__field:focus ~ &__label { - color: var(--brand-blue, #85acb0); - } - - &__items { - position: absolute; - top: 4.8rem; - width: 100%; - display: flex; - flex-direction: column; - align-items: flex-start; - z-index: 2; - border-radius: 0.4rem; - background: var(--system-light-8-primary-background, #fff); - box-shadow: 0 3.2rem 6.4rem 0 rgba(14, 14, 14, 0.14); - overflow-y: auto; - - & > :first-child { - border-radius: 0.4rem 0.4rem 0 0; - } - - & > :last-child { - border-radius: 0 0 0.4rem 0.4rem; - } - - &--sm { - max-height: 22rem; - } - - &--md { - max-height: 42rem; - } - - &--lg { - max-height: 66rem; - } - } - - &__icon { - position: absolute; - left: 1.6rem; - width: 1.6rem; - height: 1.6rem; - } - - &__item { - padding: 1rem 1.6rem; - width: 100%; - z-index: 2; - - &:hover:not(&--active) { - cursor: pointer; - background: var(--system-light-6-hover-background, #e6e9e9); - } - - &--active { - background: var(--system-light-5-active-background, #d6dadb); - } - } -} diff --git a/src/components/Dropdown/Dropdown.tsx b/src/components/Dropdown/Dropdown.tsx deleted file mode 100644 index 42885b1b..00000000 --- a/src/components/Dropdown/Dropdown.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import { FC, ReactNode, useCallback, useEffect, useState } from 'react'; -import clsx from 'clsx'; -import { useCombobox } from 'downshift'; -import { TextField } from '@/components'; -import { reactNodeToString } from '@/utils'; -import { LabelPairedChevronDownMdRegularIcon } from '@deriv/quill-icons'; -import { Text } from '@deriv-com/ui'; -import { TextFieldProps } from '../TextField/TextField'; -import './Dropdown.scss'; - -type TGenericSizes = '2xl' | '2xs' | '3xl' | '3xs' | '4xl' | '5xl' | '6xl' | 'lg' | 'md' | 'sm' | 'xl' | 'xs'; - -type TProps = { - disabled?: boolean; - errorMessage?: TextFieldProps['errorMessage']; - icon?: ReactNode; - isRequired?: boolean; - label?: TextFieldProps['label']; - list: { - text?: ReactNode; - value?: string; - }[]; - listHeight?: Extract; - name: TextFieldProps['name']; - onChange?: (inputValue: string) => void; - onSelect: (value: string) => void; - value?: TextFieldProps['value']; - variant?: 'comboBox' | 'prompt'; -}; - -const Dropdown: FC = ({ - disabled = false, - errorMessage = '', - icon = false, - isRequired = false, - label = '', - list, - listHeight = 'md', - name, - onChange = () => { - // do nothing - }, - onSelect, - value, - variant = 'prompt', -}) => { - const [items, setItems] = useState(list); - const [hasSelected, setHasSelected] = useState(false); - const [shouldFilterList, setShouldFilterList] = useState(false); - const clearFilter = useCallback(() => { - setShouldFilterList(false); - setItems(list); - }, [list]); - const { closeMenu, getInputProps, getItemProps, getMenuProps, getToggleButtonProps, isOpen, openMenu } = - useCombobox({ - defaultSelectedItem: items.find(item => item.value === value) ?? null, - items, - itemToString(item) { - return item ? reactNodeToString(item.text) : ''; - }, - onInputValueChange({ inputValue }) { - onChange?.(inputValue ?? ''); - if (shouldFilterList) { - setItems( - list.filter(item => - reactNodeToString(item.text) - .toLowerCase() - .includes(inputValue?.toLowerCase() ?? '') - ) - ); - } - }, - onIsOpenChange({ isOpen }) { - if (!isOpen) { - clearFilter(); - } - }, - onSelectedItemChange({ selectedItem }) { - onSelect(selectedItem?.value ?? ''); - closeMenu(); - }, - }); - - const handleInputClick = useCallback(() => { - variant === 'comboBox' && setShouldFilterList(true); - - if (isOpen) { - closeMenu(); - } else { - openMenu(); - } - }, [closeMenu, isOpen, openMenu, variant]); - - useEffect(() => { - setItems(list); - }, [list]); - - return ( -
-
- setHasSelected(true)} - onKeyUp={() => setShouldFilterList(true)} - placeholder={reactNodeToString(label)} - readOnly={variant !== 'comboBox'} - renderLeftIcon={icon ? () => icon : undefined} - renderRightIcon={() => ( - - )} - type='text' - value={value} - {...getInputProps()} - /> -
-
    - {isOpen && - items.map((item, index) => ( -
  • - - {item.text} - -
  • - ))} -
-
- ); -}; - -export default Dropdown; diff --git a/src/components/Dropdown/index.ts b/src/components/Dropdown/index.ts deleted file mode 100644 index 9f1f7763..00000000 --- a/src/components/Dropdown/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -// TODO: Delete this component once @deriv-com/ui has it published - -export { default as Dropdown } from './Dropdown'; diff --git a/src/components/PaymentMethodField/PaymentMethodField.tsx b/src/components/PaymentMethodField/PaymentMethodField.tsx index 44355d3c..07e8b73d 100644 --- a/src/components/PaymentMethodField/PaymentMethodField.tsx +++ b/src/components/PaymentMethodField/PaymentMethodField.tsx @@ -1,7 +1,7 @@ import { Controller, useForm } from 'react-hook-form'; import { VALID_SYMBOLS_PATTERN } from '@/constants'; -import { Input } from '@deriv-com/ui'; -import { TextArea } from '..'; +import { useTranslations } from '@deriv-com/translations'; +import { Input, TextArea } from '@deriv-com/ui'; type TPaymentMethodField = { control: ReturnType['control']; @@ -23,6 +23,7 @@ type TPaymentMethodField = { * @example * **/ const PaymentMethodField = ({ control, defaultValue, displayName, field, required }: TPaymentMethodField) => { + const { localize } = useTranslations(); return (
) : ( @@ -53,10 +55,13 @@ const PaymentMethodField = ({ control, defaultValue, displayName, field, require }} rules={{ pattern: { - message: `${displayName} can only include letters, numbers, spaces, and any of these symbols: -+.,'#@():;`, // TODO: Remember to translate this + message: localize( + "{{displayName}} can only include letters, numbers, spaces, and any of these symbols: -+.,'#@():;", + { displayName } + ), value: VALID_SYMBOLS_PATTERN, }, - required: required ? 'This field is required.' : false, + required: required ? localize('This field is required.') : false, }} />
diff --git a/src/components/TextArea/TextArea.scss b/src/components/TextArea/TextArea.scss deleted file mode 100644 index 8d0691d7..00000000 --- a/src/components/TextArea/TextArea.scss +++ /dev/null @@ -1,69 +0,0 @@ -.textarea { - position: relative; - width: 100%; - - & textarea { - resize: none; - width: 100%; - height: 9.6rem; - border-radius: 0.4rem; - border: 1px solid #d6dadb; - outline: none; - padding: 1rem 1.6rem; - font-size: 1.4rem; - - &:focus { - border: 1px solid #85acb0; - } - - &::placeholder { - color: #999999; - } - &:focus + label span { - color: #85acb0; - } - &:focus + label, - &[data-has-value='true'] + label { - transform: translate(0, -1.4rem) scale(0.75); - background-color: #ffffff; - } - &:not(:focus)[data-has-value='true'] + label { - & span { - color: #333; - } - } - &:has(~ label)::placeholder { - color: transparent; - } - } - - & label { - display: block; - position: absolute; - left: 1.6rem; - top: 1rem; - transition: all 0.2s ease; - transform-origin: left top; - text-overflow: ellipsis; - overflow: hidden; - } - - &--error { - & textarea, - & textarea:focus { - border: 1px solid #ec3f3f; - & + label span { - color: #ec3f3f; - } - } - } - - &__footer { - display: flex; - line-height: 1.5; - - & span { - margin-left: auto; - } - } -} diff --git a/src/components/TextArea/TextArea.tsx b/src/components/TextArea/TextArea.tsx deleted file mode 100644 index ad8d9568..00000000 --- a/src/components/TextArea/TextArea.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { ChangeEventHandler, HtmlHTMLAttributes, useState } from 'react'; -import clsx from 'clsx'; -import { Text } from '@deriv-com/ui'; -import './TextArea.scss'; - -type TTextAreaProps = HtmlHTMLAttributes & { - hint?: string; - isInvalid?: boolean; - label?: string; - maxLength?: number; - onChange: ChangeEventHandler; - placeholder?: string; - shouldShowCounter?: boolean; - testId?: string; - value?: string; -}; -const TextArea = ({ - hint, - isInvalid = false, - label, - maxLength, - onChange, - placeholder, - shouldShowCounter = false, - testId, - value, -}: TTextAreaProps) => { - const [currentValue, setCurrentValue] = useState(value); - - return ( -
-