@alfalab/core-components-bank-card 6.0.1 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/Component.d.ts +2 -2
  2. package/Component.js.map +1 -1
  3. package/cssm/Component.d.ts +2 -2
  4. package/cssm/Component.js.map +1 -1
  5. package/cssm/helpers/getDefaultInputLabel.d.ts +1 -1
  6. package/cssm/helpers/getDefaultInputLabel.js.map +1 -1
  7. package/cssm/index.module.css +21 -12
  8. package/esm/Component.d.ts +2 -2
  9. package/esm/Component.js.map +1 -1
  10. package/esm/helpers/getDefaultInputLabel.d.ts +1 -1
  11. package/esm/helpers/getDefaultInputLabel.js.map +1 -1
  12. package/esm/index.css +40 -31
  13. package/esm/index.module.css.js +1 -1
  14. package/esm/index.module.css.js.map +1 -1
  15. package/helpers/getDefaultInputLabel.d.ts +1 -1
  16. package/helpers/getDefaultInputLabel.js.map +1 -1
  17. package/index.css +40 -31
  18. package/index.module.css.js +1 -1
  19. package/index.module.css.js.map +1 -1
  20. package/modern/Component.d.ts +2 -2
  21. package/modern/Component.js.map +1 -1
  22. package/modern/helpers/getDefaultInputLabel.d.ts +1 -1
  23. package/modern/helpers/getDefaultInputLabel.js.map +1 -1
  24. package/modern/index.css +40 -31
  25. package/modern/index.module.css.js +1 -1
  26. package/modern/index.module.css.js.map +1 -1
  27. package/moderncssm/Component.d.ts +2 -2
  28. package/moderncssm/Component.js.map +1 -1
  29. package/moderncssm/helpers/getDefaultInputLabel.d.ts +1 -1
  30. package/moderncssm/helpers/getDefaultInputLabel.js.map +1 -1
  31. package/moderncssm/index.module.css +20 -29
  32. package/package.json +3 -3
  33. package/src/Component.tsx +4 -4
  34. package/src/helpers/{getDefaultInputLabel.tsx → getDefaultInputLabel.ts} +1 -1
  35. package/src/index.module.css +3 -3
