@companix/uikit 0.0.1

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 (124) hide show
  1. package/.eslintrc +54 -0
  2. package/declaration.d.ts +4 -0
  3. package/index.html +12 -0
  4. package/package.json +66 -0
  5. package/playground/App.tsx +166 -0
  6. package/playground/Example.tsx +14 -0
  7. package/playground/Test.tsx +44 -0
  8. package/playground/animation-test-1/index.scss +20 -0
  9. package/playground/animation-test-1/index.tsx +17 -0
  10. package/playground/animation-test-2/index.scss +62 -0
  11. package/playground/animation-test-2/index.tsx +32 -0
  12. package/playground/bootstrap.tsx +19 -0
  13. package/playground/buttons/index.tsx +132 -0
  14. package/playground/checkbox/index.tsx +64 -0
  15. package/playground/date-input/index.tsx +45 -0
  16. package/playground/date-picker/index.tsx +41 -0
  17. package/playground/dialog/index.tsx +92 -0
  18. package/playground/dialog-alert/index.tsx +47 -0
  19. package/playground/drawer/index.tsx +55 -0
  20. package/playground/index.css +33 -0
  21. package/playground/index.scss +270 -0
  22. package/playground/input/index.tsx +112 -0
  23. package/playground/number-inputs/index.tsx +50 -0
  24. package/playground/popovers/index.tsx +70 -0
  25. package/playground/radio-group/index.tsx +69 -0
  26. package/playground/select/index.tsx +72 -0
  27. package/playground/select-tags/index.tsx +36 -0
  28. package/playground/styles.scss +2 -0
  29. package/playground/switch/index.tsx +44 -0
  30. package/playground/tabs/index.tsx +16 -0
  31. package/playground/test.scss +0 -0
  32. package/playground/text-area/index.tsx +17 -0
  33. package/playground/text-input/index.tsx +12 -0
  34. package/playground/toaster/index.tsx +156 -0
  35. package/playground/tooltip/index.tsx +26 -0
  36. package/src/Button/Button.scss +128 -0
  37. package/src/Button/index.tsx +72 -0
  38. package/src/ButtonGroup/ButtonGroup.scss +18 -0
  39. package/src/ButtonGroup/index.tsx +20 -0
  40. package/src/Checkbox/Checkbox.scss +115 -0
  41. package/src/Checkbox/index.tsx +46 -0
  42. package/src/Countdown/index.tsx +54 -0
  43. package/src/DateInput/DateInput.scss +11 -0
  44. package/src/DateInput/index.tsx +96 -0
  45. package/src/DatePicker/Calendar.scss +125 -0
  46. package/src/DatePicker/Calendar.tsx +157 -0
  47. package/src/DatePicker/CalendarHeader.tsx +139 -0
  48. package/src/DatePicker/DatePicker.scss +0 -0
  49. package/src/DatePicker/index.tsx +177 -0
  50. package/src/Dialog/Dialog.scss +25 -0
  51. package/src/Dialog/Popup.scss +55 -0
  52. package/src/Dialog/index.tsx +31 -0
  53. package/src/DialogAlert/Alert.scss +52 -0
  54. package/src/DialogAlert/Alert.tsx +78 -0
  55. package/src/DialogAlert/Viewport.tsx +52 -0
  56. package/src/DialogAlert/index.tsx +37 -0
  57. package/src/Drawer/Drawer.scss +112 -0
  58. package/src/Drawer/index.tsx +46 -0
  59. package/src/File/index.tsx +60 -0
  60. package/src/Form/Form.scss +70 -0
  61. package/src/Form/Input.scss +24 -0
  62. package/src/Form/index.tsx +131 -0
  63. package/src/Icon/icon.scss +18 -0
  64. package/src/Icon/index.tsx +43 -0
  65. package/src/LoadButton/index.tsx +17 -0
  66. package/src/NumberInput/index.tsx +74 -0
  67. package/src/OptionItem/Option.scss +89 -0
  68. package/src/OptionItem/OptionItem.tsx +49 -0
  69. package/src/OptionItem/OptionsList.tsx +26 -0
  70. package/src/Popover/Popover.scss +80 -0
  71. package/src/Popover/index.tsx +117 -0
  72. package/src/Radio/Radio.scss +148 -0
  73. package/src/Radio/index.tsx +68 -0
  74. package/src/Scrollable/ImitateScroll.tsx +141 -0
  75. package/src/Scrollable/Scrollable.scss +50 -0
  76. package/src/Scrollable/index.tsx +141 -0
  77. package/src/Select/Select.scss +80 -0
  78. package/src/Select/SelectInput.tsx +131 -0
  79. package/src/Select/index.tsx +134 -0
  80. package/src/SelectTags/SelectTags.scss +66 -0
  81. package/src/SelectTags/index.tsx +192 -0
  82. package/src/Spinner/Spinner.scss +14 -0
  83. package/src/Spinner/index.tsx +19 -0
  84. package/src/Stepper/StepperInput.scss +35 -0
  85. package/src/Stepper/index.tsx +76 -0
  86. package/src/Switch/Switch.scss +102 -0
  87. package/src/Switch/index.tsx +49 -0
  88. package/src/Tabs/Tabs.scss +58 -0
  89. package/src/Tabs/index.tsx +89 -0
  90. package/src/TextArea/TextArea.scss +34 -0
  91. package/src/TextArea/index.tsx +51 -0
  92. package/src/Toaster/RemoveListener.tsx +11 -0
  93. package/src/Toaster/Toast.tsx +69 -0
  94. package/src/Toaster/Toaster.scss +151 -0
  95. package/src/Toaster/Viewport.tsx +117 -0
  96. package/src/Toaster/index.tsx +52 -0
  97. package/src/Tooltip/Tooltip.scss +28 -0
  98. package/src/Tooltip/index.tsx +33 -0
  99. package/src/__hooks/use-frooze-closing.ts +51 -0
  100. package/src/__hooks/use-loading.ts +34 -0
  101. package/src/__hooks/use-local-storage.ts +19 -0
  102. package/src/__hooks/use-popover-position.ts +24 -0
  103. package/src/__hooks/use-previos.ts +25 -0
  104. package/src/__hooks/use-resize.ts +41 -0
  105. package/src/__hooks/use-scrollbox.ts +45 -0
  106. package/src/__hooks/use-stepper-input.ts +82 -0
  107. package/src/__hooks/use-update.ts +19 -0
  108. package/src/__hooks/useCalendar.ts +104 -0
  109. package/src/__hooks/useCalendarOptions-copy.ts +87 -0
  110. package/src/__hooks/useCalendarOptions.ts +68 -0
  111. package/src/__libs/calendar.ts +175 -0
  112. package/src/__utils/utils.ts +137 -0
  113. package/src/css.scss +120 -0
  114. package/src/index.scss +22 -0
  115. package/src/index.ts +36 -0
  116. package/src/mixins.scss +99 -0
  117. package/src/theme.scss +103 -0
  118. package/src/types.ts +14 -0
  119. package/tailwind.config.js +91 -0
  120. package/themes/classic/animations.scss +179 -0
  121. package/themes/classic/classic.scss +493 -0
  122. package/tsconfig.json +27 -0
  123. package/vite.build.ts +35 -0
  124. package/vite.config.ts +33 -0
