@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.
- package/.eslintrc +54 -0
- package/declaration.d.ts +4 -0
- package/index.html +12 -0
- package/package.json +66 -0
- package/playground/App.tsx +166 -0
- package/playground/Example.tsx +14 -0
- package/playground/Test.tsx +44 -0
- package/playground/animation-test-1/index.scss +20 -0
- package/playground/animation-test-1/index.tsx +17 -0
- package/playground/animation-test-2/index.scss +62 -0
- package/playground/animation-test-2/index.tsx +32 -0
- package/playground/bootstrap.tsx +19 -0
- package/playground/buttons/index.tsx +132 -0
- package/playground/checkbox/index.tsx +64 -0
- package/playground/date-input/index.tsx +45 -0
- package/playground/date-picker/index.tsx +41 -0
- package/playground/dialog/index.tsx +92 -0
- package/playground/dialog-alert/index.tsx +47 -0
- package/playground/drawer/index.tsx +55 -0
- package/playground/index.css +33 -0
- package/playground/index.scss +270 -0
- package/playground/input/index.tsx +112 -0
- package/playground/number-inputs/index.tsx +50 -0
- package/playground/popovers/index.tsx +70 -0
- package/playground/radio-group/index.tsx +69 -0
- package/playground/select/index.tsx +72 -0
- package/playground/select-tags/index.tsx +36 -0
- package/playground/styles.scss +2 -0
- package/playground/switch/index.tsx +44 -0
- package/playground/tabs/index.tsx +16 -0
- package/playground/test.scss +0 -0
- package/playground/text-area/index.tsx +17 -0
- package/playground/text-input/index.tsx +12 -0
- package/playground/toaster/index.tsx +156 -0
- package/playground/tooltip/index.tsx +26 -0
- package/src/Button/Button.scss +128 -0
- package/src/Button/index.tsx +72 -0
- package/src/ButtonGroup/ButtonGroup.scss +18 -0
- package/src/ButtonGroup/index.tsx +20 -0
- package/src/Checkbox/Checkbox.scss +115 -0
- package/src/Checkbox/index.tsx +46 -0
- package/src/Countdown/index.tsx +54 -0
- package/src/DateInput/DateInput.scss +11 -0
- package/src/DateInput/index.tsx +96 -0
- package/src/DatePicker/Calendar.scss +125 -0
- package/src/DatePicker/Calendar.tsx +157 -0
- package/src/DatePicker/CalendarHeader.tsx +139 -0
- package/src/DatePicker/DatePicker.scss +0 -0
- package/src/DatePicker/index.tsx +177 -0
- package/src/Dialog/Dialog.scss +25 -0
- package/src/Dialog/Popup.scss +55 -0
- package/src/Dialog/index.tsx +31 -0
- package/src/DialogAlert/Alert.scss +52 -0
- package/src/DialogAlert/Alert.tsx +78 -0
- package/src/DialogAlert/Viewport.tsx +52 -0
- package/src/DialogAlert/index.tsx +37 -0
- package/src/Drawer/Drawer.scss +112 -0
- package/src/Drawer/index.tsx +46 -0
- package/src/File/index.tsx +60 -0
- package/src/Form/Form.scss +70 -0
- package/src/Form/Input.scss +24 -0
- package/src/Form/index.tsx +131 -0
- package/src/Icon/icon.scss +18 -0
- package/src/Icon/index.tsx +43 -0
- package/src/LoadButton/index.tsx +17 -0
- package/src/NumberInput/index.tsx +74 -0
- package/src/OptionItem/Option.scss +89 -0
- package/src/OptionItem/OptionItem.tsx +49 -0
- package/src/OptionItem/OptionsList.tsx +26 -0
- package/src/Popover/Popover.scss +80 -0
- package/src/Popover/index.tsx +117 -0
- package/src/Radio/Radio.scss +148 -0
- package/src/Radio/index.tsx +68 -0
- package/src/Scrollable/ImitateScroll.tsx +141 -0
- package/src/Scrollable/Scrollable.scss +50 -0
- package/src/Scrollable/index.tsx +141 -0
- package/src/Select/Select.scss +80 -0
- package/src/Select/SelectInput.tsx +131 -0
- package/src/Select/index.tsx +134 -0
- package/src/SelectTags/SelectTags.scss +66 -0
- package/src/SelectTags/index.tsx +192 -0
- package/src/Spinner/Spinner.scss +14 -0
- package/src/Spinner/index.tsx +19 -0
- package/src/Stepper/StepperInput.scss +35 -0
- package/src/Stepper/index.tsx +76 -0
- package/src/Switch/Switch.scss +102 -0
- package/src/Switch/index.tsx +49 -0
- package/src/Tabs/Tabs.scss +58 -0
- package/src/Tabs/index.tsx +89 -0
- package/src/TextArea/TextArea.scss +34 -0
- package/src/TextArea/index.tsx +51 -0
- package/src/Toaster/RemoveListener.tsx +11 -0
- package/src/Toaster/Toast.tsx +69 -0
- package/src/Toaster/Toaster.scss +151 -0
- package/src/Toaster/Viewport.tsx +117 -0
- package/src/Toaster/index.tsx +52 -0
- package/src/Tooltip/Tooltip.scss +28 -0
- package/src/Tooltip/index.tsx +33 -0
- package/src/__hooks/use-frooze-closing.ts +51 -0
- package/src/__hooks/use-loading.ts +34 -0
- package/src/__hooks/use-local-storage.ts +19 -0
- package/src/__hooks/use-popover-position.ts +24 -0
- package/src/__hooks/use-previos.ts +25 -0
- package/src/__hooks/use-resize.ts +41 -0
- package/src/__hooks/use-scrollbox.ts +45 -0
- package/src/__hooks/use-stepper-input.ts +82 -0
- package/src/__hooks/use-update.ts +19 -0
- package/src/__hooks/useCalendar.ts +104 -0
- package/src/__hooks/useCalendarOptions-copy.ts +87 -0
- package/src/__hooks/useCalendarOptions.ts +68 -0
- package/src/__libs/calendar.ts +175 -0
- package/src/__utils/utils.ts +137 -0
- package/src/css.scss +120 -0
- package/src/index.scss +22 -0
- package/src/index.ts +36 -0
- package/src/mixins.scss +99 -0
- package/src/theme.scss +103 -0
- package/src/types.ts +14 -0
- package/tailwind.config.js +91 -0
- package/themes/classic/animations.scss +179 -0
- package/themes/classic/classic.scss +493 -0
- package/tsconfig.json +27 -0
- package/vite.build.ts +35 -0
- package/vite.config.ts +33 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { CalendarProps } from '../DatePicker/Calendar'
|
|
2
|
+
import { useCallback, useMemo } from 'react'
|
|
3
|
+
|
|
4
|
+
export function isSameDate(d1: Date, d2: Date): boolean {
|
|
5
|
+
return (
|
|
6
|
+
d1.getDate() === d2.getDate() &&
|
|
7
|
+
d1.getMonth() === d2.getMonth() &&
|
|
8
|
+
d1.getFullYear() === d2.getFullYear()
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const MONDAY = 1
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Возвращает дату начала недели
|
|
16
|
+
*/
|
|
17
|
+
export function startOfWeek(date: Date, { weekStartsOn = MONDAY }): Date {
|
|
18
|
+
const result = new Date(date)
|
|
19
|
+
const day = result.getDay()
|
|
20
|
+
const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn
|
|
21
|
+
|
|
22
|
+
result.setDate(result.getDate() - diff)
|
|
23
|
+
result.setHours(0, 0, 0, 0)
|
|
24
|
+
return result
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Возвращает дату конца недели
|
|
29
|
+
*/
|
|
30
|
+
export function endOfWeek(date: Date, { weekStartsOn = MONDAY }): Date {
|
|
31
|
+
const result = new Date(date)
|
|
32
|
+
const day = result.getDay()
|
|
33
|
+
const diff = (day < weekStartsOn ? -7 : 0) + 6 - (day - weekStartsOn)
|
|
34
|
+
|
|
35
|
+
result.setDate(result.getDate() + diff)
|
|
36
|
+
result.setHours(23, 59, 59, 999)
|
|
37
|
+
return result
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Возвращает дату начала дня
|
|
42
|
+
*/
|
|
43
|
+
export function startOfDay(date: Date): Date {
|
|
44
|
+
const result = new Date(date)
|
|
45
|
+
result.setHours(0, 0, 0, 0)
|
|
46
|
+
return result
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Возвращает дату конца дня
|
|
51
|
+
*/
|
|
52
|
+
export function endOfDay(date: Date): Date {
|
|
53
|
+
const result = new Date(date)
|
|
54
|
+
result.setHours(23, 59, 59, 999)
|
|
55
|
+
return result
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Позволяет определить удовлетворяет ли исходная дата заданным ограничения `min` и/или `max`
|
|
60
|
+
*/
|
|
61
|
+
export function isDayMinMaxRestricted(
|
|
62
|
+
day: Date,
|
|
63
|
+
options: { min?: Date; max?: Date; withTime?: boolean } = {}
|
|
64
|
+
): boolean {
|
|
65
|
+
const { min, max, withTime = false } = options
|
|
66
|
+
|
|
67
|
+
if (!withTime && ((min && isSameDate(day, min)) || (max && isSameDate(day, max)))) {
|
|
68
|
+
return false
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return Boolean((min && day < min) || (max && day > max))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function addMonths(date: Date, amount: number): Date {
|
|
75
|
+
const result = new Date(date)
|
|
76
|
+
|
|
77
|
+
if (!amount) {
|
|
78
|
+
return result
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const dayOfMonth = result.getDate()
|
|
82
|
+
|
|
83
|
+
const endOfDesiredMonth = new Date(date)
|
|
84
|
+
endOfDesiredMonth.setMonth(result.getMonth() + amount + 1, 0) // Конец месяца
|
|
85
|
+
const daysInMonth = endOfDesiredMonth.getDate()
|
|
86
|
+
if (dayOfMonth >= daysInMonth) {
|
|
87
|
+
// Если мы уже находимся в конце месяца, то это нужная дата
|
|
88
|
+
return endOfDesiredMonth
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
result.setFullYear(endOfDesiredMonth.getFullYear(), endOfDesiredMonth.getMonth(), dayOfMonth)
|
|
92
|
+
return result
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function subMonths(date: Date, amount: number): Date {
|
|
96
|
+
return addMonths(date, -amount)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// set
|
|
100
|
+
|
|
101
|
+
function getDaysInMonth(date: Date): number {
|
|
102
|
+
const result = new Date(date)
|
|
103
|
+
const lastDayOfMonth = new Date(result)
|
|
104
|
+
lastDayOfMonth.setFullYear(result.getFullYear(), result.getMonth() + 1, 0)
|
|
105
|
+
lastDayOfMonth.setHours(0, 0, 0, 0)
|
|
106
|
+
return lastDayOfMonth.getDate()
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function setYear(date: Date, year: number): Date {
|
|
110
|
+
const result = new Date(date)
|
|
111
|
+
result.setFullYear(year)
|
|
112
|
+
return result
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function setMonth(date: Date, month: number): Date {
|
|
116
|
+
const result = new Date(date)
|
|
117
|
+
const year = result.getFullYear()
|
|
118
|
+
const day = result.getDate()
|
|
119
|
+
|
|
120
|
+
const midMonth = new Date(date)
|
|
121
|
+
midMonth.setFullYear(year, month, 15)
|
|
122
|
+
midMonth.setHours(0, 0, 0, 0)
|
|
123
|
+
const daysInMonth = getDaysInMonth(midMonth)
|
|
124
|
+
|
|
125
|
+
result.setMonth(month, Math.min(day, daysInMonth))
|
|
126
|
+
return result
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// custom
|
|
130
|
+
|
|
131
|
+
interface DisableOptions
|
|
132
|
+
extends Pick<
|
|
133
|
+
CalendarProps,
|
|
134
|
+
'disableFuture' | 'disablePast' | 'maxDateTime' | 'minDateTime' | 'shouldDisableDate'
|
|
135
|
+
> {}
|
|
136
|
+
|
|
137
|
+
export const createDayDisableChecker = (options: DisableOptions) => {
|
|
138
|
+
const { disableFuture, disablePast, maxDateTime, minDateTime, shouldDisableDate } = options
|
|
139
|
+
|
|
140
|
+
return (day: Date, withTime?: boolean) => {
|
|
141
|
+
const now = new Date()
|
|
142
|
+
|
|
143
|
+
if (shouldDisableDate) {
|
|
144
|
+
return shouldDisableDate(day)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (disableFuture) {
|
|
148
|
+
return startOfDay(day) > now
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (disablePast) {
|
|
152
|
+
return endOfDay(day) < now
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (minDateTime || maxDateTime) {
|
|
156
|
+
return isDayMinMaxRestricted(day, { min: minDateTime, max: maxDateTime, withTime })
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return false
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export const useDayDisableCheker = (options: DisableOptions) => {
|
|
164
|
+
const isDayDisabled = useMemo(() => {
|
|
165
|
+
return createDayDisableChecker(options)
|
|
166
|
+
}, [
|
|
167
|
+
options.disableFuture,
|
|
168
|
+
options.disablePast,
|
|
169
|
+
options.shouldDisableDate,
|
|
170
|
+
options.minDateTime,
|
|
171
|
+
options.maxDateTime
|
|
172
|
+
])
|
|
173
|
+
|
|
174
|
+
return useCallback(isDayDisabled, [isDayDisabled])
|
|
175
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { clamp } from '@companix/utils-browser'
|
|
2
|
+
import { DateFormat, Option } from '..'
|
|
3
|
+
|
|
4
|
+
export const getMonthMaxDay = (month: number, year: number) => {
|
|
5
|
+
return new Date(year, month, 0).getDate()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getFirstDay = (month: number, year: number) => {
|
|
9
|
+
return new Date(year, month - 1, 1).getDay()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 0 is Monday, 6 - is Sunday
|
|
13
|
+
export const getDayIndex = (day: number) => {
|
|
14
|
+
return day === 0 ? 6 : day - 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const createVoids = (length: number) => {
|
|
18
|
+
return new Array(length).fill(0)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const dateToFormat = (date: Date): DateFormat => {
|
|
22
|
+
return {
|
|
23
|
+
day: date.getDate(),
|
|
24
|
+
month: date.getMonth() + 1,
|
|
25
|
+
year: date.getFullYear()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const createDateValidation = ({ min, max }: { min: DateFormat; max: DateFormat }) => {
|
|
30
|
+
return (value: DateFormat) => {
|
|
31
|
+
if (min.year === value.year) {
|
|
32
|
+
if (value.month !== 0 && value.month < min.month) {
|
|
33
|
+
value.month = 0
|
|
34
|
+
value.day = 0
|
|
35
|
+
|
|
36
|
+
return value
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (value.month === min.month && value.day < min.day && value.day !== 0) {
|
|
40
|
+
value.day = 0
|
|
41
|
+
|
|
42
|
+
return value
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (max.year === value.year) {
|
|
47
|
+
if (value.month !== 0 && value.month > max.month) {
|
|
48
|
+
value.month = 0
|
|
49
|
+
value.day = 0
|
|
50
|
+
|
|
51
|
+
return value
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (value.month === max.month && value.day > max.day && value.day !== 0) {
|
|
55
|
+
value.day = 0
|
|
56
|
+
|
|
57
|
+
return value
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const createRangeValidation = ({ min, max }: { min?: DateFormat; max?: DateFormat }) => {
|
|
64
|
+
const minTime = min ? new Date(formatToDate(min)).getTime() : 0
|
|
65
|
+
const maxTime = max ? new Date(formatToDate(max)).getTime() : Infinity
|
|
66
|
+
|
|
67
|
+
const getCurrentTime = (value: DateFormat) => {
|
|
68
|
+
return new Date(formatToDate(value)).getTime()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
isDateMinValid: (value: DateFormat) => {
|
|
73
|
+
return getCurrentTime(value) > minTime
|
|
74
|
+
},
|
|
75
|
+
isDateMaxValid: (value: DateFormat) => {
|
|
76
|
+
return getCurrentTime(value) < maxTime
|
|
77
|
+
},
|
|
78
|
+
isDateInRange: (value: DateFormat) => {
|
|
79
|
+
const current = getCurrentTime(value)
|
|
80
|
+
|
|
81
|
+
return current > minTime && current < maxTime
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const formatToDate = (format: DateFormat): Date => {
|
|
87
|
+
return new Date(format.year, format.month - 1, format.day)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const weeks = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']
|
|
91
|
+
|
|
92
|
+
export const DefaultMonths = [
|
|
93
|
+
'Январь',
|
|
94
|
+
'Февраль',
|
|
95
|
+
'Март',
|
|
96
|
+
'Апрель',
|
|
97
|
+
'Май',
|
|
98
|
+
'Июнь',
|
|
99
|
+
'Июль',
|
|
100
|
+
'Август',
|
|
101
|
+
'Сентябрь',
|
|
102
|
+
'Октябрь',
|
|
103
|
+
'Ноябрь',
|
|
104
|
+
'Декабрь'
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
export const DEFAULT_MAX_YEAR = 9999
|
|
108
|
+
export const DEFAULT_MIN_YEAR = 100
|
|
109
|
+
|
|
110
|
+
export const getYears = (currentYear: number, range: number): Option<number>[] => {
|
|
111
|
+
const years: Option<number>[] = []
|
|
112
|
+
|
|
113
|
+
const minYear = clamp(currentYear - range, DEFAULT_MIN_YEAR, DEFAULT_MAX_YEAR)
|
|
114
|
+
const maxYear = clamp(currentYear + range, DEFAULT_MIN_YEAR, DEFAULT_MAX_YEAR)
|
|
115
|
+
|
|
116
|
+
for (let i = minYear; i <= maxYear; i++) {
|
|
117
|
+
years.push({ title: String(i).padStart(4, '0'), value: i })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return years
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const getMonths = (locale?: string): Option<number>[] => {
|
|
124
|
+
const months: Option<number>[] = []
|
|
125
|
+
const formatter = new Intl.DateTimeFormat(locale, {
|
|
126
|
+
month: 'long'
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
for (let i = 0; i < 12; i++) {
|
|
130
|
+
months.push({
|
|
131
|
+
title: formatter.format(new Date(2023, i, 15)),
|
|
132
|
+
value: i
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return months
|
|
137
|
+
}
|
package/src/css.scss
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
$properties: (
|
|
2
|
+
// Layout
|
|
3
|
+
display,
|
|
4
|
+
position,
|
|
5
|
+
top,
|
|
6
|
+
right,
|
|
7
|
+
bottom,
|
|
8
|
+
left,
|
|
9
|
+
z-index,
|
|
10
|
+
float,
|
|
11
|
+
clear,
|
|
12
|
+
overflow,
|
|
13
|
+
overflow-x,
|
|
14
|
+
overflow-y,
|
|
15
|
+
visibility,
|
|
16
|
+
// Box model
|
|
17
|
+
box-sizing,
|
|
18
|
+
width,
|
|
19
|
+
min-width,
|
|
20
|
+
max-width,
|
|
21
|
+
height,
|
|
22
|
+
min-height,
|
|
23
|
+
max-height,
|
|
24
|
+
margin,
|
|
25
|
+
margin-top,
|
|
26
|
+
margin-right,
|
|
27
|
+
margin-bottom,
|
|
28
|
+
margin-left,
|
|
29
|
+
padding,
|
|
30
|
+
padding-top,
|
|
31
|
+
padding-right,
|
|
32
|
+
padding-bottom,
|
|
33
|
+
padding-left,
|
|
34
|
+
// Flexbox
|
|
35
|
+
flex,
|
|
36
|
+
flex-direction,
|
|
37
|
+
flex-wrap,
|
|
38
|
+
flex-grow,
|
|
39
|
+
flex-shrink,
|
|
40
|
+
flex-basis,
|
|
41
|
+
justify-content,
|
|
42
|
+
align-items,
|
|
43
|
+
align-content,
|
|
44
|
+
align-self,
|
|
45
|
+
gap,
|
|
46
|
+
row-gap,
|
|
47
|
+
column-gap,
|
|
48
|
+
// Grid
|
|
49
|
+
grid,
|
|
50
|
+
grid-template-columns,
|
|
51
|
+
grid-template-rows,
|
|
52
|
+
grid-template-areas,
|
|
53
|
+
grid-column,
|
|
54
|
+
grid-row,
|
|
55
|
+
grid-area,
|
|
56
|
+
// Typography
|
|
57
|
+
color,
|
|
58
|
+
font,
|
|
59
|
+
font-family,
|
|
60
|
+
font-size,
|
|
61
|
+
font-weight,
|
|
62
|
+
font-style,
|
|
63
|
+
font-stretch,
|
|
64
|
+
line-height,
|
|
65
|
+
letter-spacing,
|
|
66
|
+
text-align,
|
|
67
|
+
text-decoration,
|
|
68
|
+
text-transform,
|
|
69
|
+
text-overflow,
|
|
70
|
+
white-space,
|
|
71
|
+
word-break,
|
|
72
|
+
word-wrap,
|
|
73
|
+
// Background
|
|
74
|
+
background,
|
|
75
|
+
background-color,
|
|
76
|
+
background-image,
|
|
77
|
+
background-repeat,
|
|
78
|
+
background-position,
|
|
79
|
+
background-size,
|
|
80
|
+
// Border
|
|
81
|
+
border,
|
|
82
|
+
border-width,
|
|
83
|
+
border-style,
|
|
84
|
+
border-color,
|
|
85
|
+
border-radius,
|
|
86
|
+
border-top,
|
|
87
|
+
border-right,
|
|
88
|
+
border-bottom,
|
|
89
|
+
border-left,
|
|
90
|
+
// Effects
|
|
91
|
+
box-shadow,
|
|
92
|
+
opacity,
|
|
93
|
+
filter,
|
|
94
|
+
// Transform & animation
|
|
95
|
+
transform,
|
|
96
|
+
transform-origin,
|
|
97
|
+
transition,
|
|
98
|
+
transition-property,
|
|
99
|
+
transition-duration,
|
|
100
|
+
transition-timing-function,
|
|
101
|
+
transition-delay,
|
|
102
|
+
animation,
|
|
103
|
+
animation-name,
|
|
104
|
+
animation-duration,
|
|
105
|
+
animation-timing-function,
|
|
106
|
+
animation-delay,
|
|
107
|
+
animation-iteration-count,
|
|
108
|
+
animation-direction,
|
|
109
|
+
animation-fill-mode,
|
|
110
|
+
// Interaction
|
|
111
|
+
cursor,
|
|
112
|
+
pointer-events,
|
|
113
|
+
user-select,
|
|
114
|
+
// Misc
|
|
115
|
+
outline,
|
|
116
|
+
outline-offset,
|
|
117
|
+
resize,
|
|
118
|
+
object-fit,
|
|
119
|
+
object-position
|
|
120
|
+
);
|
package/src/index.scss
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@use './Button/Button.scss';
|
|
2
|
+
@use './Icon/icon.scss';
|
|
3
|
+
@use './Popover/Popover.scss';
|
|
4
|
+
@use './Tooltip/Tooltip.scss';
|
|
5
|
+
@use './Checkbox/Checkbox.scss';
|
|
6
|
+
@use './Radio/Radio.scss';
|
|
7
|
+
@use './Tabs/Tabs.scss';
|
|
8
|
+
@use './Toaster/Toaster.scss';
|
|
9
|
+
@use './Dialog/Popup.scss';
|
|
10
|
+
@use './Dialog/Dialog.scss';
|
|
11
|
+
@use './DialogAlert/Alert.scss';
|
|
12
|
+
@use './Drawer/Drawer.scss';
|
|
13
|
+
@use './Form/Form.scss';
|
|
14
|
+
@use './Select/Select.scss';
|
|
15
|
+
@use './TextArea/TextArea.scss';
|
|
16
|
+
@use './SelectTags/SelectTags.scss';
|
|
17
|
+
@use './OptionItem/Option.scss';
|
|
18
|
+
@use './DateInput/DateInput.scss';
|
|
19
|
+
@use './DatePicker/DatePicker.scss';
|
|
20
|
+
@use './DatePicker/Calendar.scss';
|
|
21
|
+
@use './Form/Input.scss';
|
|
22
|
+
@use './Switch/Switch.scss';
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import './theme.scss'
|
|
2
|
+
|
|
3
|
+
export { Button } from './Button'
|
|
4
|
+
export { Spinner } from './Spinner'
|
|
5
|
+
export { Scrollable } from './Scrollable'
|
|
6
|
+
export { ImitateScroll } from './Scrollable/ImitateScroll'
|
|
7
|
+
export { Popover } from './Popover'
|
|
8
|
+
export { Tooltip } from './Tooltip'
|
|
9
|
+
export { StepperInput } from './Stepper'
|
|
10
|
+
export { Select } from './Select'
|
|
11
|
+
export { Form } from './Form'
|
|
12
|
+
export { OptionItem } from './OptionItem/OptionItem'
|
|
13
|
+
export { NumberInput } from './NumberInput'
|
|
14
|
+
export { OptionsList } from './OptionItem/OptionsList'
|
|
15
|
+
export { ButtonGroup } from './ButtonGroup'
|
|
16
|
+
export { Checkbox } from './Checkbox'
|
|
17
|
+
export { Switch } from './Switch'
|
|
18
|
+
export { Radio } from './Radio'
|
|
19
|
+
export { Drawer } from './Drawer'
|
|
20
|
+
export { Dialog } from './Dialog'
|
|
21
|
+
export { AlertDialog } from './DialogAlert/Alert'
|
|
22
|
+
export { LoadButton } from './LoadButton'
|
|
23
|
+
export { Tabs } from './Tabs'
|
|
24
|
+
export { Countdown } from './Countdown'
|
|
25
|
+
export { TextArea } from './TextArea'
|
|
26
|
+
export { SelectTags } from './SelectTags'
|
|
27
|
+
export { DatePicker } from './DatePicker'
|
|
28
|
+
export { FileOverlay } from './File'
|
|
29
|
+
// hooks
|
|
30
|
+
export * from './__hooks/use-local-storage'
|
|
31
|
+
// agents
|
|
32
|
+
export { createAlertAgent } from './DialogAlert'
|
|
33
|
+
export { createToaster } from './Toaster'
|
|
34
|
+
// types
|
|
35
|
+
export * from './types'
|
|
36
|
+
export type { Appearance } from './Button'
|
package/src/mixins.scss
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
@use './theme.scss';
|
|
2
|
+
@use './css.scss';
|
|
3
|
+
@use 'sass:map';
|
|
4
|
+
@use 'sass:list';
|
|
5
|
+
@use 'sass:meta';
|
|
6
|
+
|
|
7
|
+
@mixin height($size) {
|
|
8
|
+
height: $size;
|
|
9
|
+
min-height: $size;
|
|
10
|
+
max-height: $size;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@mixin box($size) {
|
|
14
|
+
height: $size;
|
|
15
|
+
width: $size;
|
|
16
|
+
min-width: $size;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@mixin items-spacing($spacing) {
|
|
20
|
+
& > * {
|
|
21
|
+
margin-right: $spacing;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
& > :last-child {
|
|
25
|
+
margin-right: 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@mixin truncate-text() {
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
text-overflow: ellipsis;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@function get-value($map, $keys...) {
|
|
36
|
+
$current: $map;
|
|
37
|
+
|
|
38
|
+
@each $key in $keys {
|
|
39
|
+
@if meta.type-of($current) != 'map' {
|
|
40
|
+
@return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
$current: map.get($current, $key);
|
|
44
|
+
|
|
45
|
+
@if $current == null {
|
|
46
|
+
@return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@return $current;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@mixin set-style($property, $source, $keys...) {
|
|
54
|
+
$path: list.append($keys, $property);
|
|
55
|
+
$var-name: get-value($source, $path...);
|
|
56
|
+
|
|
57
|
+
@if $var-name != null {
|
|
58
|
+
@if meta.type-of($var-name) != 'map' {
|
|
59
|
+
#{$property}: $var-name;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@mixin use-styles($component, $keys...) {
|
|
65
|
+
$source: map.get(theme.$tokens, $component);
|
|
66
|
+
|
|
67
|
+
@each $property, $v in css.$properties {
|
|
68
|
+
@include set-style($property, $source, $keys...);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@mixin use-styles-debug($component, $keys...) {
|
|
73
|
+
$source: map.get(theme.$tokens, $component);
|
|
74
|
+
|
|
75
|
+
@debug $source;
|
|
76
|
+
|
|
77
|
+
@each $property, $v in css.$properties {
|
|
78
|
+
@include set-style($property, $source, $keys...);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@function get-var-name($component, $keys...) {
|
|
83
|
+
$source: map.get(theme.$tokens, $component);
|
|
84
|
+
$var-name: get-value($source, $keys...);
|
|
85
|
+
|
|
86
|
+
@return $var-name;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@mixin use-size($component, $keys...) {
|
|
90
|
+
$name: get-var-name($component, $keys...);
|
|
91
|
+
|
|
92
|
+
@if $name != null {
|
|
93
|
+
@if meta.type-of($name) != 'map' {
|
|
94
|
+
width: $name;
|
|
95
|
+
min-width: $name;
|
|
96
|
+
height: $name;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
package/src/theme.scss
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use 'sass:string';
|
|
3
|
+
@use 'sass:list';
|
|
4
|
+
|
|
5
|
+
$button-appearances: ();
|
|
6
|
+
|
|
7
|
+
$tokens: ();
|
|
8
|
+
|
|
9
|
+
// changes
|
|
10
|
+
@function str-split($string, $delimiter) {
|
|
11
|
+
$result: ();
|
|
12
|
+
$buffer: '';
|
|
13
|
+
|
|
14
|
+
@for $i from 1 through string.length($string) {
|
|
15
|
+
$char: string.slice($string, $i, $i);
|
|
16
|
+
|
|
17
|
+
@if ($char == $delimiter) {
|
|
18
|
+
$result: list.append($result, $buffer);
|
|
19
|
+
$buffer: '';
|
|
20
|
+
} @else {
|
|
21
|
+
$buffer: $buffer + $char;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
$result: list.append($result, $buffer);
|
|
26
|
+
|
|
27
|
+
@return $result;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@function list-slice($list, $start, $end: list.length($list)) {
|
|
31
|
+
$new: ();
|
|
32
|
+
|
|
33
|
+
@for $i from $start through $end {
|
|
34
|
+
$new: list.append($new, list.nth($list, $i));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@return $new;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/// Добавляет значение в многоуровневую карту
|
|
41
|
+
@function map-deep-set($map, $keys, $value) {
|
|
42
|
+
$current: $map;
|
|
43
|
+
$key: list.nth($keys, 1);
|
|
44
|
+
|
|
45
|
+
@if list.length($keys) == 1 {
|
|
46
|
+
@return map.merge(
|
|
47
|
+
$current,
|
|
48
|
+
(
|
|
49
|
+
$key: $value
|
|
50
|
+
)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
$nested: map.get($current, $key);
|
|
55
|
+
|
|
56
|
+
@if $nested == null {
|
|
57
|
+
$nested: ();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
$nested: map-deep-set($nested, list-slice($keys, 2), $value);
|
|
61
|
+
|
|
62
|
+
@return map.merge(
|
|
63
|
+
$current,
|
|
64
|
+
(
|
|
65
|
+
$key: $nested
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@mixin use-button-properties($vars) {
|
|
71
|
+
@each $full-name, $v in $vars {
|
|
72
|
+
// Разбиваем путь: primary-default-enabled-background → ('primary', 'default', 'enabled', 'background')
|
|
73
|
+
$parts: str-split($full-name, '_');
|
|
74
|
+
// Создаём CSS переменную:
|
|
75
|
+
$css-var: string.unquote('var(--btn_#{$full-name})');
|
|
76
|
+
// Глубоко добавляем значение в структуру
|
|
77
|
+
$button-appearances: map-deep-set($button-appearances, $parts, $css-var) !global;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@mixin use-tokens($components) {
|
|
82
|
+
@each $component-name, $v in $components {
|
|
83
|
+
$component-vars: map.get($components, $component-name);
|
|
84
|
+
|
|
85
|
+
@each $path, $v in $component-vars {
|
|
86
|
+
$name: #{$component-name}_#{$path};
|
|
87
|
+
// Разбиваем путь: primary_default_enabled_background → ('primary', 'default', 'enabled', 'background')
|
|
88
|
+
$keys: str-split($name, '_');
|
|
89
|
+
// Создаём CSS переменную:
|
|
90
|
+
$css-var: string.unquote('var(--#{$name})');
|
|
91
|
+
// Глубоко добавляем значение в структуру
|
|
92
|
+
$tokens: map-deep-set($tokens, $keys, $css-var) !global;
|
|
93
|
+
// set scss var
|
|
94
|
+
--#{$name}: #{map.get($component-vars, $path)};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@mixin use-css-vars($prefix, $map) {
|
|
100
|
+
@each $name, $value in $map {
|
|
101
|
+
--#{$prefix}_#{$name}: #{$value};
|
|
102
|
+
}
|
|
103
|
+
}
|
package/src/types.ts
ADDED