package/Component.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import React, { ChangeEvent, MouseEvent, ReactNode } from 'react';
2
- import { MaskType } from './types';
1
+ import React, { type ChangeEvent, type MouseEvent, type ReactNode } from 'react';
2
+ import { type MaskType } from './types';
3
3
  export declare type BankCardProps = {
4
4
  /**
5
5
  * Дополнительный класс
package/Component.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Component.js","sources":["src/Component.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":["validateCardNumber","React","MirXxlIcon","VisaXxlIcon","MastercardLIcon","forwardRef","AlfaBankSignMIcon","MaskTypeEnum","getDefaultInputLabel","useState","useCallback","styles","CameraMIcon","useEffect","cn","MaskedInput"],"mappings":"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"}
1
+ {"version":3,"file":"Component.js","sources":["src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { type MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":["validateCardNumber","React","MirXxlIcon","VisaXxlIcon","MastercardLIcon","forwardRef","AlfaBankSignMIcon","MaskTypeEnum","getDefaultInputLabel","useState","useCallback","styles","CameraMIcon","useEffect","cn","MaskedInput"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import React, { ChangeEvent, MouseEvent, ReactNode } from 'react';
2
- import { MaskType } from './types';
1
+ import React, { type ChangeEvent, type MouseEvent, type ReactNode } from 'react';
2
+ import { type MaskType } from './types';
3
3
  export declare type BankCardProps = {
4
4
  /**
5
5
  * Дополнительный класс
@@ -1 +1 @@
1
- {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":["validateCardNumber","React","MirXxlIcon","VisaXxlIcon","MastercardLIcon","forwardRef","AlfaBankSignMIcon","MaskTypeEnum","getDefaultInputLabel","useState","useCallback","styles","CameraMIcon","useEffect","cn","MaskedInput"],"mappings":"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"}
1
+ {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { type MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":["validateCardNumber","React","MirXxlIcon","VisaXxlIcon","MastercardLIcon","forwardRef","AlfaBankSignMIcon","MaskTypeEnum","getDefaultInputLabel","useState","useCallback","styles","CameraMIcon","useEffect","cn","MaskedInput"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { MaskType } from '../types';
1
+ import { type MaskType } from '../types';
2
2
  export declare const getDefaultInputLabel: (maskType: MaskType) => "Номер карты" | "Номер счёта" | "Номер карты или счёта";
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.tsx"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":["MaskTypeEnum"],"mappings":";;;;;;AAGO,IAAM,oBAAoB,GAAG,UAAC,QAAkB,EAAA;AACnD,IAAA,QAAQ,QAAQ;QACZ,KAAKA,kBAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
1
+ {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.ts"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { type MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":["MaskTypeEnum"],"mappings":";;;;;;AAGO,IAAM,oBAAoB,GAAG,UAAC,QAAkB,EAAA;AACnD,IAAA,QAAQ,QAAQ;QACZ,KAAKA,kBAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
@@ -15,8 +15,9 @@
15
15
  --gap-16: var(--gap-m);
16
16
  --gap-20: var(--gap-l);
17
17
  } :root {
18
- --font-family-styrene: 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto,
19
- 'Helvetica Neue', Helvetica, sans-serif;
18
+ --font-family-styrene:
19
+ 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica,
20
+ sans-serif;
20
21
  } .component {
21
22
  --form-control-border-radius: 0;
22
23
  --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);
@@ -49,18 +50,26 @@
49
50
  left: var(--gap-0);
50
51
  transform: translateY(-1px);
51
52
  color: var(--color-light-text-secondary);
53
+
52
54
  font-size: 20px;
53
- line-height: 24px
55
+
56
+ line-height: 24px;
57
+
58
+ font-weight: 400;
59
+
60
+ font-feature-settings: 'ss01';
61
+
62
+ font-family: var(--font-family-styrene);
54
63
  } @media (max-width: 360px) { .label {
55
- font-size: 16px
64
+ font-size: 16px;
56
65
  }
57
66
  } .focused .label,
58
67
  .filled .label {
59
68
  color: var(--color-light-neutral-translucent-1300);
60
- transform: translateY(-19px) scale(0.6)
69
+ transform: translateY(-19px) scale(0.6);
61
70
  } @media (max-width: 360px) { .focused .label,
62
71
  .filled .label {
63
- transform: translateY(-22px) scale(0.75)
72
+ transform: translateY(-22px) scale(0.75);
64
73
  }
65
74
  } .focused:before {
66
75
  transform: scale(1) !important;
@@ -74,22 +83,22 @@
74
83
  color: var(--color-light-neutral-translucent-1300);
75
84
  caret-color: var(--color-light-neutral-translucent-1300);
76
85
  padding-left: var(--gap-0) !important;
77
- padding-bottom: var(--gap-4) !important
86
+ padding-bottom: var(--gap-4) !important;
78
87
  } @media (max-width: 360px) { .input {
79
- font-size: 16px
88
+ font-size: 16px;
80
89
  }
81
90
  } .bankLogo {
82
91
  position: absolute;
83
92
  top: var(--gap-16);
84
- left: var(--gap-16)
93
+ left: var(--gap-16);
85
94
  } .bankLogo svg {
86
- display: block
95
+ display: block;
87
96
  } .bankLogo svg g {
88
97
  fill: var(--color-light-neutral-translucent-1300);
89
98
  } .brandLogo {
90
99
  position: absolute;
91
100
  bottom: var(--gap-20);
92
- right: var(--gap-20)
101
+ right: var(--gap-20);
93
102
  } .brandLogo svg {
94
103
  display: block;
95
104
  fill: var(--color-light-neutral-translucent-1300);
@@ -108,7 +117,7 @@
108
117
  outline: none;
109
118
  margin-bottom: var(--gap-4);
110
119
  align-self: flex-end;
111
- margin-right: calc(var(--gap-12) * -1)
120
+ margin-right: calc(var(--gap-12) * -1);
112
121
  } .usePhoto svg {
113
122
  fill: var(--color-light-neutral-translucent-1300);
114
123
  display: block;
@@ -1,5 +1,5 @@
1
- import React, { ChangeEvent, MouseEvent, ReactNode } from 'react';
2
- import { MaskType } from './types';
1
+ import React, { type ChangeEvent, type MouseEvent, type ReactNode } from 'react';
2
+ import { type MaskType } from './types';
3
3
  export declare type BankCardProps = {
4
4
  /**
5
5
  * Дополнительный класс
@@ -1 +1 @@
1
- {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { type MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { MaskType } from '../types';
1
+ import { type MaskType } from '../types';
2
2
  export declare const getDefaultInputLabel: (maskType: MaskType) => "Номер карты" | "Номер счёта" | "Номер карты или счёта";
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.tsx"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":[],"mappings":";;AAGO,IAAM,oBAAoB,GAAG,UAAC,QAAkB,EAAA;AACnD,IAAA,QAAQ,QAAQ;QACZ,KAAK,YAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
1
+ {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.ts"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { type MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":[],"mappings":";;AAGO,IAAM,oBAAoB,GAAG,UAAC,QAAkB,EAAA;AACnD,IAAA,QAAQ,QAAQ;QACZ,KAAK,YAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
package/esm/index.css CHANGED
@@ -15,9 +15,10 @@
15
15
  --gap-16: var(--gap-m);
16
16
  --gap-20: var(--gap-l);
17
17
  } :root {
18
- --font-family-styrene: 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto,
19
- 'Helvetica Neue', Helvetica, sans-serif;
20
- } .bank-card__component_1e5wo {
18
+ --font-family-styrene:
19
+ 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica,
20
+ sans-serif;
21
+ } .bank-card__component_1ww0x {
21
22
  --form-control-border-radius: 0;
22
23
  --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);
23
24
  --form-control-bg-color: transparent;
@@ -31,9 +32,9 @@
31
32
  max-width: 343px;
32
33
 
33
34
  font-family: var(--font-family-styrene);
34
- } .bank-card__aspectRatioContainer_1e5wo {
35
+ } .bank-card__aspectRatioContainer_1ww0x {
35
36
  padding-bottom: 63%;
36
- } .bank-card__content_1e5wo {
37
+ } .bank-card__content_1ww0x {
37
38
  position: absolute;
38
39
  top: var(--gap-0);
39
40
  right: var(--gap-0);
@@ -45,26 +46,34 @@
45
46
  padding-right: var(--gap-20);
46
47
  border-radius: var(--border-radius-12);
47
48
  box-sizing: border-box;
48
- } .bank-card__label_1e5wo {
49
+ } .bank-card__label_1ww0x {
49
50
  left: var(--gap-0);
50
51
  transform: translateY(-1px);
51
52
  color: var(--color-light-text-secondary);
53
+
52
54
  font-size: 20px;
53
- line-height: 24px
54
- } @media (max-width: 360px) { .bank-card__label_1e5wo {
55
- font-size: 16px
55
+
56
+ line-height: 24px;
57
+
58
+ font-weight: 400;
59
+
60
+ font-feature-settings: 'ss01';
61
+
62
+ font-family: var(--font-family-styrene);
63
+ } @media (max-width: 360px) { .bank-card__label_1ww0x {
64
+ font-size: 16px;
56
65
  }
57
- } .bank-card__focused_1e5wo .bank-card__label_1e5wo,
58
- .bank-card__filled_1e5wo .bank-card__label_1e5wo {
66
+ } .bank-card__focused_1ww0x .bank-card__label_1ww0x,
67
+ .bank-card__filled_1ww0x .bank-card__label_1ww0x {
59
68
  color: var(--color-light-neutral-translucent-1300);
60
- transform: translateY(-19px) scale(0.6)
61
- } @media (max-width: 360px) { .bank-card__focused_1e5wo .bank-card__label_1e5wo,
62
- .bank-card__filled_1e5wo .bank-card__label_1e5wo {
63
- transform: translateY(-22px) scale(0.75)
69
+ transform: translateY(-19px) scale(0.6);
70
+ } @media (max-width: 360px) { .bank-card__focused_1ww0x .bank-card__label_1ww0x,
71
+ .bank-card__filled_1ww0x .bank-card__label_1ww0x {
72
+ transform: translateY(-22px) scale(0.75);
64
73
  }
65
- } .bank-card__focused_1e5wo:before {
74
+ } .bank-card__focused_1ww0x:before {
66
75
  transform: scale(1) !important;
67
- } .bank-card__input_1e5wo {
76
+ } .bank-card__input_1ww0x {
68
77
  font-size: 20px;
69
78
  line-height: 24px;
70
79
  font-weight: 400;
@@ -74,26 +83,26 @@
74
83
  color: var(--color-light-neutral-translucent-1300);
75
84
  caret-color: var(--color-light-neutral-translucent-1300);
76
85
  padding-left: var(--gap-0) !important;
77
- padding-bottom: var(--gap-4) !important
78
- } @media (max-width: 360px) { .bank-card__input_1e5wo {
79
- font-size: 16px
86
+ padding-bottom: var(--gap-4) !important;
87
+ } @media (max-width: 360px) { .bank-card__input_1ww0x {
88
+ font-size: 16px;
80
89
  }
81
- } .bank-card__bankLogo_1e5wo {
90
+ } .bank-card__bankLogo_1ww0x {
82
91
  position: absolute;
83
92
  top: var(--gap-16);
84
- left: var(--gap-16)
85
- } .bank-card__bankLogo_1e5wo svg {
86
- display: block
87
- } .bank-card__bankLogo_1e5wo svg g {
93
+ left: var(--gap-16);
94
+ } .bank-card__bankLogo_1ww0x svg {
95
+ display: block;
96
+ } .bank-card__bankLogo_1ww0x svg g {
88
97
  fill: var(--color-light-neutral-translucent-1300);
89
- } .bank-card__brandLogo_1e5wo {
98
+ } .bank-card__brandLogo_1ww0x {
90
99
  position: absolute;
91
100
  bottom: var(--gap-20);
92
- right: var(--gap-20)
93
- } .bank-card__brandLogo_1e5wo svg {
101
+ right: var(--gap-20);
102
+ } .bank-card__brandLogo_1ww0x svg {
94
103
  display: block;
95
104
  fill: var(--color-light-neutral-translucent-1300);
96
- } .bank-card__usePhoto_1e5wo {
105
+ } .bank-card__usePhoto_1ww0x {
97
106
  display: block;
98
107
  margin: var(--gap-0);
99
108
  padding: var(--gap-0);
@@ -108,8 +117,8 @@
108
117
  outline: none;
109
118
  margin-bottom: var(--gap-4);
110
119
  align-self: flex-end;
111
- margin-right: calc(var(--gap-12) * -1)
112
- } .bank-card__usePhoto_1e5wo svg {
120
+ margin-right: calc(var(--gap-12) * -1);
121
+ } .bank-card__usePhoto_1ww0x svg {
113
122
  fill: var(--color-light-neutral-translucent-1300);
114
123
  display: block;
115
124
  }
@@ -1,6 +1,6 @@
1
1
  import './index.css';
2
2
 
3
- var styles = {"component":"bank-card__component_1e5wo","aspectRatioContainer":"bank-card__aspectRatioContainer_1e5wo","content":"bank-card__content_1e5wo","label":"bank-card__label_1e5wo","focused":"bank-card__focused_1e5wo","filled":"bank-card__filled_1e5wo","input":"bank-card__input_1e5wo","bankLogo":"bank-card__bankLogo_1e5wo","brandLogo":"bank-card__brandLogo_1e5wo","usePhoto":"bank-card__usePhoto_1e5wo"};
3
+ var styles = {"component":"bank-card__component_1ww0x","aspectRatioContainer":"bank-card__aspectRatioContainer_1ww0x","content":"bank-card__content_1ww0x","label":"bank-card__label_1ww0x","focused":"bank-card__focused_1ww0x","filled":"bank-card__filled_1ww0x","input":"bank-card__input_1ww0x","bankLogo":"bank-card__bankLogo_1ww0x","brandLogo":"bank-card__brandLogo_1ww0x","usePhoto":"bank-card__usePhoto_1ww0x"};
4
4
 
5
5
  export { styles as default };
6
6
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n/* purgecss ignore */\n.component {\n /* TODO: как это будет собираться и работать в webView */\n --form-control-border-radius: 0;\n --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);\n --form-control-bg-color: transparent;\n\n /* focus */\n --form-control-focus-border-bottom: 1px solid var(--color-light-neutral-translucent-1300);\n --form-control-focus-shadow: transparent;\n\n /* hover */\n --form-control-hover-bg-color: transparent;\n --form-control-focus-bg-color: transparent;\n --form-control-font-family: var(--font-family-styrene);\n\n position: relative;\n max-width: 343px;\n\n font-family: var(--font-family-styrene);\n}\n\n.aspectRatioContainer {\n /* Эталонный размер 343x216 */\n padding-bottom: 63%;\n}\n\n.content {\n position: absolute;\n top: var(--gap-0);\n right: var(--gap-0);\n bottom: var(--gap-0);\n left: var(--gap-0);\n display: flex;\n align-items: center;\n padding-left: var(--gap-20);\n padding-right: var(--gap-20);\n border-radius: var(--border-radius-12);\n box-sizing: border-box;\n}\n\n.label {\n left: var(--gap-0);\n transform: translateY(-1px);\n color: var(--color-light-text-secondary);\n font-size: 20px;\n line-height: 24px;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.focused .label,\n.filled .label {\n color: var(--color-light-neutral-translucent-1300);\n transform: translateY(-19px) scale(0.6);\n\n @media (max-width: 360px) {\n transform: translateY(-22px) scale(0.75);\n }\n}\n\n.focused:before {\n transform: scale(1) !important;\n}\n\n.input {\n @mixin promo_xsmall;\n\n color: var(--color-light-neutral-translucent-1300);\n caret-color: var(--color-light-neutral-translucent-1300);\n\n /* TODO: обсудить с дизайнером, почему инпут не соответствует дизайн-системе, либо уменьшить каскад в form-control */\n padding-left: var(--gap-0) !important;\n padding-bottom: var(--gap-4) !important;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.bankLogo {\n position: absolute;\n top: var(--gap-16);\n left: var(--gap-16);\n\n & svg {\n display: block;\n\n & g {\n fill: var(--color-light-neutral-translucent-1300);\n }\n }\n}\n\n.brandLogo {\n position: absolute;\n bottom: var(--gap-20);\n right: var(--gap-20);\n\n & svg {\n display: block;\n fill: var(--color-light-neutral-translucent-1300);\n }\n}\n\n.usePhoto {\n display: block;\n margin: var(--gap-0);\n padding: var(--gap-0);\n text-decoration: none;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n user-select: none;\n cursor: pointer;\n outline: none;\n margin-bottom: var(--gap-4);\n align-self: flex-end;\n\n /* В макете иконка прилегает к правому краю поля, а по дизайн-системе там должен быть отступ */\n margin-right: calc(var(--gap-12) * -1);\n\n & svg {\n fill: var(--color-light-neutral-translucent-1300);\n display: block;\n }\n}\n"],"names":[],"mappings":";;AAEgB,aAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,sBAAsB,CAAC,uCAAuC,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,wBAAwB,CAAC,UAAU,CAAC,2BAA2B,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,CAAC,2BAA2B,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/no-typography-index.css';\n\n/* purgecss ignore */\n.component {\n /* TODO: как это будет собираться и работать в webView */\n --form-control-border-radius: 0;\n --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);\n --form-control-bg-color: transparent;\n\n /* focus */\n --form-control-focus-border-bottom: 1px solid var(--color-light-neutral-translucent-1300);\n --form-control-focus-shadow: transparent;\n\n /* hover */\n --form-control-hover-bg-color: transparent;\n --form-control-focus-bg-color: transparent;\n --form-control-font-family: var(--font-family-styrene);\n\n position: relative;\n max-width: 343px;\n\n font-family: var(--font-family-styrene);\n}\n\n.aspectRatioContainer {\n /* Эталонный размер 343x216 */\n padding-bottom: 63%;\n}\n\n.content {\n position: absolute;\n top: var(--gap-0);\n right: var(--gap-0);\n bottom: var(--gap-0);\n left: var(--gap-0);\n display: flex;\n align-items: center;\n padding-left: var(--gap-20);\n padding-right: var(--gap-20);\n border-radius: var(--border-radius-12);\n box-sizing: border-box;\n}\n\n.label {\n left: var(--gap-0);\n transform: translateY(-1px);\n color: var(--color-light-text-secondary);\n\n @mixin promo_xsmall;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.focused .label,\n.filled .label {\n color: var(--color-light-neutral-translucent-1300);\n transform: translateY(-19px) scale(0.6);\n\n @media (max-width: 360px) {\n transform: translateY(-22px) scale(0.75);\n }\n}\n\n.focused:before {\n transform: scale(1) !important;\n}\n\n.input {\n @mixin promo_xsmall;\n\n color: var(--color-light-neutral-translucent-1300);\n caret-color: var(--color-light-neutral-translucent-1300);\n\n /* TODO: обсудить с дизайнером, почему инпут не соответствует дизайн-системе, либо уменьшить каскад в form-control */\n padding-left: var(--gap-0) !important;\n padding-bottom: var(--gap-4) !important;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.bankLogo {\n position: absolute;\n top: var(--gap-16);\n left: var(--gap-16);\n\n & svg {\n display: block;\n\n & g {\n fill: var(--color-light-neutral-translucent-1300);\n }\n }\n}\n\n.brandLogo {\n position: absolute;\n bottom: var(--gap-20);\n right: var(--gap-20);\n\n & svg {\n display: block;\n fill: var(--color-light-neutral-translucent-1300);\n }\n}\n\n.usePhoto {\n display: block;\n margin: var(--gap-0);\n padding: var(--gap-0);\n text-decoration: none;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n user-select: none;\n cursor: pointer;\n outline: none;\n margin-bottom: var(--gap-4);\n align-self: flex-end;\n\n /* В макете иконка прилегает к правому краю поля, а по дизайн-системе там должен быть отступ */\n margin-right: calc(var(--gap-12) * -1);\n\n & svg {\n fill: var(--color-light-neutral-translucent-1300);\n display: block;\n }\n}\n"],"names":[],"mappings":";;AAEgB,aAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,sBAAsB,CAAC,uCAAuC,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,wBAAwB,CAAC,UAAU,CAAC,2BAA2B,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,CAAC,2BAA2B,CAAC;;;;"}
@@ -1,2 +1,2 @@
1
- import { MaskType } from '../types';
1
+ import { type MaskType } from '../types';
2
2
  export declare const getDefaultInputLabel: (maskType: MaskType) => "Номер карты" | "Номер счёта" | "Номер карты или счёта";
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultInputLabel.js","sources":["../src/helpers/getDefaultInputLabel.tsx"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":["MaskTypeEnum"],"mappings":";;;;;;AAGO,IAAM,oBAAoB,GAAG,UAAC,QAAkB,EAAA;AACnD,IAAA,QAAQ,QAAQ;QACZ,KAAKA,kBAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
1
+ {"version":3,"file":"getDefaultInputLabel.js","sources":["../src/helpers/getDefaultInputLabel.ts"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { type MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":["MaskTypeEnum"],"mappings":";;;;;;AAGO,IAAM,oBAAoB,GAAG,UAAC,QAAkB,EAAA;AACnD,IAAA,QAAQ,QAAQ;QACZ,KAAKA,kBAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAKA,kBAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
package/index.css CHANGED
@@ -15,9 +15,10 @@
15
15
  --gap-16: var(--gap-m);
16
16
  --gap-20: var(--gap-l);
17
17
  } :root {
18
- --font-family-styrene: 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto,
19
- 'Helvetica Neue', Helvetica, sans-serif;
20
- } .bank-card__component_1e5wo {
18
+ --font-family-styrene:
19
+ 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica,
20
+ sans-serif;
21
+ } .bank-card__component_1ww0x {
21
22
  --form-control-border-radius: 0;
22
23
  --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);
23
24
  --form-control-bg-color: transparent;
@@ -31,9 +32,9 @@
31
32
  max-width: 343px;
32
33
 
33
34
  font-family: var(--font-family-styrene);
34
- } .bank-card__aspectRatioContainer_1e5wo {
35
+ } .bank-card__aspectRatioContainer_1ww0x {
35
36
  padding-bottom: 63%;
36
- } .bank-card__content_1e5wo {
37
+ } .bank-card__content_1ww0x {
37
38
  position: absolute;
38
39
  top: var(--gap-0);
39
40
  right: var(--gap-0);
@@ -45,26 +46,34 @@
45
46
  padding-right: var(--gap-20);
46
47
  border-radius: var(--border-radius-12);
47
48
  box-sizing: border-box;
48
- } .bank-card__label_1e5wo {
49
+ } .bank-card__label_1ww0x {
49
50
  left: var(--gap-0);
50
51
  transform: translateY(-1px);
51
52
  color: var(--color-light-text-secondary);
53
+
52
54
  font-size: 20px;
53
- line-height: 24px
54
- } @media (max-width: 360px) { .bank-card__label_1e5wo {
55
- font-size: 16px
55
+
56
+ line-height: 24px;
57
+
58
+ font-weight: 400;
59
+
60
+ font-feature-settings: 'ss01';
61
+
62
+ font-family: var(--font-family-styrene);
63
+ } @media (max-width: 360px) { .bank-card__label_1ww0x {
64
+ font-size: 16px;
56
65
  }
57
- } .bank-card__focused_1e5wo .bank-card__label_1e5wo,
58
- .bank-card__filled_1e5wo .bank-card__label_1e5wo {
66
+ } .bank-card__focused_1ww0x .bank-card__label_1ww0x,
67
+ .bank-card__filled_1ww0x .bank-card__label_1ww0x {
59
68
  color: var(--color-light-neutral-translucent-1300);
60
- transform: translateY(-19px) scale(0.6)
61
- } @media (max-width: 360px) { .bank-card__focused_1e5wo .bank-card__label_1e5wo,
62
- .bank-card__filled_1e5wo .bank-card__label_1e5wo {
63
- transform: translateY(-22px) scale(0.75)
69
+ transform: translateY(-19px) scale(0.6);
70
+ } @media (max-width: 360px) { .bank-card__focused_1ww0x .bank-card__label_1ww0x,
71
+ .bank-card__filled_1ww0x .bank-card__label_1ww0x {
72
+ transform: translateY(-22px) scale(0.75);
64
73
  }
65
- } .bank-card__focused_1e5wo:before {
74
+ } .bank-card__focused_1ww0x:before {
66
75
  transform: scale(1) !important;
67
- } .bank-card__input_1e5wo {
76
+ } .bank-card__input_1ww0x {
68
77
  font-size: 20px;
69
78
  line-height: 24px;
70
79
  font-weight: 400;
@@ -74,26 +83,26 @@
74
83
  color: var(--color-light-neutral-translucent-1300);
75
84
  caret-color: var(--color-light-neutral-translucent-1300);
76
85
  padding-left: var(--gap-0) !important;
77
- padding-bottom: var(--gap-4) !important
78
- } @media (max-width: 360px) { .bank-card__input_1e5wo {
79
- font-size: 16px
86
+ padding-bottom: var(--gap-4) !important;
87
+ } @media (max-width: 360px) { .bank-card__input_1ww0x {
88
+ font-size: 16px;
80
89
  }
81
- } .bank-card__bankLogo_1e5wo {
90
+ } .bank-card__bankLogo_1ww0x {
82
91
  position: absolute;
83
92
  top: var(--gap-16);
84
- left: var(--gap-16)
85
- } .bank-card__bankLogo_1e5wo svg {
86
- display: block
87
- } .bank-card__bankLogo_1e5wo svg g {
93
+ left: var(--gap-16);
94
+ } .bank-card__bankLogo_1ww0x svg {
95
+ display: block;
96
+ } .bank-card__bankLogo_1ww0x svg g {
88
97
  fill: var(--color-light-neutral-translucent-1300);
89
- } .bank-card__brandLogo_1e5wo {
98
+ } .bank-card__brandLogo_1ww0x {
90
99
  position: absolute;
91
100
  bottom: var(--gap-20);
92
- right: var(--gap-20)
93
- } .bank-card__brandLogo_1e5wo svg {
101
+ right: var(--gap-20);
102
+ } .bank-card__brandLogo_1ww0x svg {
94
103
  display: block;
95
104
  fill: var(--color-light-neutral-translucent-1300);
96
- } .bank-card__usePhoto_1e5wo {
105
+ } .bank-card__usePhoto_1ww0x {
97
106
  display: block;
98
107
  margin: var(--gap-0);
99
108
  padding: var(--gap-0);
@@ -108,8 +117,8 @@
108
117
  outline: none;
109
118
  margin-bottom: var(--gap-4);
110
119
  align-self: flex-end;
111
- margin-right: calc(var(--gap-12) * -1)
112
- } .bank-card__usePhoto_1e5wo svg {
120
+ margin-right: calc(var(--gap-12) * -1);
121
+ } .bank-card__usePhoto_1ww0x svg {
113
122
  fill: var(--color-light-neutral-translucent-1300);
114
123
  display: block;
115
124
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require('./index.css');
4
4
 
5
- var styles = {"component":"bank-card__component_1e5wo","aspectRatioContainer":"bank-card__aspectRatioContainer_1e5wo","content":"bank-card__content_1e5wo","label":"bank-card__label_1e5wo","focused":"bank-card__focused_1e5wo","filled":"bank-card__filled_1e5wo","input":"bank-card__input_1e5wo","bankLogo":"bank-card__bankLogo_1e5wo","brandLogo":"bank-card__brandLogo_1e5wo","usePhoto":"bank-card__usePhoto_1e5wo"};
5
+ var styles = {"component":"bank-card__component_1ww0x","aspectRatioContainer":"bank-card__aspectRatioContainer_1ww0x","content":"bank-card__content_1ww0x","label":"bank-card__label_1ww0x","focused":"bank-card__focused_1ww0x","filled":"bank-card__filled_1ww0x","input":"bank-card__input_1ww0x","bankLogo":"bank-card__bankLogo_1ww0x","brandLogo":"bank-card__brandLogo_1ww0x","usePhoto":"bank-card__usePhoto_1ww0x"};
6
6
 
7
7
  module.exports = styles;
8
8
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n/* purgecss ignore */\n.component {\n /* TODO: как это будет собираться и работать в webView */\n --form-control-border-radius: 0;\n --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);\n --form-control-bg-color: transparent;\n\n /* focus */\n --form-control-focus-border-bottom: 1px solid var(--color-light-neutral-translucent-1300);\n --form-control-focus-shadow: transparent;\n\n /* hover */\n --form-control-hover-bg-color: transparent;\n --form-control-focus-bg-color: transparent;\n --form-control-font-family: var(--font-family-styrene);\n\n position: relative;\n max-width: 343px;\n\n font-family: var(--font-family-styrene);\n}\n\n.aspectRatioContainer {\n /* Эталонный размер 343x216 */\n padding-bottom: 63%;\n}\n\n.content {\n position: absolute;\n top: var(--gap-0);\n right: var(--gap-0);\n bottom: var(--gap-0);\n left: var(--gap-0);\n display: flex;\n align-items: center;\n padding-left: var(--gap-20);\n padding-right: var(--gap-20);\n border-radius: var(--border-radius-12);\n box-sizing: border-box;\n}\n\n.label {\n left: var(--gap-0);\n transform: translateY(-1px);\n color: var(--color-light-text-secondary);\n font-size: 20px;\n line-height: 24px;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.focused .label,\n.filled .label {\n color: var(--color-light-neutral-translucent-1300);\n transform: translateY(-19px) scale(0.6);\n\n @media (max-width: 360px) {\n transform: translateY(-22px) scale(0.75);\n }\n}\n\n.focused:before {\n transform: scale(1) !important;\n}\n\n.input {\n @mixin promo_xsmall;\n\n color: var(--color-light-neutral-translucent-1300);\n caret-color: var(--color-light-neutral-translucent-1300);\n\n /* TODO: обсудить с дизайнером, почему инпут не соответствует дизайн-системе, либо уменьшить каскад в form-control */\n padding-left: var(--gap-0) !important;\n padding-bottom: var(--gap-4) !important;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.bankLogo {\n position: absolute;\n top: var(--gap-16);\n left: var(--gap-16);\n\n & svg {\n display: block;\n\n & g {\n fill: var(--color-light-neutral-translucent-1300);\n }\n }\n}\n\n.brandLogo {\n position: absolute;\n bottom: var(--gap-20);\n right: var(--gap-20);\n\n & svg {\n display: block;\n fill: var(--color-light-neutral-translucent-1300);\n }\n}\n\n.usePhoto {\n display: block;\n margin: var(--gap-0);\n padding: var(--gap-0);\n text-decoration: none;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n user-select: none;\n cursor: pointer;\n outline: none;\n margin-bottom: var(--gap-4);\n align-self: flex-end;\n\n /* В макете иконка прилегает к правому краю поля, а по дизайн-системе там должен быть отступ */\n margin-right: calc(var(--gap-12) * -1);\n\n & svg {\n fill: var(--color-light-neutral-translucent-1300);\n display: block;\n }\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,sBAAsB,CAAC,uCAAuC,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,wBAAwB,CAAC,UAAU,CAAC,2BAA2B,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,CAAC,2BAA2B,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/no-typography-index.css';\n\n/* purgecss ignore */\n.component {\n /* TODO: как это будет собираться и работать в webView */\n --form-control-border-radius: 0;\n --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);\n --form-control-bg-color: transparent;\n\n /* focus */\n --form-control-focus-border-bottom: 1px solid var(--color-light-neutral-translucent-1300);\n --form-control-focus-shadow: transparent;\n\n /* hover */\n --form-control-hover-bg-color: transparent;\n --form-control-focus-bg-color: transparent;\n --form-control-font-family: var(--font-family-styrene);\n\n position: relative;\n max-width: 343px;\n\n font-family: var(--font-family-styrene);\n}\n\n.aspectRatioContainer {\n /* Эталонный размер 343x216 */\n padding-bottom: 63%;\n}\n\n.content {\n position: absolute;\n top: var(--gap-0);\n right: var(--gap-0);\n bottom: var(--gap-0);\n left: var(--gap-0);\n display: flex;\n align-items: center;\n padding-left: var(--gap-20);\n padding-right: var(--gap-20);\n border-radius: var(--border-radius-12);\n box-sizing: border-box;\n}\n\n.label {\n left: var(--gap-0);\n transform: translateY(-1px);\n color: var(--color-light-text-secondary);\n\n @mixin promo_xsmall;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.focused .label,\n.filled .label {\n color: var(--color-light-neutral-translucent-1300);\n transform: translateY(-19px) scale(0.6);\n\n @media (max-width: 360px) {\n transform: translateY(-22px) scale(0.75);\n }\n}\n\n.focused:before {\n transform: scale(1) !important;\n}\n\n.input {\n @mixin promo_xsmall;\n\n color: var(--color-light-neutral-translucent-1300);\n caret-color: var(--color-light-neutral-translucent-1300);\n\n /* TODO: обсудить с дизайнером, почему инпут не соответствует дизайн-системе, либо уменьшить каскад в form-control */\n padding-left: var(--gap-0) !important;\n padding-bottom: var(--gap-4) !important;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.bankLogo {\n position: absolute;\n top: var(--gap-16);\n left: var(--gap-16);\n\n & svg {\n display: block;\n\n & g {\n fill: var(--color-light-neutral-translucent-1300);\n }\n }\n}\n\n.brandLogo {\n position: absolute;\n bottom: var(--gap-20);\n right: var(--gap-20);\n\n & svg {\n display: block;\n fill: var(--color-light-neutral-translucent-1300);\n }\n}\n\n.usePhoto {\n display: block;\n margin: var(--gap-0);\n padding: var(--gap-0);\n text-decoration: none;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n user-select: none;\n cursor: pointer;\n outline: none;\n margin-bottom: var(--gap-4);\n align-self: flex-end;\n\n /* В макете иконка прилегает к правому краю поля, а по дизайн-системе там должен быть отступ */\n margin-right: calc(var(--gap-12) * -1);\n\n & svg {\n fill: var(--color-light-neutral-translucent-1300);\n display: block;\n }\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,sBAAsB,CAAC,uCAAuC,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,wBAAwB,CAAC,UAAU,CAAC,2BAA2B,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,CAAC,2BAA2B,CAAC;;;;"}
@@ -1,5 +1,5 @@
1
- import React, { ChangeEvent, MouseEvent, ReactNode } from 'react';
2
- import { MaskType } from './types';
1
+ import React, { type ChangeEvent, type MouseEvent, type ReactNode } from 'react';
2
+ import { type MaskType } from './types';
3
3
  export declare type BankCardProps = {
4
4
  /**
5
5
  * Дополнительный класс
@@ -1 +1 @@
1
- {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { type MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { MaskType } from '../types';
1
+ import { type MaskType } from '../types';
2
2
  export declare const getDefaultInputLabel: (maskType: MaskType) => "Номер карты" | "Номер счёта" | "Номер карты или счёта";
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.tsx"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":[],"mappings":";;AAGa,MAAA,oBAAoB,GAAG,CAAC,QAAkB,KAAI;AACvD,IAAA,QAAQ,QAAQ;QACZ,KAAK,YAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
1
+ {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.ts"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { type MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":[],"mappings":";;AAGa,MAAA,oBAAoB,GAAG,CAAC,QAAkB,KAAI;AACvD,IAAA,QAAQ,QAAQ;QACZ,KAAK,YAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
package/modern/index.css CHANGED
@@ -15,9 +15,10 @@
15
15
  --gap-16: var(--gap-m);
16
16
  --gap-20: var(--gap-l);
17
17
  } :root {
18
- --font-family-styrene: 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto,
19
- 'Helvetica Neue', Helvetica, sans-serif;
20
- } .bank-card__component_1e5wo {
18
+ --font-family-styrene:
19
+ 'Styrene UI', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica,
20
+ sans-serif;
21
+ } .bank-card__component_1ww0x {
21
22
  --form-control-border-radius: 0;
22
23
  --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);
23
24
  --form-control-bg-color: transparent;
@@ -31,9 +32,9 @@
31
32
  max-width: 343px;
32
33
 
33
34
  font-family: var(--font-family-styrene);
34
- } .bank-card__aspectRatioContainer_1e5wo {
35
+ } .bank-card__aspectRatioContainer_1ww0x {
35
36
  padding-bottom: 63%;
36
- } .bank-card__content_1e5wo {
37
+ } .bank-card__content_1ww0x {
37
38
  position: absolute;
38
39
  top: var(--gap-0);
39
40
  right: var(--gap-0);
@@ -45,26 +46,34 @@
45
46
  padding-right: var(--gap-20);
46
47
  border-radius: var(--border-radius-12);
47
48
  box-sizing: border-box;
48
- } .bank-card__label_1e5wo {
49
+ } .bank-card__label_1ww0x {
49
50
  left: var(--gap-0);
50
51
  transform: translateY(-1px);
51
52
  color: var(--color-light-text-secondary);
53
+
52
54
  font-size: 20px;
53
- line-height: 24px
54
- } @media (max-width: 360px) { .bank-card__label_1e5wo {
55
- font-size: 16px
55
+
56
+ line-height: 24px;
57
+
58
+ font-weight: 400;
59
+
60
+ font-feature-settings: 'ss01';
61
+
62
+ font-family: var(--font-family-styrene);
63
+ } @media (max-width: 360px) { .bank-card__label_1ww0x {
64
+ font-size: 16px;
56
65
  }
57
- } .bank-card__focused_1e5wo .bank-card__label_1e5wo,
58
- .bank-card__filled_1e5wo .bank-card__label_1e5wo {
66
+ } .bank-card__focused_1ww0x .bank-card__label_1ww0x,
67
+ .bank-card__filled_1ww0x .bank-card__label_1ww0x {
59
68
  color: var(--color-light-neutral-translucent-1300);
60
- transform: translateY(-19px) scale(0.6)
61
- } @media (max-width: 360px) { .bank-card__focused_1e5wo .bank-card__label_1e5wo,
62
- .bank-card__filled_1e5wo .bank-card__label_1e5wo {
63
- transform: translateY(-22px) scale(0.75)
69
+ transform: translateY(-19px) scale(0.6);
70
+ } @media (max-width: 360px) { .bank-card__focused_1ww0x .bank-card__label_1ww0x,
71
+ .bank-card__filled_1ww0x .bank-card__label_1ww0x {
72
+ transform: translateY(-22px) scale(0.75);
64
73
  }
65
- } .bank-card__focused_1e5wo:before {
74
+ } .bank-card__focused_1ww0x:before {
66
75
  transform: scale(1) !important;
67
- } .bank-card__input_1e5wo {
76
+ } .bank-card__input_1ww0x {
68
77
  font-size: 20px;
69
78
  line-height: 24px;
70
79
  font-weight: 400;
@@ -74,26 +83,26 @@
74
83
  color: var(--color-light-neutral-translucent-1300);
75
84
  caret-color: var(--color-light-neutral-translucent-1300);
76
85
  padding-left: var(--gap-0) !important;
77
- padding-bottom: var(--gap-4) !important
78
- } @media (max-width: 360px) { .bank-card__input_1e5wo {
79
- font-size: 16px
86
+ padding-bottom: var(--gap-4) !important;
87
+ } @media (max-width: 360px) { .bank-card__input_1ww0x {
88
+ font-size: 16px;
80
89
  }
81
- } .bank-card__bankLogo_1e5wo {
90
+ } .bank-card__bankLogo_1ww0x {
82
91
  position: absolute;
83
92
  top: var(--gap-16);
84
- left: var(--gap-16)
85
- } .bank-card__bankLogo_1e5wo svg {
86
- display: block
87
- } .bank-card__bankLogo_1e5wo svg g {
93
+ left: var(--gap-16);
94
+ } .bank-card__bankLogo_1ww0x svg {
95
+ display: block;
96
+ } .bank-card__bankLogo_1ww0x svg g {
88
97
  fill: var(--color-light-neutral-translucent-1300);
89
- } .bank-card__brandLogo_1e5wo {
98
+ } .bank-card__brandLogo_1ww0x {
90
99
  position: absolute;
91
100
  bottom: var(--gap-20);
92
- right: var(--gap-20)
93
- } .bank-card__brandLogo_1e5wo svg {
101
+ right: var(--gap-20);
102
+ } .bank-card__brandLogo_1ww0x svg {
94
103
  display: block;
95
104
  fill: var(--color-light-neutral-translucent-1300);
96
- } .bank-card__usePhoto_1e5wo {
105
+ } .bank-card__usePhoto_1ww0x {
97
106
  display: block;
98
107
  margin: var(--gap-0);
99
108
  padding: var(--gap-0);
@@ -108,8 +117,8 @@
108
117
  outline: none;
109
118
  margin-bottom: var(--gap-4);
110
119
  align-self: flex-end;
111
- margin-right: calc(var(--gap-12) * -1)
112
- } .bank-card__usePhoto_1e5wo svg {
120
+ margin-right: calc(var(--gap-12) * -1);
121
+ } .bank-card__usePhoto_1ww0x svg {
113
122
  fill: var(--color-light-neutral-translucent-1300);
114
123
  display: block;
115
124
  }
@@ -1,6 +1,6 @@
1
1
  import './index.css';
2
2
 
3
- const styles = {"component":"bank-card__component_1e5wo","aspectRatioContainer":"bank-card__aspectRatioContainer_1e5wo","content":"bank-card__content_1e5wo","label":"bank-card__label_1e5wo","focused":"bank-card__focused_1e5wo","filled":"bank-card__filled_1e5wo","input":"bank-card__input_1e5wo","bankLogo":"bank-card__bankLogo_1e5wo","brandLogo":"bank-card__brandLogo_1e5wo","usePhoto":"bank-card__usePhoto_1e5wo"};
3
+ const styles = {"component":"bank-card__component_1ww0x","aspectRatioContainer":"bank-card__aspectRatioContainer_1ww0x","content":"bank-card__content_1ww0x","label":"bank-card__label_1ww0x","focused":"bank-card__focused_1ww0x","filled":"bank-card__filled_1ww0x","input":"bank-card__input_1ww0x","bankLogo":"bank-card__bankLogo_1ww0x","brandLogo":"bank-card__brandLogo_1ww0x","usePhoto":"bank-card__usePhoto_1ww0x"};
4
4
 
5
5
  export { styles as default };
6
6
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n/* purgecss ignore */\n.component {\n /* TODO: как это будет собираться и работать в webView */\n --form-control-border-radius: 0;\n --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);\n --form-control-bg-color: transparent;\n\n /* focus */\n --form-control-focus-border-bottom: 1px solid var(--color-light-neutral-translucent-1300);\n --form-control-focus-shadow: transparent;\n\n /* hover */\n --form-control-hover-bg-color: transparent;\n --form-control-focus-bg-color: transparent;\n --form-control-font-family: var(--font-family-styrene);\n\n position: relative;\n max-width: 343px;\n\n font-family: var(--font-family-styrene);\n}\n\n.aspectRatioContainer {\n /* Эталонный размер 343x216 */\n padding-bottom: 63%;\n}\n\n.content {\n position: absolute;\n top: var(--gap-0);\n right: var(--gap-0);\n bottom: var(--gap-0);\n left: var(--gap-0);\n display: flex;\n align-items: center;\n padding-left: var(--gap-20);\n padding-right: var(--gap-20);\n border-radius: var(--border-radius-12);\n box-sizing: border-box;\n}\n\n.label {\n left: var(--gap-0);\n transform: translateY(-1px);\n color: var(--color-light-text-secondary);\n font-size: 20px;\n line-height: 24px;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.focused .label,\n.filled .label {\n color: var(--color-light-neutral-translucent-1300);\n transform: translateY(-19px) scale(0.6);\n\n @media (max-width: 360px) {\n transform: translateY(-22px) scale(0.75);\n }\n}\n\n.focused:before {\n transform: scale(1) !important;\n}\n\n.input {\n @mixin promo_xsmall;\n\n color: var(--color-light-neutral-translucent-1300);\n caret-color: var(--color-light-neutral-translucent-1300);\n\n /* TODO: обсудить с дизайнером, почему инпут не соответствует дизайн-системе, либо уменьшить каскад в form-control */\n padding-left: var(--gap-0) !important;\n padding-bottom: var(--gap-4) !important;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.bankLogo {\n position: absolute;\n top: var(--gap-16);\n left: var(--gap-16);\n\n & svg {\n display: block;\n\n & g {\n fill: var(--color-light-neutral-translucent-1300);\n }\n }\n}\n\n.brandLogo {\n position: absolute;\n bottom: var(--gap-20);\n right: var(--gap-20);\n\n & svg {\n display: block;\n fill: var(--color-light-neutral-translucent-1300);\n }\n}\n\n.usePhoto {\n display: block;\n margin: var(--gap-0);\n padding: var(--gap-0);\n text-decoration: none;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n user-select: none;\n cursor: pointer;\n outline: none;\n margin-bottom: var(--gap-4);\n align-self: flex-end;\n\n /* В макете иконка прилегает к правому краю поля, а по дизайн-системе там должен быть отступ */\n margin-right: calc(var(--gap-12) * -1);\n\n & svg {\n fill: var(--color-light-neutral-translucent-1300);\n display: block;\n }\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,sBAAsB,CAAC,uCAAuC,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,wBAAwB,CAAC,UAAU,CAAC,2BAA2B,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,CAAC,2BAA2B,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["src/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/no-typography-index.css';\n\n/* purgecss ignore */\n.component {\n /* TODO: как это будет собираться и работать в webView */\n --form-control-border-radius: 0;\n --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);\n --form-control-bg-color: transparent;\n\n /* focus */\n --form-control-focus-border-bottom: 1px solid var(--color-light-neutral-translucent-1300);\n --form-control-focus-shadow: transparent;\n\n /* hover */\n --form-control-hover-bg-color: transparent;\n --form-control-focus-bg-color: transparent;\n --form-control-font-family: var(--font-family-styrene);\n\n position: relative;\n max-width: 343px;\n\n font-family: var(--font-family-styrene);\n}\n\n.aspectRatioContainer {\n /* Эталонный размер 343x216 */\n padding-bottom: 63%;\n}\n\n.content {\n position: absolute;\n top: var(--gap-0);\n right: var(--gap-0);\n bottom: var(--gap-0);\n left: var(--gap-0);\n display: flex;\n align-items: center;\n padding-left: var(--gap-20);\n padding-right: var(--gap-20);\n border-radius: var(--border-radius-12);\n box-sizing: border-box;\n}\n\n.label {\n left: var(--gap-0);\n transform: translateY(-1px);\n color: var(--color-light-text-secondary);\n\n @mixin promo_xsmall;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.focused .label,\n.filled .label {\n color: var(--color-light-neutral-translucent-1300);\n transform: translateY(-19px) scale(0.6);\n\n @media (max-width: 360px) {\n transform: translateY(-22px) scale(0.75);\n }\n}\n\n.focused:before {\n transform: scale(1) !important;\n}\n\n.input {\n @mixin promo_xsmall;\n\n color: var(--color-light-neutral-translucent-1300);\n caret-color: var(--color-light-neutral-translucent-1300);\n\n /* TODO: обсудить с дизайнером, почему инпут не соответствует дизайн-системе, либо уменьшить каскад в form-control */\n padding-left: var(--gap-0) !important;\n padding-bottom: var(--gap-4) !important;\n\n @media (max-width: 360px) {\n font-size: 16px;\n }\n}\n\n.bankLogo {\n position: absolute;\n top: var(--gap-16);\n left: var(--gap-16);\n\n & svg {\n display: block;\n\n & g {\n fill: var(--color-light-neutral-translucent-1300);\n }\n }\n}\n\n.brandLogo {\n position: absolute;\n bottom: var(--gap-20);\n right: var(--gap-20);\n\n & svg {\n display: block;\n fill: var(--color-light-neutral-translucent-1300);\n }\n}\n\n.usePhoto {\n display: block;\n margin: var(--gap-0);\n padding: var(--gap-0);\n text-decoration: none;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n user-select: none;\n cursor: pointer;\n outline: none;\n margin-bottom: var(--gap-4);\n align-self: flex-end;\n\n /* В макете иконка прилегает к правому краю поля, а по дизайн-системе там должен быть отступ */\n margin-right: calc(var(--gap-12) * -1);\n\n & svg {\n fill: var(--color-light-neutral-translucent-1300);\n display: block;\n }\n}\n"],"names":[],"mappings":";;AAEgB,eAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,sBAAsB,CAAC,uCAAuC,CAAC,SAAS,CAAC,0BAA0B,CAAC,OAAO,CAAC,wBAAwB,CAAC,SAAS,CAAC,0BAA0B,CAAC,QAAQ,CAAC,yBAAyB,CAAC,OAAO,CAAC,wBAAwB,CAAC,UAAU,CAAC,2BAA2B,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,CAAC,2BAA2B,CAAC;;;;"}
@@ -1,5 +1,5 @@
1
- import React, { ChangeEvent, MouseEvent, ReactNode } from 'react';
2
- import { MaskType } from './types';
1
+ import React, { type ChangeEvent, type MouseEvent, type ReactNode } from 'react';
2
+ import { type MaskType } from './types';
3
3
  export declare type BankCardProps = {
4
4
  /**
5
5
  * Дополнительный класс
@@ -1 +1 @@
1
- {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n ChangeEvent,\n forwardRef,\n MouseEvent,\n ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":[],"mappings":";;;;;;;;;;;;;AAyEA;AACA,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAChI;AACA,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAEtK,MAAM,YAAY,GAAG,CAAC,KAAK,GAAG,EAAE,KAAI;;AAEhC,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,EAAE,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE;AACrE,QAAA,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAA,CAAA,aAAA,CAAC,UAAU,EAAA,IAAA,CAAG;AAChD,QAAA,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAA,CAAA,aAAA,CAAC,WAAW,EAAA,IAAA,CAAG;AACjD,QAAA,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAA,CAAA,aAAA,CAAC,eAAe,EAAA,IAAA,CAAG;AACrD,QAAA,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAA,CAAA,aAAA,CAAC,eAAe,EAAA,IAAA,CAAG;AACxD;AAED,IAAA,OAAO,IAAI;AACf,CAAC;AAEY,MAAA,QAAQ,GAAG,UAAU,CAC9B,CACI,EACI,QAAQ,GAAG,KAAC,CAAA,aAAA,CAAA,iBAAiB,IAAC,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAI,CAAA,EACvD,eAAe,GAAG,SAAS,EAC3B,KAAK,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,UAAU,EACV,QAAQ,GAAG,YAAY,CAAC,OAAO,EAC/B,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,GAC9C,EACD,GAAG,KACH;AACA,IAAA,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;AAExC,IAAA,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAY,YAAY,CAAC,KAAK,CAAC,CAAC;AAE1E,IAAA,MAAM,OAAO,GAAG,WAAW,CACvB,CAAC,QAAgB,KAAI;AACjB,QAAA,QAAQ,QAAQ;YACZ,KAAK,YAAY,CAAC,IAAI;AAClB,gBAAA,OAAO,QAAQ;YACnB,KAAK,YAAY,CAAC,aAAa;AAC3B,gBAAA,OAAO,iBAAiB;YAC5B,KAAK,YAAY,CAAC,OAAO;AACzB,YAAA;AACI,gBAAA,OAAO,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,GAAG,iBAAiB;AAC/E;AACL,KAAC,EACD,CAAC,QAAQ,CAAC,CACb;IAED,MAAM,iBAAiB,GAAG,WAAW,CACjC,CAAC,KAAoC,EAAE,OAA0B,KAAI;AACjE,QAAA,IAAI,YAAY,EAAE;YACd,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACjD;AAED,QAAA,IAAI,QAAQ,EAAE;AACV,YAAA,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;AAC3B;AACL,KAAC,EACD,CAAC,QAAQ,EAAE,YAAY,CAAC,CAC3B;IAED,MAAM,iBAAiB,GAAG,WAAW,CACjC,OACI,KAAQ,CAAA,aAAA,CAAA,QAAA,EAAA,EAAA,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAA;QACjE,KAAC,CAAA,aAAA,CAAA,WAAW,OAAG,CACV,CACZ,EACD,CAAC,UAAU,CAAC,CACf;IAED,SAAS,CAAC,MAAK;AACX,QAAA,YAAY,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACrC,KAAC,EAAE,CAAC,KAAK,CAAC,CAAC;IAEX,QACI,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,EAAA;AAC3C,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,MAAM,CAAC,oBAAoB,EAAA;YACvC,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,eAAe,EAAE,EAAA;AACtD,gBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAA,EAAG,QAAQ,CAAO;AAEjD,gBAAA,KAAA,CAAA,aAAA,CAAC,WAAW,EAAA,EACR,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,UAAU,EACjB,IAAI,EAAC,GAAG,EACR,WAAW,EAAE,iBAAiB,EAAE,EAChC,cAAc,EAAE,MAAM,CAAC,KAAK,EAC5B,cAAc,EAAE,MAAM,CAAC,KAAK,EAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAC9B,gBAAgB,EAAE,MAAM,CAAC,OAAO,EAChC,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAC,SAAS,EACnB,OAAO,EAAC,QAAQ,EAChB,UAAU,EAAE,CAAC,EACf,CAAA;AAED,gBAAA,SAAS,IAAI,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,MAAM,CAAC,SAAS,EAAG,EAAA,SAAS,CAAO,CAC/D,CACJ,CACJ;AAEd,CAAC;AAGL,QAAQ,CAAC,WAAW,GAAG,UAAU;;;;"}
1
+ {"version":3,"file":"Component.js","sources":["../src/Component.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n forwardRef,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useState,\n} from 'react';\nimport cn from 'classnames';\n\nimport { MaskedInput } from '@alfalab/core-components-masked-input';\nimport { CameraMIcon } from '@alfalab/icons-glyph/CameraMIcon';\nimport { AlfaBankSignMIcon } from '@alfalab/icons-logo/AlfaBankSignMIcon';\nimport { MastercardLIcon } from '@alfalab/icons-logotype/MastercardLIcon';\nimport { MirXxlIcon } from '@alfalab/icons-logotype/MirXxlIcon';\nimport { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';\n\nimport { getDefaultInputLabel } from './helpers/getDefaultInputLabel';\nimport { MaskTypeEnum } from './enums';\nimport { type MaskType } from './types';\nimport { validateCardNumber } from './utils';\n\nimport styles from './index.module.css';\n\nexport type BankCardProps = {\n /**\n * Дополнительный класс\n */\n className?: string;\n\n /**\n * Цвет фона карты\n */\n backgroundColor?: string;\n\n /**\n * Иконка логотипа банка (размер L)\n */\n bankLogo?: ReactNode;\n\n /**\n * Лэйбл поля ввода\n */\n inputLabel?: string;\n\n /**\n * Значение поля ввода\n */\n value?: string;\n\n /**\n * Обработчик ввода\n */\n onChange?: (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => void;\n\n /**\n * Обработчик вызова камеры\n */\n onUsePhoto?: (event: MouseEvent<HTMLButtonElement>) => void;\n\n /**\n * Идентификатор для систем автоматизированного тестирования\n */\n dataTestId?: string;\n\n /**\n * Тип вводимой маски. Позволяет устанавливать необходимый тип номера (номер карты или номер счёта)\n * Если параметр не передавать - работает с обоими типами номеров\n */\n maskType?: MaskType;\n};\n\n// prettier-ignore\nconst cardMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n// prettier-ignore\nconst accountNumberMask = [/\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/, ' ', /\\d/, /\\d/, /\\d/, /\\d/];\n\nconst getBrandIcon = (value = '') => {\n // Показываем логотип только после ввода всех цифр карты\n if (value.replace(/\\s/g, '').length === 16 && validateCardNumber(value)) {\n if (value.startsWith('2')) return <MirXxlIcon />;\n if (value.startsWith('4')) return <VisaXxlIcon />;\n if (value.startsWith('5')) return <MastercardLIcon />;\n if (value.startsWith('6')) return <MastercardLIcon />;\n }\n\n return null;\n};\n\nexport const BankCard = forwardRef<HTMLInputElement, BankCardProps>(\n (\n {\n bankLogo = <AlfaBankSignMIcon width={30} height={40} />,\n backgroundColor = '#EF3124',\n value,\n className,\n onUsePhoto,\n onChange,\n dataTestId,\n maskType = MaskTypeEnum.Default,\n inputLabel = getDefaultInputLabel(maskType),\n },\n ref,\n ) => {\n const uncontrolled = value === undefined;\n\n const [brandIcon, setBrandIcon] = useState<ReactNode>(getBrandIcon(value));\n\n const getMask = useCallback(\n (newValue: string) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return cardMask;\n case MaskTypeEnum.AccountNumber:\n return accountNumberMask;\n case MaskTypeEnum.Default:\n default:\n return newValue.length <= cardMask.length ? cardMask : accountNumberMask;\n }\n },\n [maskType],\n );\n\n const handleInputChange = useCallback(\n (event: ChangeEvent<HTMLInputElement>, payload: { value: string }) => {\n if (uncontrolled) {\n setBrandIcon(getBrandIcon(event.target.value));\n }\n\n if (onChange) {\n onChange(event, payload);\n }\n },\n [onChange, uncontrolled],\n );\n\n const renderRightAddons = useCallback(\n () => (\n <button type='button' className={styles.usePhoto} onClick={onUsePhoto}>\n <CameraMIcon />\n </button>\n ),\n [onUsePhoto],\n );\n\n useEffect(() => {\n setBrandIcon(getBrandIcon(value));\n }, [value]);\n\n return (\n <div className={cn(styles.component, className)}>\n <div className={styles.aspectRatioContainer}>\n <div className={styles.content} style={{ backgroundColor }}>\n <div className={styles.bankLogo}>{bankLogo}</div>\n\n <MaskedInput\n ref={ref}\n value={value}\n mask={getMask}\n block={true}\n label={inputLabel}\n size='m'\n rightAddons={renderRightAddons()}\n inputClassName={styles.input}\n labelClassName={styles.label}\n filledClassName={styles.filled}\n focusedClassName={styles.focused}\n onChange={handleInputChange}\n dataTestId={dataTestId}\n inputMode='numeric'\n pattern='[0-9]*'\n breakpoint={1}\n />\n\n {brandIcon && <div className={styles.brandLogo}>{brandIcon}</div>}\n </div>\n </div>\n </div>\n );\n },\n);\n\nBankCard.displayName = 'BankCard';\n"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { MaskType } from '../types';
1
+ import { type MaskType } from '../types';
2
2
  export declare const getDefaultInputLabel: (maskType: MaskType) => "Номер карты" | "Номер счёта" | "Номер карты или счёта";
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.tsx"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":[],"mappings":";;AAGa,MAAA,oBAAoB,GAAG,CAAC,QAAkB,KAAI;AACvD,IAAA,QAAQ,QAAQ;QACZ,KAAK,YAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
1
+ {"version":3,"file":"getDefaultInputLabel.js","sources":["../../src/helpers/getDefaultInputLabel.ts"],"sourcesContent":["import { MaskTypeEnum } from '../enums';\nimport { type MaskType } from '../types';\n\nexport const getDefaultInputLabel = (maskType: MaskType) => {\n switch (maskType) {\n case MaskTypeEnum.Card:\n return 'Номер карты';\n case MaskTypeEnum.AccountNumber:\n return 'Номер счёта';\n case MaskTypeEnum.Default:\n default:\n return 'Номер карты или счёта';\n }\n};\n"],"names":[],"mappings":";;AAGa,MAAA,oBAAoB,GAAG,CAAC,QAAkB,KAAI;AACvD,IAAA,QAAQ,QAAQ;QACZ,KAAK,YAAY,CAAC,IAAI;AAClB,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,aAAa;AAC3B,YAAA,OAAO,aAAa;QACxB,KAAK,YAAY,CAAC,OAAO;AACzB,QAAA;AACI,YAAA,OAAO,uBAAuB;AACrC;AACL;;;;"}
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  .component {
2
4
  --form-control-border-radius: 0;
3
5
  --form-control-border-bottom: 1px solid var(--color-light-neutral-translucent-700);
@@ -13,11 +15,9 @@
13
15
 
14
16
  font-family: var(--font-family-styrene);
15
17
  }
16
-
17
18
  .aspectRatioContainer {
18
19
  padding-bottom: 63%;
19
20
  }
20
-
21
21
  .content {
22
22
  position: absolute;
23
23
  top: var(--gap-0);
@@ -31,40 +31,40 @@
31
31
  border-radius: var(--border-radius-12);
32
32
  box-sizing: border-box;
33
33
  }
34
-
35
34
  .label {
36
35
  left: var(--gap-0);
37
36
  transform: translateY(-1px);
38
37
  color: var(--color-light-text-secondary);
38
+
39
39
  font-size: 20px;
40
- line-height: 24px
41
- }
42
40
 
43
- @media (max-width: 360px) {
41
+ line-height: 24px;
42
+
43
+ font-weight: 400;
44
+
45
+ font-feature-settings: 'ss01';
44
46
 
47
+ font-family: var(--font-family-styrene);
48
+ }
49
+ @media (max-width: 360px) {
45
50
  .label {
46
- font-size: 16px
51
+ font-size: 16px;
47
52
  }
48
53
  }
49
-
50
54
  .focused .label,
51
55
  .filled .label {
52
56
  color: var(--color-light-neutral-translucent-1300);
53
- transform: translateY(-19px) scale(0.6)
57
+ transform: translateY(-19px) scale(0.6);
54
58
  }
55
-
56
59
  @media (max-width: 360px) {
57
-
58
60
  .focused .label,
59
61
  .filled .label {
60
- transform: translateY(-22px) scale(0.75)
62
+ transform: translateY(-22px) scale(0.75);
61
63
  }
62
64
  }
63
-
64
65
  .focused:before {
65
66
  transform: scale(1) !important;
66
67
  }
67
-
68
68
  .input {
69
69
  font-size: 20px;
70
70
  line-height: 24px;
@@ -75,41 +75,33 @@
75
75
  color: var(--color-light-neutral-translucent-1300);
76
76
  caret-color: var(--color-light-neutral-translucent-1300);
77
77
  padding-left: var(--gap-0) !important;
78
- padding-bottom: var(--gap-4) !important
78
+ padding-bottom: var(--gap-4) !important;
79
79
  }
80
-
81
80
  @media (max-width: 360px) {
82
-
83
81
  .input {
84
- font-size: 16px
82
+ font-size: 16px;
85
83
  }
86
84
  }
87
-
88
85
  .bankLogo {
89
86
  position: absolute;
90
87
  top: var(--gap-16);
91
- left: var(--gap-16)
88
+ left: var(--gap-16);
92
89
  }
93
-
94
90
  .bankLogo svg {
95
- display: block
91
+ display: block;
96
92
  }
97
-
98
93
  .bankLogo svg g {
99
94
  fill: var(--color-light-neutral-translucent-1300);
100
95
  }
101
-
102
96
  .brandLogo {
103
97
  position: absolute;
104
98
  bottom: var(--gap-20);
105
- right: var(--gap-20)
99
+ right: var(--gap-20);
106
100
  }
107
-
108
101
  .brandLogo svg {
109
102
  display: block;
110
103
  fill: var(--color-light-neutral-translucent-1300);
111
104
  }
112
-
113
105
  .usePhoto {
114
106
  display: block;
115
107
  margin: var(--gap-0);
@@ -125,9 +117,8 @@
125
117
  outline: none;
126
118
  margin-bottom: var(--gap-4);
127
119
  align-self: flex-end;
128
- margin-right: calc(var(--gap-12) * -1)
120
+ margin-right: calc(var(--gap-12) * -1);
129
121
  }
130
-
131
122
  .usePhoto svg {
132
123
  fill: var(--color-light-neutral-translucent-1300);
133
124
  display: block;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-bank-card",
3
- "version": "6.0.1",
3
+ "version": "6.0.2",
4
4
  "description": "Bank card component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "main": "index.js",
11
11
  "module": "./esm/index.js",
12
12
  "dependencies": {
13
- "@alfalab/core-components-masked-input": "^7.0.1",
13
+ "@alfalab/core-components-masked-input": "^7.0.2",
14
14
  "@alfalab/icons-glyph": "^2.247.0",
15
15
  "@alfalab/icons-logo": "^1.48.0",
16
16
  "@alfalab/icons-logotype": "^2.34.0",
@@ -25,6 +25,6 @@
25
25
  "access": "public",
26
26
  "directory": "dist"
27
27
  },
28
- "themesVersion": "14.1.0",
28
+ "themesVersion": "14.1.2",
29
29
  "varsVersion": "10.1.0"
30
30
  }
package/src/Component.tsx CHANGED
@@ -1,8 +1,8 @@
1
1
  import React, {
2
- ChangeEvent,
2
+ type ChangeEvent,
3
3
  forwardRef,
4
- MouseEvent,
5
- ReactNode,
4
+ type MouseEvent,
5
+ type ReactNode,
6
6
  useCallback,
7
7
  useEffect,
8
8
  useState,
@@ -18,7 +18,7 @@ import { VisaXxlIcon } from '@alfalab/icons-logotype/VisaXxlIcon';
18
18
 
19
19
  import { getDefaultInputLabel } from './helpers/getDefaultInputLabel';
20
20
  import { MaskTypeEnum } from './enums';
21
- import { MaskType } from './types';
21
+ import { type MaskType } from './types';
22
22
  import { validateCardNumber } from './utils';
23
23
 
24
24
  import styles from './index.module.css';
@@ -1,5 +1,5 @@
1
1
  import { MaskTypeEnum } from '../enums';
2
- import { MaskType } from '../types';
2
+ import { type MaskType } from '../types';
3
3
 
4
4
  export const getDefaultInputLabel = (maskType: MaskType) => {
5
5
  switch (maskType) {
@@ -1,4 +1,4 @@
1
- @import '@alfalab/core-components-vars/src/index.css';
1
+ @import '@alfalab/core-components-vars/src/no-typography-index.css';
2
2
 
3
3
  /* purgecss ignore */
4
4
  .component {
@@ -45,8 +45,8 @@
45
45
  left: var(--gap-0);
46
46
  transform: translateY(-1px);
47
47
  color: var(--color-light-text-secondary);
48
- font-size: 20px;
49
- line-height: 24px;
48
+
49
+ @mixin promo_xsmall;
50
50
 
51
51
  @media (max-width: 360px) {
52
52
  font-size: 16px;