@@ -0,0 +1,26 @@
1
+ import { Button } from '@/Button'
2
+ import { ButtonGroup } from '@/ButtonGroup'
3
+ import { Tooltip } from '@/Tooltip'
4
+
5
+ export const TooltipExample = () => {
6
+ return (
7
+ <div className="col-group">
8
+ <div className="row-group">
9
+ <Tooltip content={<div>Content Tooltip</div>}>
10
+ <Button>Hover</Button>
11
+ </Tooltip>
12
+ <ButtonGroup>
13
+ <Tooltip content={<div>Each</div>}>
14
+ <Button>Group</Button>
15
+ </Tooltip>
16
+ <Tooltip content={<div>has</div>}>
17
+ <Button>Of</Button>
18
+ </Tooltip>
19
+ <Tooltip content={<div>a tooltip</div>}>
20
+ <Button>Buttons</Button>
21
+ </Tooltip>
22
+ </ButtonGroup>
23
+ </div>
24
+ </div>
25
+ )
26
+ }
@@ -0,0 +1,128 @@
1
+ @use '../mixins.scss';
2
+
3
+ // scheme: bth-[appearance]-[mode]-[property]--[state]
4
+ //
5
+ // appearance: primary, neutral, positive, negative
6
+ // mode: default, outline, minimal
7
+ // state: enabled, hovered, pressed, disabled, loading
8
+ // property: text, background, shadow, border
9
+
10
+ @mixin use-mode($appearance, $mode) {
11
+ @include mixins.use-styles(button, $appearance, $mode, enabled);
12
+
13
+ &:hover {
14
+ @include mixins.use-styles(button, $appearance, $mode, hovered);
15
+ }
16
+
17
+ &[data-active],
18
+ &:active {
19
+ @include mixins.use-styles(button, $appearance, $mode, pressed);
20
+ }
21
+
22
+ &[data-loading] {
23
+ @include mixins.use-styles(button, $appearance, $mode, loading);
24
+ }
25
+
26
+ &[disabled] {
27
+ cursor: not-allowed;
28
+ @include mixins.use-styles(button, $appearance, $mode, disabled);
29
+ }
30
+ }
31
+
32
+ @mixin use-appearance($appearance) {
33
+ &[data-appearance='#{$appearance}'] {
34
+ &[data-mode='default'] {
35
+ @include use-mode($appearance, default);
36
+ }
37
+
38
+ &[data-mode='outline'] {
39
+ @include use-mode($appearance, outline);
40
+ }
41
+
42
+ &[data-mode='minimal'] {
43
+ @include use-mode($appearance, minimal);
44
+ }
45
+ }
46
+ }
47
+
48
+ .button {
49
+ overflow: visible;
50
+ box-sizing: border-box;
51
+ -moz-user-focus: ignore;
52
+ -webkit-user-select: none;
53
+ -moz-user-select: none;
54
+ -ms-user-select: none;
55
+ user-select: none;
56
+ text-decoration: none;
57
+ outline: none;
58
+ -webkit-tap-highlight-color: transparent;
59
+ -ms-touch-action: manipulation;
60
+ touch-action: manipulation;
61
+ cursor: pointer;
62
+ display: flex;
63
+ align-items: center;
64
+
65
+ @include mixins.use-styles(button);
66
+ @include mixins.items-spacing(8px);
67
+
68
+ // fill
69
+
70
+ &[data-fill] {
71
+ width: 100%;
72
+ }
73
+
74
+ // align
75
+
76
+ &[data-align='center'] {
77
+ justify-content: center;
78
+
79
+ & > .button-text {
80
+ text-align: center;
81
+ }
82
+ }
83
+
84
+ &[data-align='left'] {
85
+ justify-content: left;
86
+
87
+ & > .button-text {
88
+ flex: 1 1 auto;
89
+ text-align: left;
90
+ }
91
+ }
92
+
93
+ &[data-align='right'] {
94
+ justify-content: right;
95
+
96
+ & > .button-text {
97
+ flex: 1 1 auto;
98
+ text-align: right;
99
+ }
100
+ }
101
+
102
+ // sizes
103
+
104
+ &[data-size='sm'] {
105
+ @include mixins.use-styles(button, size, sm);
106
+ }
107
+
108
+ &[data-size='md'] {
109
+ @include mixins.use-styles(button, size, md);
110
+ }
111
+
112
+ &[data-size='lg'] {
113
+ @include mixins.use-styles(button, size, lg);
114
+ }
115
+
116
+ // text
117
+
118
+ &-text {
119
+ @include mixins.truncate-text();
120
+ }
121
+
122
+ // appearance
123
+
124
+ @include use-appearance(primary);
125
+ @include use-appearance(neutral);
126
+ @include use-appearance(negative);
127
+ @include use-appearance(positive);
128
+ }
@@ -0,0 +1,72 @@
1
+ import classNames from 'classnames'
2
+ import { Spinner } from '../Spinner'
3
+ import { forwardRef } from 'react'
4
+ import { attr } from '@companix/utils-browser'
5
+
6
+ export type Appearance = 'primary' | 'neutral' | 'positive' | 'negative'
7
+ export type Mode = 'default' | 'outline' | 'minimal'
8
+ export type Size = 'sm' | 'md' | 'lg'
9
+
10
+ export interface InternButtonProps {
11
+ icon?: React.ReactNode
12
+ iconRight?: React.ReactNode
13
+ appearance?: Appearance
14
+ mode?: Mode
15
+ size?: Size
16
+ fill?: boolean
17
+ align?: 'left' | 'center' | 'right'
18
+ loading?: boolean
19
+ active?: boolean
20
+ text?: React.ReactNode
21
+ children?: React.ReactNode
22
+ className?: string
23
+ }
24
+
25
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, InternButtonProps {}
26
+
27
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
28
+ (
29
+ {
30
+ children,
31
+ fill,
32
+ text,
33
+ active,
34
+ mode = 'default',
35
+ appearance = 'neutral',
36
+ size = 'md',
37
+ align,
38
+ icon,
39
+ loading,
40
+ className,
41
+ iconRight,
42
+ ...buttonProps
43
+ },
44
+ ref
45
+ ) => {
46
+ return (
47
+ <button
48
+ ref={ref}
49
+ className={classNames('button', className)}
50
+ data-size={size}
51
+ data-loading={attr(loading)}
52
+ data-align={loading ? 'center' : align ?? (icon && iconRight ? 'left' : 'center')}
53
+ data-appearance={appearance}
54
+ data-mode={mode}
55
+ data-fill={attr(fill)}
56
+ data-active={attr(active)}
57
+ {...buttonProps}
58
+ onClick={loading ?? buttonProps.disabled ? undefined : buttonProps.onClick}
59
+ >
60
+ {loading ? (
61
+ <Spinner size={14} width={2} />
62
+ ) : (
63
+ <>
64
+ {icon}
65
+ {(children ?? text) && <span className="button-text">{text ?? children}</span>}
66
+ {iconRight}
67
+ </>
68
+ )}
69
+ </button>
70
+ )
71
+ }
72
+ )
@@ -0,0 +1,18 @@
1
+ .button-group {
2
+ display: flex;
3
+
4
+ &[data-fill] {
5
+ width: 100%;
6
+ }
7
+
8
+ & > .button:not(:first-child) {
9
+ border-bottom-left-radius: 0;
10
+ border-top-left-radius: 0;
11
+ }
12
+
13
+ & > .button:not(:last-child) {
14
+ border-bottom-right-radius: 0;
15
+ border-top-right-radius: 0;
16
+ margin-right: -1px;
17
+ }
18
+ }
@@ -0,0 +1,20 @@
1
+ import './ButtonGroup.scss'
2
+ import { forwardRef } from 'react'
3
+ import cn from 'classnames'
4
+ import { attr } from '@companix/utils-browser'
5
+
6
+ interface ButtonGroupProps {
7
+ children: React.ReactNode
8
+ className?: string
9
+ fill?: boolean
10
+ }
11
+
12
+ export const ButtonGroup = forwardRef<HTMLDivElement, ButtonGroupProps>(
13
+ ({ children, className, fill }, ref) => {
14
+ return (
15
+ <div ref={ref} className={cn('button-group', className)} data-fill={attr(fill)}>
16
+ {children}
17
+ </div>
18
+ )
19
+ }
20
+ )
@@ -0,0 +1,115 @@
1
+ @use '../mixins.scss';
2
+
3
+ .checkbox {
4
+ display: inline-table;
5
+ user-select: none;
6
+ touch-action: manipulation;
7
+ max-width: max-content;
8
+
9
+ @include mixins.use-styles(checkbox);
10
+
11
+ &:not([data-disabled]):not([data-required]):hover {
12
+ .checkbox-box[data-state='unchecked'] {
13
+ @include mixins.use-styles(checkbox, box, hover);
14
+ }
15
+ }
16
+
17
+ &:not([data-disabled]):not([data-required]):active {
18
+ .checkbox-box[data-state='unchecked'] {
19
+ @include mixins.use-styles(checkbox, box, active);
20
+ }
21
+ }
22
+
23
+ &:not([data-disabled]) {
24
+ .checkbox-box[data-state='checked'] {
25
+ @include mixins.use-styles(checkbox, box, checked);
26
+ }
27
+ }
28
+
29
+ &[data-disabled] {
30
+ @include mixins.use-styles(checkbox, disabled);
31
+ }
32
+
33
+ &[data-required] {
34
+ @include mixins.use-styles(checkbox, required);
35
+
36
+ .checkbox-box::before {
37
+ content: '';
38
+ position: absolute;
39
+ width: 100%;
40
+ height: 100%;
41
+ left: 0;
42
+
43
+ @include mixins.use-styles(checkbox, required, box);
44
+
45
+ border-radius: mixins.get-var-name(checkbox, box, border-radius);
46
+ }
47
+ }
48
+
49
+ &[data-size='sm'] {
50
+ @include mixins.use-styles(checkbox, size, sm);
51
+
52
+ .checkbox-box {
53
+ @include mixins.use-size(checkbox, size, sm, box);
54
+ }
55
+ }
56
+
57
+ &[data-size='md'] {
58
+ @include mixins.use-styles(checkbox, size, md);
59
+
60
+ .checkbox-box {
61
+ @include mixins.use-size(checkbox, size, md, box);
62
+ }
63
+ }
64
+
65
+ &-box {
66
+ cursor: pointer;
67
+ outline: none;
68
+ transition: background-color 0.1s linear;
69
+ display: inline-block;
70
+ position: relative;
71
+ z-index: 0;
72
+
73
+ @include mixins.use-styles(checkbox, box);
74
+
75
+ &[data-disabled] {
76
+ cursor: default;
77
+ }
78
+
79
+ &:after {
80
+ visibility: hidden;
81
+ content: '\00A0';
82
+ }
83
+ }
84
+
85
+ &-label {
86
+ cursor: pointer;
87
+ display: table-cell;
88
+ word-break: break-word;
89
+
90
+ &[data-disabled] {
91
+ cursor: default;
92
+ }
93
+
94
+ @include mixins.use-styles(checkbox, label);
95
+ }
96
+
97
+ &-icon {
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ z-index: 3;
102
+ position: absolute;
103
+ width: 100%;
104
+ height: 100%;
105
+ top: 0;
106
+
107
+ &[data-state='checked'] {
108
+ @include mixins.use-styles(checkbox, icon, in);
109
+ }
110
+
111
+ &[data-state='unchecked'] {
112
+ @include mixins.use-styles(checkbox, icon, out);
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,46 @@
1
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox'
2
+ import { Icon } from '../Icon'
3
+ import { faCheck } from '@fortawesome/free-solid-svg-icons'
4
+ import { useId } from 'react'
5
+ import { attr } from '@companix/utils-browser'
6
+
7
+ interface CheckboxProps {
8
+ checked: boolean
9
+ onCheckedChange: (checked: boolean) => void
10
+ size?: 'sm' | 'md'
11
+ label?: React.ReactNode
12
+ disabled?: boolean
13
+ required?: boolean
14
+ }
15
+
16
+ const Checkbox = ({ checked, required, disabled, onCheckedChange, size, label }: CheckboxProps) => {
17
+ const id = useId()
18
+
19
+ return (
20
+ <div
21
+ className="checkbox"
22
+ data-size={size ?? 'md'}
23
+ data-required={attr(required && !checked)}
24
+ data-disabled={attr(disabled)}
25
+ >
26
+ <CheckboxPrimitive.Root
27
+ className="checkbox-box"
28
+ checked={checked}
29
+ onCheckedChange={onCheckedChange}
30
+ disabled={disabled}
31
+ id={id}
32
+ >
33
+ <CheckboxPrimitive.Indicator className="checkbox-icon">
34
+ <Icon icon={faCheck} size="xxxs" />
35
+ </CheckboxPrimitive.Indicator>
36
+ </CheckboxPrimitive.Root>
37
+ {label && (
38
+ <label className="checkbox-label" htmlFor={id} data-disabled={attr(disabled)}>
39
+ {label}
40
+ </label>
41
+ )}
42
+ </div>
43
+ )
44
+ }
45
+
46
+ export { Checkbox }
@@ -0,0 +1,54 @@
1
+ import { getNextCandleTime, getTimes, sleep } from '@companix/utils-js'
2
+ import { useState, useEffect, useRef } from 'react'
3
+
4
+ const formatTime = (num: number) => String(num).padStart(2, '0')
5
+
6
+ interface CountDownProps {
7
+ expiration: number
8
+ separator?: string
9
+ onExpired?: VoidFunction
10
+ }
11
+
12
+ export const Countdown = ({ expiration, separator = ':', onExpired }: CountDownProps) => {
13
+ const ref = useRef<null | NodeJS.Timeout>(null)
14
+ const [, rerender] = useState([])
15
+
16
+ useEffect(() => {
17
+ const currentTime = Date.now()
18
+ const closestNextSecondTimestamp = getNextCandleTime(currentTime, '1s')
19
+ const waitToNextSecond = closestNextSecondTimestamp - currentTime
20
+
21
+ if (ref.current) {
22
+ clearInterval(ref.current)
23
+ }
24
+
25
+ sleep(waitToNextSecond).then(() => {
26
+ rerender([])
27
+
28
+ ref.current = setInterval(() => {
29
+ rerender([])
30
+ }, 1000)
31
+ })
32
+
33
+ return () => {
34
+ if (ref.current) {
35
+ clearInterval(ref.current)
36
+ }
37
+ }
38
+ }, [expiration])
39
+
40
+ const time = expiration - Date.now()
41
+ const { hours, minutes, seconds } = getTimes(time)
42
+
43
+ useEffect(() => {
44
+ if (time <= 0) {
45
+ onExpired?.()
46
+
47
+ if (ref.current) {
48
+ clearInterval(ref.current)
49
+ }
50
+ }
51
+ }, [time <= 0])
52
+
53
+ return <>{[formatTime(hours), formatTime(minutes), formatTime(seconds)].join(separator)}</>
54
+ }
@@ -0,0 +1,11 @@
1
+ .data-input {
2
+ display: flex;
3
+ gap: 8px;
4
+ width: 100%;
5
+
6
+ .form {
7
+ input {
8
+ width: 100%;
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,96 @@
1
+ import { useMemo, useEffect } from 'react'
2
+ import { DateFormat, Select } from '..'
3
+ import { createDateValidation, getMonthMaxDay } from '../__utils/utils'
4
+ import { defaultMax, defaultMin, useCalendarOptions } from '../__hooks/useCalendarOptions'
5
+
6
+ export interface DatePickerProps {
7
+ min?: DateFormat
8
+ max?: DateFormat
9
+ noDaySelect?: boolean
10
+ noYearSelect?: boolean
11
+ disabled?: boolean
12
+ required?: boolean
13
+ size?: 'sm' | 'md' | 'lg'
14
+ value: DateFormat
15
+ onChange: (e: DateFormat) => void
16
+ }
17
+
18
+ export const DateInput = ({
19
+ min = defaultMin,
20
+ max = defaultMax,
21
+ disabled,
22
+ value,
23
+ noDaySelect,
24
+ noYearSelect,
25
+ onChange,
26
+ required,
27
+ size
28
+ }: DatePickerProps) => {
29
+ const validateDate = useMemo(() => {
30
+ return createDateValidation({ min, max })
31
+ }, [min, max])
32
+
33
+ useEffect(() => {
34
+ const changed = validateDate(value)
35
+
36
+ if (changed) {
37
+ onChange(changed)
38
+ }
39
+ }, [validateDate, value])
40
+
41
+ const { years, months, days } = useCalendarOptions({ min, max, now: value })
42
+
43
+ const handleDateChange = (source: 'year' | 'month' | 'day', val: number) => {
44
+ const nextValue = { ...value }
45
+
46
+ nextValue[source] = val
47
+
48
+ const max = getMonthMaxDay(nextValue.month, nextValue.year)
49
+ nextValue.day = nextValue.day > max ? max : nextValue.day
50
+
51
+ onChange(nextValue)
52
+ }
53
+
54
+ return (
55
+ <div className="data-input">
56
+ {!noYearSelect && years.length > 0 && (
57
+ <Select
58
+ placeholder="Год"
59
+ options={years}
60
+ onChange={(e) => handleDateChange('year', e || 0)}
61
+ value={value.year}
62
+ required={required}
63
+ disabled={disabled}
64
+ size={size}
65
+ minimalOptions
66
+ matchTarget="min-width"
67
+ />
68
+ )}
69
+ <Select
70
+ placeholder="Месяц"
71
+ className="w-full"
72
+ options={months}
73
+ onChange={(e) => handleDateChange('month', e || 0)}
74
+ value={value.month}
75
+ disabled={disabled}
76
+ required={required}
77
+ size={size}
78
+ minimalOptions
79
+ matchTarget="min-width"
80
+ />
81
+ {!noDaySelect && (
82
+ <Select
83
+ placeholder="День"
84
+ options={days}
85
+ disabled={disabled || days.length === 0}
86
+ onChange={(e) => handleDateChange('day', e || 0)}
87
+ value={value.day}
88
+ required={required}
89
+ size={size}
90
+ minimalOptions
91
+ matchTarget="min-width"
92
+ />
93
+ )}
94
+ </div>
95
+ )
96
+ }