@scbt-ecom/ui 0.4.1 → 0.4.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.
- package/.env +3 -0
- package/.github/workflows/publish.yml +61 -0
- package/.github/workflows/setup-node/action.yml +22 -0
- package/.husky/pre-commit +1 -0
- package/.prettierignore +1 -0
- package/.prettierrc +20 -0
- package/.releaserc +18 -0
- package/.storybook/main.ts +44 -0
- package/.storybook/preview.tsx +37 -0
- package/chromatic.config.json +5 -0
- package/eslint.config.mjs +193 -0
- package/index.html +13 -0
- package/lib/client.ts +12 -0
- package/lib/configs/index.ts +2 -0
- package/lib/configs/tailwindConfigBase.ts +110 -0
- package/lib/configs/tailwindPresets/extendsPreset.ts +43 -0
- package/lib/configs/tailwindPresets/index.ts +2 -0
- package/lib/configs/tailwindPresets/resetPreset.ts +71 -0
- package/lib/hybrid.ts +25 -0
- package/lib/shared/constants/api.ts +2 -0
- package/lib/shared/constants/designSystem/colors.ts +121 -0
- package/lib/shared/constants/designSystem/index.ts +3 -0
- package/lib/shared/constants/designSystem/others.ts +30 -0
- package/lib/shared/constants/designSystem/typography.ts +88 -0
- package/lib/shared/constants/index.ts +2 -0
- package/lib/shared/hooks/index.ts +5 -0
- package/lib/shared/hooks/useBoolean.ts +12 -0
- package/lib/shared/hooks/useClickOutside.ts +22 -0
- package/lib/shared/hooks/useCombineRef.ts +23 -0
- package/lib/shared/hooks/useControlledForm.ts +16 -0
- package/lib/shared/hooks/useDebounce.ts +38 -0
- package/lib/shared/hooks/useMediaQuery.tsx +42 -0
- package/lib/shared/style.css +118 -0
- package/lib/shared/ui/Badge.tsx +20 -0
- package/lib/shared/ui/Breadcrumbs.tsx +57 -0
- package/lib/shared/ui/ButtonIcon.tsx +50 -0
- package/lib/shared/ui/CustomLink.tsx +76 -0
- package/lib/shared/ui/Document.tsx +51 -0
- package/lib/shared/ui/Heading.tsx +33 -0
- package/lib/shared/ui/Hint.tsx +72 -0
- package/lib/shared/ui/Loader.tsx +58 -0
- package/lib/shared/ui/PhoneView.tsx +23 -0
- package/lib/shared/ui/ProgressBar.tsx +43 -0
- package/lib/shared/ui/ResponsiveContainer.tsx +15 -0
- package/lib/shared/ui/Section.tsx +15 -0
- package/lib/shared/ui/Skeleton.tsx +9 -0
- package/lib/shared/ui/TabsSwitcher.tsx +87 -0
- package/lib/shared/ui/accordion/Accordion.tsx +36 -0
- package/lib/shared/ui/accordion/index.ts +1 -0
- package/lib/shared/ui/accordion/model/types.ts +20 -0
- package/lib/shared/ui/accordion/ui/AccordionHeader.tsx +35 -0
- package/lib/shared/ui/brandLogos.tsx +14 -0
- package/lib/shared/ui/button/Button.tsx +117 -0
- package/lib/shared/ui/button/index.ts +1 -0
- package/lib/shared/ui/button/model/helpers.ts +16 -0
- package/lib/shared/ui/formControlElements/CheckboxControl.tsx +92 -0
- package/lib/shared/ui/formControlElements/FormControl.tsx +5 -0
- package/lib/shared/ui/formControlElements/InputControlMask.tsx +90 -0
- package/lib/shared/ui/formControlElements/RadioControl.tsx +130 -0
- package/lib/shared/ui/formControlElements/SwitchControl.tsx +79 -0
- package/lib/shared/ui/formControlElements/TextareaControl.tsx +96 -0
- package/lib/shared/ui/formControlElements/calendarControl/CalendarControl.tsx +178 -0
- package/lib/shared/ui/formControlElements/calendarControl/hooks/index.ts +2 -0
- package/lib/shared/ui/formControlElements/calendarControl/hooks/useCalendar.tsx +86 -0
- package/lib/shared/ui/formControlElements/calendarControl/hooks/useCalendarDropdowns.ts +38 -0
- package/lib/shared/ui/formControlElements/calendarControl/index.ts +1 -0
- package/lib/shared/ui/formControlElements/calendarControl/model/helpers.ts +60 -0
- package/lib/shared/ui/formControlElements/calendarControl/model/types.ts +44 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/DaysOfMonth.tsx +53 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/DaysOfWeek.tsx +28 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/Dropdown.tsx +62 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/Header.tsx +51 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/Navigation.tsx +32 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/OptionsList.tsx +44 -0
- package/lib/shared/ui/formControlElements/calendarControl/ui/index.ts +4 -0
- package/lib/shared/ui/formControlElements/comboboxControl/ComboboxControl.tsx +134 -0
- package/lib/shared/ui/formControlElements/comboboxControl/index.ts +1 -0
- package/lib/shared/ui/formControlElements/comboboxControl/model/selectClassnames.ts +51 -0
- package/lib/shared/ui/formControlElements/comboboxControl/model/types.ts +42 -0
- package/lib/shared/ui/formControlElements/comboboxControl/ui/ComboboxOption.tsx +38 -0
- package/lib/shared/ui/formControlElements/comboboxControl/ui/DropdownIndicator.tsx +23 -0
- package/lib/shared/ui/formControlElements/comboboxControl/ui/MultiValueRemove.tsx +16 -0
- package/lib/shared/ui/formControlElements/comboboxControl/ui/index.ts +3 -0
- package/lib/shared/ui/formControlElements/dadata/DadataInputControl.tsx +137 -0
- package/lib/shared/ui/formControlElements/dadata/index.ts +1 -0
- package/lib/shared/ui/formControlElements/dadata/model/api.ts +25 -0
- package/lib/shared/ui/formControlElements/dadata/model/helpers.ts +76 -0
- package/lib/shared/ui/formControlElements/dadata/model/types.ts +52 -0
- package/lib/shared/ui/formControlElements/dadata/model/useDadata.ts +25 -0
- package/lib/shared/ui/formControlElements/editorControl/EditorControl.tsx +82 -0
- package/lib/shared/ui/formControlElements/editorControl/components/conrols.tsx +136 -0
- package/lib/shared/ui/formControlElements/editorControl/components/menu.tsx +107 -0
- package/lib/shared/ui/formControlElements/editorControl/index.ts +60 -0
- package/lib/shared/ui/formControlElements/editorControl/ui/RemoveBlockButton.tsx +23 -0
- package/lib/shared/ui/formControlElements/editorControl/ui/ResetBlockType.tsx +17 -0
- package/lib/shared/ui/formControlElements/index.ts +14 -0
- package/lib/shared/ui/formControlElements/inputControl/InputControl.tsx +87 -0
- package/lib/shared/ui/formControlElements/inputControl/index.ts +1 -0
- package/lib/shared/ui/formControlElements/inputControl/model/hooks.tsx +26 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/InputControlUploader.tsx +47 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/index.ts +1 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/model/helpers.ts +18 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/model/hooks/useUploader.tsx +66 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/model/index.ts +1 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/model/types.ts +22 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/ui/File.tsx +35 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/ui/Filename.tsx +40 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/ui/Files.tsx +30 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/ui/Input.tsx +48 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/ui/Uploader.tsx +58 -0
- package/lib/shared/ui/formControlElements/inputControlUploader/ui/index.ts +3 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/InputCurrencyControl.tsx +88 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/index.ts +1 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/model/helpers.ts +46 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/model/useInputCurrency.tsx +33 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/ui/MenuTrigger.tsx +20 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/ui/OptionList.tsx +29 -0
- package/lib/shared/ui/formControlElements/inputCurrencyControl/ui/index.ts +2 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/InputSliderControl.tsx +144 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/index.ts +1 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/dates/getEndWordMonth.ts +14 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/dates/getYearEnding.ts +13 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/dates/index.ts +2 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/formatNumber.ts +6 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/getInputSliderSuffix.ts +20 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/getStepByVariant.ts +29 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/index.ts +4 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/types.ts +1 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/model/useSlider.ts +26 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/ui/SliderControl.tsx +47 -0
- package/lib/shared/ui/formControlElements/inputSliderControl/ui/index.ts +1 -0
- package/lib/shared/ui/formControlElements/model/classes-types.ts +22 -0
- package/lib/shared/ui/formControlElements/model/index.ts +2 -0
- package/lib/shared/ui/formControlElements/model/message-view-animation.ts +6 -0
- package/lib/shared/ui/formControlElements/model/props-types.ts +31 -0
- package/lib/shared/ui/formControlElements/ui/FieldAttachment.tsx +76 -0
- package/lib/shared/ui/formControlElements/ui/FieldContainer.tsx +37 -0
- package/lib/shared/ui/formControlElements/ui/FieldWrapper.tsx +33 -0
- package/lib/shared/ui/formControlElements/ui/Label.tsx +32 -0
- package/lib/shared/ui/formControlElements/ui/MessageView.tsx +41 -0
- package/lib/shared/ui/formControlElements/ui/index.ts +4 -0
- package/lib/shared/ui/icon/Icon.tsx +41 -0
- package/lib/shared/ui/icon/index.ts +2 -0
- package/lib/shared/ui/icon/sprite.gen.ts +177 -0
- package/lib/shared/ui/index.ts +68 -0
- package/lib/shared/ui/modal/Modal.tsx +68 -0
- package/lib/shared/ui/modal/index.ts +1 -0
- package/lib/shared/ui/modal/model/helpers.ts +13 -0
- package/lib/shared/ui/modal/ui/ModalHeader.tsx +33 -0
- package/lib/shared/ui/notification/Notification.tsx +31 -0
- package/lib/shared/ui/notification/index.ts +1 -0
- package/lib/shared/ui/notification/ui/CustomToast.tsx +42 -0
- package/lib/shared/ui/popover/Popover.tsx +74 -0
- package/lib/shared/ui/popover/index.ts +1 -0
- package/lib/shared/ui/providers/NotificationProvider.tsx +29 -0
- package/lib/shared/ui/providers/index.ts +1 -0
- package/lib/shared/ui/table/Table.tsx +144 -0
- package/lib/shared/ui/table/index.ts +1 -0
- package/lib/shared/ui/table/type.ts +30 -0
- package/lib/shared/utils/capitalize.ts +6 -0
- package/lib/shared/utils/cn.ts +6 -0
- package/lib/shared/utils/deepCompare.ts +1 -0
- package/lib/shared/utils/formatToDate.ts +5 -0
- package/lib/shared/utils/index.ts +5 -0
- package/lib/shared/utils/isClient.ts +1 -0
- package/lib/shared/validation/index.ts +3 -0
- package/lib/shared/validation/messages.ts +12 -0
- package/lib/shared/validation/regExp.ts +5 -0
- package/lib/shared/validation/zodValidation/calendar.ts +32 -0
- package/lib/shared/validation/zodValidation/dadataFio.ts +67 -0
- package/lib/shared/validation/zodValidation/index.ts +2 -0
- package/lib/vite-env.d.ts +2 -0
- package/lib/widgets/Advantages.tsx +45 -0
- package/lib/widgets/banner/Banner.tsx +74 -0
- package/lib/widgets/banner/index.ts +1 -0
- package/lib/widgets/banner/model/helpers.ts +159 -0
- package/lib/widgets/banner/money.png +0 -0
- package/lib/widgets/banner/saif.jpg +0 -0
- package/lib/widgets/banner/saifMob.jpg +0 -0
- package/lib/widgets/banner/seif.jpg +0 -0
- package/lib/widgets/banner/shield.jpg +0 -0
- package/lib/widgets/banner/shield.png +0 -0
- package/lib/widgets/banner/ui/BannerButtonsGroup.tsx +44 -0
- package/lib/widgets/banner/ui/banners/BannerImageFull.tsx +82 -0
- package/lib/widgets/banner/ui/banners/BannerWithSeparateImg.tsx +60 -0
- package/lib/widgets/banner/ui/banners/index.ts +1 -0
- package/lib/widgets/footer/Footer.tsx +95 -0
- package/lib/widgets/footer/index.ts +1 -0
- package/lib/widgets/footer/model/defaultValues.tsx +105 -0
- package/lib/widgets/footer/model/types.ts +19 -0
- package/lib/widgets/footer/ui/Copyright.tsx +15 -0
- package/lib/widgets/footer/ui/Ligal.tsx +50 -0
- package/lib/widgets/footer/ui/NavLinks.tsx +41 -0
- package/lib/widgets/footer/ui/PhonesBlock.tsx +34 -0
- package/lib/widgets/footer/ui/SocialLinks.tsx +30 -0
- package/lib/widgets/footer/ui/index.ts +5 -0
- package/lib/widgets/index.ts +5 -0
- package/lib/widgets/pageHeader/PageHeader.tsx +54 -0
- package/lib/widgets/pageHeader/index.ts +1 -0
- package/lib/widgets/stepper/Stepper.tsx +43 -0
- package/lib/widgets/stepper/index.ts +1 -0
- package/lib/widgets/stepper/ui/SingleStep.tsx +42 -0
- package/package.json +1 -4
- package/postcss.config.mjs +8 -0
- package/public/sprites/arrows.svg +1 -0
- package/public/sprites/brandLogos.svg +1 -0
- package/public/sprites/files.svg +1 -0
- package/public/sprites/general.svg +1 -0
- package/public/sprites/info.svg +1 -0
- package/public/sprites/social.svg +1 -0
- package/src/App.tsx +9 -0
- package/src/app/providers/RootProvider.tsx +11 -0
- package/src/app/providers/index.ts +1 -0
- package/src/app/providers/model/types.ts +5 -0
- package/src/configs/setup.ts +9 -0
- package/src/configs/storybook.config.ts +23 -0
- package/src/main.tsx +10 -0
- package/src/stories/primitives/Accordion.stories.tsx +66 -0
- package/src/stories/primitives/Badge.stories.tsx +28 -0
- package/src/stories/primitives/Breadcrumbs.stories.tsx +29 -0
- package/src/stories/primitives/Button/Button.stories.tsx +149 -0
- package/src/stories/primitives/Button/Button.test.tsx +150 -0
- package/src/stories/primitives/ButtonIcon.stories.tsx +75 -0
- package/src/stories/primitives/CustomLink.stories.tsx +64 -0
- package/src/stories/primitives/Document.stories.tsx +36 -0
- package/src/stories/primitives/Heading.stories.tsx +29 -0
- package/src/stories/primitives/Hint.stories.tsx +82 -0
- package/src/stories/primitives/Icon.stories.tsx +36 -0
- package/src/stories/primitives/Loader.stories.tsx +39 -0
- package/src/stories/primitives/Modal.stories.tsx +106 -0
- package/src/stories/primitives/Notification.stories.tsx +102 -0
- package/src/stories/primitives/PhoneView.stories.tsx +22 -0
- package/src/stories/primitives/Popover.stories.tsx +41 -0
- package/src/stories/primitives/ProgressBar.stories.tsx +68 -0
- package/src/stories/primitives/Skeleton.stories.tsx +21 -0
- package/src/stories/primitives/Table.stories.tsx +44 -0
- package/src/stories/primitives/TabsSwitcher.stories.tsx +45 -0
- package/src/stories/primitives/formControl/CalendarControl.stories.tsx +45 -0
- package/src/stories/primitives/formControl/CheckboxControl.stories.tsx +64 -0
- package/src/stories/primitives/formControl/ComboboxControl.stories.tsx +67 -0
- package/src/stories/primitives/formControl/DadataInputControl.stories.tsx +79 -0
- package/src/stories/primitives/formControl/EditorControl.stories.tsx +31 -0
- package/src/stories/primitives/formControl/FormControlAllFields.stories.tsx +25 -0
- package/src/stories/primitives/formControl/InputControl.stories.tsx +84 -0
- package/src/stories/primitives/formControl/InputControlPassword.stories.tsx +38 -0
- package/src/stories/primitives/formControl/InputControlUploader.stories.tsx +44 -0
- package/src/stories/primitives/formControl/InputCurrencyControl.stories.tsx +73 -0
- package/src/stories/primitives/formControl/InputSliderControl.stories.tsx +62 -0
- package/src/stories/primitives/formControl/RadioContol.stories.tsx +61 -0
- package/src/stories/primitives/formControl/SwitchControl.stories.tsx +51 -0
- package/src/stories/primitives/formControl/TextareaControl.stories.tsx +55 -0
- package/src/stories/primitives/formControl/inputControlMask.stories.tsx +67 -0
- package/src/stories/widgets/Advantages.stories.tsx +42 -0
- package/src/stories/widgets/Banner.stories.tsx +94 -0
- package/src/stories/widgets/Footer.stories.tsx +36 -0
- package/src/stories/widgets/PageHeader.stories.tsx +33 -0
- package/src/stories/widgets/Stepper.stories.tsx +24 -0
- package/src/storybookHelpers/actions.tsx +5 -0
- package/src/storybookHelpers/index.ts +2 -0
- package/src/storybookHelpers/reactHookForm/index.ts +3 -0
- package/src/storybookHelpers/reactHookForm/model/mockData.ts +19 -0
- package/src/storybookHelpers/reactHookForm/model/mocks.tsx +105 -0
- package/src/storybookHelpers/reactHookForm/model/renderFields.tsx +58 -0
- package/src/storybookHelpers/reactHookForm/model/types.ts +86 -0
- package/src/storybookHelpers/reactHookForm/ui/StorybookFieldsMapper.tsx +32 -0
- package/src/storybookHelpers/reactHookForm/ui/StorybookFormProvider.tsx +43 -0
- package/src/storybookHelpers/reactHookForm/ui/index.ts +2 -0
- package/src/storybookHelpers/table/utils/defaultValue.ts +51 -0
- package/static/arrows/arrowCircle.svg +18 -0
- package/static/arrows/arrowLink.svg +3 -0
- package/static/arrows/arrowRight.svg +3 -0
- package/static/brandLogos/logoBlack.svg +14 -0
- package/static/brandLogos/logoBusiness.svg +80 -0
- package/static/brandLogos/logoGray.svg +56 -0
- package/static/brandLogos/logoInsurance.svg +124 -0
- package/static/brandLogos/logoMain.svg +14 -0
- package/static/brandLogos/logoWhite.svg +56 -0
- package/static/files/border.svg +6 -0
- package/static/files/borderError.svg +6 -0
- package/static/files/documentFilled.svg +4 -0
- package/static/files/documentOutline.svg +4 -0
- package/static/files/upload.svg +3 -0
- package/static/general/calendar.svg +3 -0
- package/static/general/check.svg +6 -0
- package/static/general/close.svg +12 -0
- package/static/general/edit.svg +4 -0
- package/static/general/hiddenEye.svg +4 -0
- package/static/general/plus.svg +3 -0
- package/static/general/showEye.svg +4 -0
- package/static/info/warningCircle.svg +5 -0
- package/static/social/classmates.svg +3 -0
- package/static/social/telegram.svg +3 -0
- package/static/social/vk.svg +3 -0
- package/tailwind.config.ts +10 -0
- package/tsconfig.json +33 -0
- package/tsconfig.node.json +11 -0
- package/vite.config.ts +68 -0
- package/vitest.config.mjs +12 -0
- package/dist/scbt-ecom-ui-0.4.1.tgz +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type ComponentProps, forwardRef, type ReactElement } from 'react'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '$/shared/utils'
|
|
4
|
+
|
|
5
|
+
type TButtonClasses = {
|
|
6
|
+
button: string
|
|
7
|
+
icon: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const buttonConfig = cva(
|
|
11
|
+
'group flex items-center justify-center cursor-pointer rounded-full outline-offset-[3px] outline-transparent outline-2 transition duration-12 active:scale-[0.97] disabled:pointer-events-none',
|
|
12
|
+
{
|
|
13
|
+
variants: {
|
|
14
|
+
intent: {
|
|
15
|
+
primary:
|
|
16
|
+
'text-icon-white bg-color-primary-default hover:bg-color-primary-hover active:bg-color-primary-hover focus:bg-color-primary-hover focus:outline-primary-focus disabled:bg-color-primary-disabled',
|
|
17
|
+
secondary:
|
|
18
|
+
'text-icon-primary-default bg-color-transparent border border-solid outline-offset-4 border-primary-default hover:bg-color-primary-tr-hover hover:text-icon-primary-default hover:border-primary-hover active:bg-color-primary-tr-pressed active:border-primary-hover active:text-icon-primary-hover focus:bg-color-primary-tr-focus focus:outline-primary-focus disabled:bg-color-blue-grey-200 disabled:border-transparent disabled:text-icon-primary-disabled',
|
|
19
|
+
ghost:
|
|
20
|
+
'text-icon-primary-default bg-color-transparent hover:bg-color-primary-tr-hover focus:bg-color-primary-tr-focus focus:outline-primary-focus active:text-icon-primary-hover active:bg-color-primary-tr-pressed disabled:bg-color-transparent disabled:text-icon-primary-disabled'
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
sm: 'size-8',
|
|
24
|
+
md: 'size-10',
|
|
25
|
+
lg: 'size-12'
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
intent: 'primary',
|
|
30
|
+
size: 'lg'
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
type TButtonProps = VariantProps<typeof buttonConfig>
|
|
36
|
+
|
|
37
|
+
export interface IButtonIconProps extends Omit<ComponentProps<'button'>, 'className'>, TButtonProps {
|
|
38
|
+
children: ReactElement
|
|
39
|
+
classes?: Partial<TButtonClasses>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const ButtonIcon = forwardRef<HTMLButtonElement, IButtonIconProps>(
|
|
43
|
+
({ size, intent, children, classes, type = 'button', ...props }, ref) => {
|
|
44
|
+
return (
|
|
45
|
+
<button ref={ref} type={type} className={cn(buttonConfig({ intent, size }), classes?.button)} {...props}>
|
|
46
|
+
<span className={cn(classes?.icon)}>{children}</span>
|
|
47
|
+
</button>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type ComponentProps } from 'react'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '../utils'
|
|
4
|
+
import { Icon, type TAllowedIcons } from './icon/Icon'
|
|
5
|
+
|
|
6
|
+
const customLinkConfig = cva(
|
|
7
|
+
'group underline underline-offset-4 outline-none p-[2px] rounded-sm border border-solid border-transparent',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
intent: {
|
|
11
|
+
blue: 'text-color-primary-default hover:text-color-primary-hover focus:text-color-primary-default focus:border-primary-focus',
|
|
12
|
+
white: 'text-color-white hover:text-color-footer focus:text-color-white focus:border-primary-focus'
|
|
13
|
+
},
|
|
14
|
+
withIcon: {
|
|
15
|
+
true: 'flex items-center gap-1',
|
|
16
|
+
false: ''
|
|
17
|
+
},
|
|
18
|
+
disabled: {
|
|
19
|
+
true: '!text-color-primary-disabled pointer-events-none !border-transparent',
|
|
20
|
+
false: ''
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
sm: 'desk-body-regular-m',
|
|
24
|
+
md: 'desk-body-regular-l'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
intent: 'blue',
|
|
29
|
+
withIcon: true,
|
|
30
|
+
disabled: false,
|
|
31
|
+
size: 'sm'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const linkArrowConfig = cva('size-6', {
|
|
37
|
+
variants: {
|
|
38
|
+
intent: {
|
|
39
|
+
blue: 'text-icon-primary-default group-hover:text-icon-primary-hover group-focus:text-icon-primary-default ',
|
|
40
|
+
white: 'text-icon-white group-hover:text-icon-footer group-focus:text-icon-white'
|
|
41
|
+
},
|
|
42
|
+
disabled: {
|
|
43
|
+
true: '!text-icon-primary-disabled pointer-events-none',
|
|
44
|
+
false: ''
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
defaultVariants: {
|
|
48
|
+
intent: 'blue',
|
|
49
|
+
disabled: false
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
type TCustomLinkConfig = VariantProps<typeof customLinkConfig>
|
|
54
|
+
|
|
55
|
+
export interface ICustomLinkProps extends TCustomLinkConfig, Omit<ComponentProps<'a'>, 'className'> {
|
|
56
|
+
Component?: 'a'
|
|
57
|
+
icon?: TAllowedIcons
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const CustomLink = ({
|
|
61
|
+
Component = 'a',
|
|
62
|
+
intent,
|
|
63
|
+
children,
|
|
64
|
+
withIcon,
|
|
65
|
+
disabled,
|
|
66
|
+
size,
|
|
67
|
+
icon = 'arrows/arrowLink',
|
|
68
|
+
...props
|
|
69
|
+
}: ICustomLinkProps) => {
|
|
70
|
+
return (
|
|
71
|
+
<Component className={cn(customLinkConfig({ intent, withIcon, disabled, size }))} {...props}>
|
|
72
|
+
{children}
|
|
73
|
+
{withIcon && <Icon name={icon} className={cn(linkArrowConfig({ intent, disabled }))} />}
|
|
74
|
+
</Component>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
2
|
+
import { Icon, type TAllowedIcons } from './icon'
|
|
3
|
+
import { cn } from '$/shared/utils'
|
|
4
|
+
|
|
5
|
+
const iconConfig = cva('size-8 transition-colors', {
|
|
6
|
+
variants: {
|
|
7
|
+
intent: {
|
|
8
|
+
outline: 'text-icon-secondary-dark-default group-hover:text-icon-secondary-dark-hover',
|
|
9
|
+
filled: 'text-icon-primary-default group-hover:text-icon-primary-hover'
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
defaultVariants: {
|
|
13
|
+
intent: 'outline'
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
type TIconConfig = VariantProps<typeof iconConfig>
|
|
18
|
+
|
|
19
|
+
const iconVariant: Record<NonNullable<TIconConfig['intent']>, TAllowedIcons> = {
|
|
20
|
+
filled: 'files/documentFilled',
|
|
21
|
+
outline: 'files/documentOutline'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IDocumentProps extends TIconConfig {
|
|
25
|
+
text: string
|
|
26
|
+
size: number
|
|
27
|
+
sizeType: 'КБ' | 'МБ'
|
|
28
|
+
href: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const Document = ({ text, size, sizeType, href, intent = 'outline' }: IDocumentProps) => {
|
|
32
|
+
return (
|
|
33
|
+
<a
|
|
34
|
+
href={href}
|
|
35
|
+
target='_blank'
|
|
36
|
+
rel='noreferrer'
|
|
37
|
+
tabIndex={0}
|
|
38
|
+
className={cn(
|
|
39
|
+
'group flex max-w-[288px] cursor-pointer items-center gap-2 rounded-sm p-1 outline outline-2 outline-transparent transition-colors focus-within:outline-primary-focus desktop:max-w-[592px]'
|
|
40
|
+
)}
|
|
41
|
+
>
|
|
42
|
+
<Icon name={iconVariant[intent!]} className={cn(iconConfig({ intent }))} />
|
|
43
|
+
<div className={cn('flex flex-1 flex-col')}>
|
|
44
|
+
<p className={cn('desk-body-medium-l text-color-dark')}>{text}</p>
|
|
45
|
+
<div className={cn('desk-body-regular-m text-color-disabled')}>
|
|
46
|
+
{size} {sizeType}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</a>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '$/shared/utils'
|
|
4
|
+
|
|
5
|
+
const headingConfig = cva('', {
|
|
6
|
+
variants: {
|
|
7
|
+
as: {
|
|
8
|
+
h1: 'mob-headline-bold-m desktop:desk-headline-bold-l',
|
|
9
|
+
h2: 'mob-headline-bold-s desktop:desk-headline-bold-m',
|
|
10
|
+
h3: 'mob-title-bold-l desktop:desk-title-bold-l',
|
|
11
|
+
h4: 'mob-title-bold-m desktop:desk-title-bold-s'
|
|
12
|
+
// # add h5 and h6 if need
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
as: 'h2'
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export interface IHeadingProps extends VariantProps<typeof headingConfig> {
|
|
21
|
+
children: ReactNode
|
|
22
|
+
className?: string
|
|
23
|
+
as?: 'h1' | 'h2' | 'h3' | 'h4'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const Heading = ({ as = 'h2', children, className, ...props }: IHeadingProps) => {
|
|
27
|
+
const Element = as
|
|
28
|
+
return (
|
|
29
|
+
<Element className={cn(headingConfig({ as }), className)} {...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</Element>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import type { TooltipContentProps } from '@radix-ui/react-tooltip'
|
|
5
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip'
|
|
6
|
+
import { useClickOutside } from '../hooks'
|
|
7
|
+
import { useDevice } from '../hooks/useMediaQuery'
|
|
8
|
+
import { cn } from '$/shared/utils'
|
|
9
|
+
|
|
10
|
+
type TAdditionalClasses = {
|
|
11
|
+
content: string
|
|
12
|
+
arrow: string
|
|
13
|
+
trigger: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface IHintContentProps extends TooltipContentProps {
|
|
17
|
+
delayDuration?: number
|
|
18
|
+
sideOffset?: number
|
|
19
|
+
align?: 'end' | 'center' | 'start'
|
|
20
|
+
side?: 'top' | 'right' | 'bottom' | 'left'
|
|
21
|
+
defaultOpen?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IHintProps extends IHintContentProps {
|
|
25
|
+
triggerElement: React.ReactElement
|
|
26
|
+
children: React.ReactElement | string
|
|
27
|
+
classes?: Partial<TAdditionalClasses>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const Hint = ({
|
|
31
|
+
triggerElement,
|
|
32
|
+
children,
|
|
33
|
+
delayDuration = 250,
|
|
34
|
+
sideOffset = 6,
|
|
35
|
+
align = 'center',
|
|
36
|
+
side = 'top',
|
|
37
|
+
defaultOpen = false,
|
|
38
|
+
classes,
|
|
39
|
+
...contentProps
|
|
40
|
+
}: IHintProps) => {
|
|
41
|
+
const [open, setOpen] = React.useState(false)
|
|
42
|
+
const contentRef = React.useRef<HTMLDivElement>(null)
|
|
43
|
+
const { isMobile } = useDevice()
|
|
44
|
+
|
|
45
|
+
useClickOutside(contentRef, () => setOpen(false))
|
|
46
|
+
return (
|
|
47
|
+
<TooltipPrimitive.Provider>
|
|
48
|
+
<TooltipPrimitive.Root open={open} onOpenChange={setOpen} defaultOpen={defaultOpen} delayDuration={delayDuration}>
|
|
49
|
+
<div onClick={() => setOpen(isMobile ? true : false)}>
|
|
50
|
+
<TooltipPrimitive.Trigger asChild className={cn('cursor-pointer', classes?.trigger)}>
|
|
51
|
+
{triggerElement}
|
|
52
|
+
</TooltipPrimitive.Trigger>
|
|
53
|
+
<TooltipPrimitive.Content
|
|
54
|
+
onPointerDownOutside={(event) => event.preventDefault()}
|
|
55
|
+
className={cn(
|
|
56
|
+
'desk-body-regular-m w-48 origin-center animate-scale-in rounded-sm bg-color-white p-4 text-color-dark shadow-sm',
|
|
57
|
+
classes?.content
|
|
58
|
+
)}
|
|
59
|
+
sideOffset={sideOffset}
|
|
60
|
+
align={align}
|
|
61
|
+
side={side}
|
|
62
|
+
ref={contentRef}
|
|
63
|
+
{...contentProps}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
<TooltipPrimitive.Arrow width={12} height={6} className={cn('fill-white', classes?.arrow)} />
|
|
67
|
+
</TooltipPrimitive.Content>
|
|
68
|
+
</div>
|
|
69
|
+
</TooltipPrimitive.Root>
|
|
70
|
+
</TooltipPrimitive.Provider>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactElement } from 'react'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '$/shared/utils'
|
|
4
|
+
|
|
5
|
+
const wrapperConfig = cva('', {
|
|
6
|
+
variants: {
|
|
7
|
+
position: {
|
|
8
|
+
absolute: 'absolute',
|
|
9
|
+
static: 'static',
|
|
10
|
+
fixed: 'fixed'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
position: 'static'
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const loaderConfig = cva('border-2 border-solid block animate-spin rounded-full', {
|
|
19
|
+
variants: {
|
|
20
|
+
intent: {
|
|
21
|
+
primary: 'border-white border-b-transparent',
|
|
22
|
+
secondary: 'border-primary-default border-b-transparent'
|
|
23
|
+
},
|
|
24
|
+
size: {
|
|
25
|
+
sm: 'size-5 border-2',
|
|
26
|
+
md: 'size-8 border-2',
|
|
27
|
+
lg: 'size-12 border-4'
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
size: 'md',
|
|
32
|
+
intent: 'primary'
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
type ILoaderClasses = {
|
|
37
|
+
wrapper: string
|
|
38
|
+
loader: string
|
|
39
|
+
text: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ILoaderProps
|
|
43
|
+
extends VariantProps<typeof loaderConfig>,
|
|
44
|
+
VariantProps<typeof wrapperConfig>,
|
|
45
|
+
Omit<HTMLAttributes<HTMLDivElement>, 'className'> {
|
|
46
|
+
intent?: 'primary' | 'secondary'
|
|
47
|
+
text?: ReactElement | string
|
|
48
|
+
classes?: Partial<ILoaderClasses>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const Loader = ({ size = 'md', classes, intent = 'secondary', position = 'static', text, ...props }: ILoaderProps) => {
|
|
52
|
+
return (
|
|
53
|
+
<div className={cn(wrapperConfig({ position }), { 'flex flex-col items-center gap-2': text }, classes?.wrapper)}>
|
|
54
|
+
<span data-testid='loader' className={cn(loaderConfig({ size, intent }), classes?.loader)} {...props}></span>
|
|
55
|
+
{text && <p className={cn('desk-body-regular-l text-color-dark', classes?.text)}>{text}</p>}
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { cn } from '../utils'
|
|
2
|
+
|
|
3
|
+
interface IPhoneViewClasses {
|
|
4
|
+
wrapper: string
|
|
5
|
+
link: string
|
|
6
|
+
text: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IPhoneViewProps {
|
|
10
|
+
phone: string
|
|
11
|
+
text: string
|
|
12
|
+
classes?: Partial<IPhoneViewClasses>
|
|
13
|
+
}
|
|
14
|
+
export const PhoneView = ({ phone, text, classes }: IPhoneViewProps) => {
|
|
15
|
+
return (
|
|
16
|
+
<div className={cn('flex w-max flex-col', classes?.wrapper)}>
|
|
17
|
+
<a href={`tel:${phone}`} className={cn('desk-body-medium-l ml-auto text-color-dark', classes?.link)}>
|
|
18
|
+
{phone}
|
|
19
|
+
</a>
|
|
20
|
+
<p className={cn('desk-body-regular-l text-color-tetriary', classes?.text)}>{text}</p>
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { cn } from '../utils'
|
|
3
|
+
|
|
4
|
+
type IProgressBarClasses = {
|
|
5
|
+
wrapper: string
|
|
6
|
+
topContent: string
|
|
7
|
+
bottomContent: string
|
|
8
|
+
progressBar: string
|
|
9
|
+
progress: string
|
|
10
|
+
loader: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IProgressBarProps {
|
|
14
|
+
topContent?: React.ReactElement
|
|
15
|
+
bottomContent?: React.ReactElement
|
|
16
|
+
progress: number
|
|
17
|
+
maxPercent?: number
|
|
18
|
+
classes?: Partial<IProgressBarClasses>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const ProgressBar = ({ topContent, bottomContent, progress, maxPercent = 100, classes }: IProgressBarProps) => {
|
|
22
|
+
return (
|
|
23
|
+
<div className={cn('flex flex-col', classes?.wrapper)}>
|
|
24
|
+
{topContent && <div className={cn('mb-2 flex justify-between gap-5', classes?.topContent)}>{topContent}</div>}
|
|
25
|
+
|
|
26
|
+
<div className={cn('relative h-2 w-[328xp] rounded-md bg-color-blue-grey-100 desktop:w-[524px]', classes?.progressBar)}>
|
|
27
|
+
<div
|
|
28
|
+
style={{ width: `${progress}%` }}
|
|
29
|
+
className={cn('relative z-10 h-2 rounded-md bg-color-positive transition-all', classes?.progress)}
|
|
30
|
+
></div>
|
|
31
|
+
<span
|
|
32
|
+
style={{ maxWidth: `${maxPercent}%` }}
|
|
33
|
+
className={cn(
|
|
34
|
+
'progressBar-apply absolute top-1/2 z-1 h-full w-full -translate-y-1/2 animate-progress-loader rounded-md',
|
|
35
|
+
classes?.loader
|
|
36
|
+
)}
|
|
37
|
+
></span>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
{bottomContent && <div className={cn('mt-2 flex justify-between gap-5', classes?.bottomContent)}>{bottomContent}</div>}
|
|
41
|
+
</div>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
2
|
+
import { cn } from '$/shared/utils'
|
|
3
|
+
|
|
4
|
+
export interface IResponsiveContainerProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
children: ReactNode
|
|
6
|
+
className?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const ResponsiveContainer = ({ children, className, ...props }: IResponsiveContainerProps) => {
|
|
10
|
+
return (
|
|
11
|
+
<div className={cn('m-auto w-full px-4 desktop:max-w-[1188px]', className)} {...props}>
|
|
12
|
+
{children}
|
|
13
|
+
</div>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
2
|
+
import { cn } from '$/shared/utils'
|
|
3
|
+
|
|
4
|
+
export interface ISectionProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
children: ReactNode
|
|
6
|
+
className?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Section = ({ children, className, ...props }: ISectionProps) => {
|
|
10
|
+
return (
|
|
11
|
+
<section className={cn('pb-16 desktop:pb-20', className)} {...props}>
|
|
12
|
+
{children}
|
|
13
|
+
</section>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import * as TabPrimitive from '@radix-ui/react-tabs'
|
|
5
|
+
import { cn } from '../utils'
|
|
6
|
+
import { Accordion } from './accordion'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {string} id - для триггера и для контента должен совпадать
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface ITabsClasses {
|
|
13
|
+
root: string
|
|
14
|
+
list: string
|
|
15
|
+
trigger: string
|
|
16
|
+
content: string
|
|
17
|
+
contentsWrapper: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ITabContent {
|
|
21
|
+
id: string
|
|
22
|
+
body: React.ReactElement | string
|
|
23
|
+
accordion?: {
|
|
24
|
+
title: string
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface ITabTrigger {
|
|
29
|
+
id: string
|
|
30
|
+
label: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface ITabRenderContent {
|
|
34
|
+
triggers: ITabTrigger[]
|
|
35
|
+
contents: ITabContent[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ITabsSwitcherProps {
|
|
39
|
+
renderContent: ITabRenderContent
|
|
40
|
+
value: string
|
|
41
|
+
onChangeTab: (tab: string) => void
|
|
42
|
+
defaultActiveTabId?: string
|
|
43
|
+
classes?: Partial<ITabsClasses>
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const TabsSwitcher = ({ renderContent, defaultActiveTabId = '1', value, onChangeTab, classes }: ITabsSwitcherProps) => {
|
|
47
|
+
return (
|
|
48
|
+
<TabPrimitive.Root
|
|
49
|
+
value={value}
|
|
50
|
+
onValueChange={onChangeTab}
|
|
51
|
+
defaultValue={defaultActiveTabId}
|
|
52
|
+
className={cn('flex flex-col', classes?.root)}
|
|
53
|
+
>
|
|
54
|
+
<TabPrimitive.List aria-label='Manage your account' className={cn('flex items-center gap-4', classes?.list)}>
|
|
55
|
+
{renderContent?.triggers?.map(({ id, label }) => (
|
|
56
|
+
<TabPrimitive.Trigger
|
|
57
|
+
key={id}
|
|
58
|
+
value={id}
|
|
59
|
+
className={cn(
|
|
60
|
+
'desk-body-regular-l cursor-pointer rounded-sm bg-color-blue-grey-100 px-4 py-2 text-color-secondary outline outline-2 outline-offset-2 outline-transparent transition-colors hover:bg-color-blue-grey-200 hover:text-color-secondary data-[state="active"]:!bg-color-primary-default data-[state="active"]:!text-color-white',
|
|
61
|
+
classes?.trigger
|
|
62
|
+
)}
|
|
63
|
+
>
|
|
64
|
+
{label}
|
|
65
|
+
</TabPrimitive.Trigger>
|
|
66
|
+
))}
|
|
67
|
+
</TabPrimitive.List>
|
|
68
|
+
<div className={cn('flex flex-col gap-4', classes?.contentsWrapper)}>
|
|
69
|
+
{renderContent?.contents?.map(({ id, body, accordion }) => {
|
|
70
|
+
if (accordion && accordion?.title) {
|
|
71
|
+
return (
|
|
72
|
+
<TabPrimitive.Content key={id} value={id} className={cn('py-8', classes?.content)}>
|
|
73
|
+
<Accordion label={accordion?.title}>{body}</Accordion>
|
|
74
|
+
</TabPrimitive.Content>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<TabPrimitive.Content key={id} value={id} className={cn('py-8', classes?.content)}>
|
|
80
|
+
{body}
|
|
81
|
+
</TabPrimitive.Content>
|
|
82
|
+
)
|
|
83
|
+
})}
|
|
84
|
+
</div>
|
|
85
|
+
</TabPrimitive.Root>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import * as AccordionPrimitive from '@radix-ui/react-accordion'
|
|
5
|
+
import type { TAccordionHeaderClasses, TAccordionRootClasses } from './model/types'
|
|
6
|
+
import { AccordionHeader } from './ui/AccordionHeader'
|
|
7
|
+
import { cn } from '$/shared/utils'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {string[]} defaultOpen - По умолчанию открытые аккордеоны необходимо указать тот же label явно руками.
|
|
11
|
+
* Пример defaultValue={['Заголовок аккордеона 1', 'Заголовок аккордеона 2']}
|
|
12
|
+
*/
|
|
13
|
+
export interface IAccordionProps {
|
|
14
|
+
children: React.ReactNode
|
|
15
|
+
label: string | React.ReactElement
|
|
16
|
+
classes?: Partial<TAccordionHeaderClasses> & Partial<TAccordionRootClasses>
|
|
17
|
+
defaultOpen?: string[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const Accordion = ({ children, label, classes, defaultOpen }: IAccordionProps) => {
|
|
21
|
+
return (
|
|
22
|
+
<AccordionPrimitive.Root className={cn('flex flex-col gap-5', classes?.accordion)} type='multiple' defaultValue={defaultOpen}>
|
|
23
|
+
<AccordionPrimitive.Item className={cn('w-full disabled:text-color-dark', classes?.item)} value={label.toString()}>
|
|
24
|
+
<AccordionHeader classes={classes}>{label}</AccordionHeader>
|
|
25
|
+
<AccordionPrimitive.Content
|
|
26
|
+
className={cn(
|
|
27
|
+
'desk-body-regular-l overflow-hidden bg-color-transparent text-color-dark transition-all data-[state=closed]:animate-slideUp data-[state=open]:animate-slideDown',
|
|
28
|
+
classes?.content
|
|
29
|
+
)}
|
|
30
|
+
>
|
|
31
|
+
<div className={cn('p-6', classes?.contentInner)}>{children}</div>
|
|
32
|
+
</AccordionPrimitive.Content>
|
|
33
|
+
</AccordionPrimitive.Item>
|
|
34
|
+
</AccordionPrimitive.Root>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Accordion, type IAccordionProps } from './Accordion'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type * as React from 'react'
|
|
2
|
+
|
|
3
|
+
export type TAccordionHeaderClasses = {
|
|
4
|
+
trigger: string
|
|
5
|
+
icon: string
|
|
6
|
+
header: string
|
|
7
|
+
inner: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type TAccordionRootClasses = {
|
|
11
|
+
item: string
|
|
12
|
+
content: string
|
|
13
|
+
contentInner: string
|
|
14
|
+
accordion: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IAccordionItem {
|
|
18
|
+
label: string
|
|
19
|
+
content: React.ReactNode
|
|
20
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { Header, Trigger } from '@radix-ui/react-accordion'
|
|
5
|
+
import { Icon } from '../../icon/Icon'
|
|
6
|
+
import type { TAccordionHeaderClasses } from '../model/types'
|
|
7
|
+
import { cn } from '$/shared/utils'
|
|
8
|
+
|
|
9
|
+
interface IAccordionHeaderProps {
|
|
10
|
+
children?: React.ReactElement | string
|
|
11
|
+
classes?: Partial<TAccordionHeaderClasses>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const AccordionHeader = React.forwardRef<HTMLButtonElement, IAccordionHeaderProps>(
|
|
15
|
+
({ children, classes, ...props }, forwardedRef) => (
|
|
16
|
+
<Header className={cn('rounded-sm bg-color-primary-light-default', classes?.header)}>
|
|
17
|
+
<Trigger
|
|
18
|
+
ref={forwardedRef}
|
|
19
|
+
className={cn(
|
|
20
|
+
'group flex w-full cursor-pointer items-center justify-between gap-5 rounded-sm border border-solid border-transparent bg-color-transparent px-6 py-5 outline-0 focus:border-primary-default',
|
|
21
|
+
classes?.trigger
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
>
|
|
25
|
+
<div className={cn('desk-body-medium-l text-color-dark', classes?.inner)}>{children}</div>
|
|
26
|
+
<Icon
|
|
27
|
+
name='arrows/arrowCircle'
|
|
28
|
+
className={cn('size-8 text-icon-blue-grey-800 transition-all group-data-[state=open]:rotate-180', classes?.icon)}
|
|
29
|
+
/>
|
|
30
|
+
</Trigger>
|
|
31
|
+
</Header>
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
AccordionHeader.displayName = 'AccordionHeader'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactElement } from 'react'
|
|
2
|
+
import { Icon } from './icon/Icon'
|
|
3
|
+
|
|
4
|
+
export type TBrandLogoVariant = 'main' | 'white' | 'gray' | 'black' | 'business' | 'insurance'
|
|
5
|
+
type TBrandLogosVariants = Record<TBrandLogoVariant, ReactElement>
|
|
6
|
+
|
|
7
|
+
export const brandLogos: TBrandLogosVariants = {
|
|
8
|
+
main: <Icon name='brandLogos/logoMain' />,
|
|
9
|
+
white: <Icon name='brandLogos/logoWhite' />,
|
|
10
|
+
gray: <Icon name='brandLogos/logoGray' />,
|
|
11
|
+
black: <Icon name='brandLogos/logoBlack' />,
|
|
12
|
+
business: <Icon name='brandLogos/logoBusiness' />,
|
|
13
|
+
insurance: <Icon name='brandLogos/logoInsurance' />
|
|
14
|
+
} as const
|