@kkkarsss/ui 1.5.6 → 2.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/dist/components/ui/button.d.ts +16 -0
- package/dist/components/ui/button.js +33 -0
- package/dist/components/ui/calendar.d.ts +4 -0
- package/dist/components/ui/calendar.js +41 -0
- package/dist/components/ui/popover.d.ts +6 -0
- package/dist/components/ui/popover.js +9 -0
- package/dist/index.css +104 -47
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/ui/controls/date-input/date-input.d.ts +1 -0
- package/dist/ui/controls/date-input/date-input.js +27 -13
- package/dist/ui/controls/date-input/date-input.stories.d.ts +10 -0
- package/dist/ui/controls/date-input/date-input.stories.js +56 -0
- package/dist/ui/controls/date-picker/date-picker.d.ts +7 -2
- package/dist/ui/controls/date-picker/date-picker.js +6 -30
- package/dist/ui/controls/date-picker/date-picker.stories.d.ts +8 -0
- package/dist/ui/controls/date-picker/date-picker.stories.js +46 -0
- package/package.json +77 -70
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
declare const buttonVariants: (props?: ({
|
|
4
|
+
variant?: "link" | "secondary" | "default" | "outline" | "destructive" | "ghost" | null | undefined;
|
|
5
|
+
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export type ButtonProps = {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
} & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>;
|
|
10
|
+
declare const Button: React.ForwardRefExoticComponent<{
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
} & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
|
|
13
|
+
variant?: "link" | "secondary" | "default" | "outline" | "destructive" | "ghost" | null | undefined;
|
|
14
|
+
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
15
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & React.RefAttributes<HTMLButtonElement>>;
|
|
16
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { cn } from '../../lib/utils';
|
|
6
|
+
const buttonVariants = cva('inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', {
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
10
|
+
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
|
11
|
+
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
|
12
|
+
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
13
|
+
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
|
14
|
+
link: 'text-primary underline-offset-4 hover:underline',
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
default: 'h-10 px-4 py-2',
|
|
18
|
+
sm: 'h-9 rounded-md px-3',
|
|
19
|
+
lg: 'h-11 rounded-md px-8',
|
|
20
|
+
icon: 'h-10 w-10',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: 'default',
|
|
25
|
+
size: 'default',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
29
|
+
const Comp = asChild ? Slot : 'button';
|
|
30
|
+
return _jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref: ref, ...props });
|
|
31
|
+
});
|
|
32
|
+
Button.displayName = 'Button';
|
|
33
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { ru } from 'date-fns/locale';
|
|
4
|
+
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
|
|
5
|
+
import { DayPicker } from 'react-day-picker';
|
|
6
|
+
import { buttonVariants } from './button';
|
|
7
|
+
import { cn } from '../../lib/utils';
|
|
8
|
+
function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
|
|
9
|
+
return (_jsx(DayPicker, { locale: ru, showOutsideDays: showOutsideDays, className: cn('p-3 w-fit', className), classNames: {
|
|
10
|
+
months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0 relative',
|
|
11
|
+
month: 'space-y-4 w-full',
|
|
12
|
+
month_caption: 'flex justify-center pt-1 relative items-center h-9 w-full',
|
|
13
|
+
caption_label: 'text-sm font-medium',
|
|
14
|
+
nav: 'flex items-center',
|
|
15
|
+
button_previous: cn(buttonVariants({ variant: 'outline' }), 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-1 top-1 z-10'),
|
|
16
|
+
button_next: cn(buttonVariants({ variant: 'outline' }), 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-1 top-1 z-10'),
|
|
17
|
+
month_grid: 'w-full border-collapse space-y-1',
|
|
18
|
+
weekdays: 'flex gap-[2px]',
|
|
19
|
+
weekday: 'text-muted-foreground rounded-md w-9 font-normal text-[0.8rem] flex justify-center items-center',
|
|
20
|
+
week: 'flex w-full mt-[2px] gap-[2px]',
|
|
21
|
+
day: cn('h-9 w-9 p-0 font-normal aria-selected:opacity-100'),
|
|
22
|
+
day_button: cn('h-9 w-9 p-0 font-normal aria-selected:opacity-100 aria-selected:rounded-none'),
|
|
23
|
+
selected: 'bg-primary text-primary-foreground hover:bg-primary/80 hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground aria-selected:rounded-md',
|
|
24
|
+
range_start: '-selected:rounded-l-md aria-selected:bg-primary aria-selected:text-primary-foreground',
|
|
25
|
+
range_end: 'aria-selected:rounded-r-md aria-selected:bg-primary aria-selected:text-primary-foreground',
|
|
26
|
+
range_middle: 'aria-selected:bg-secondary/80 aria-selected:text-accent-foreground',
|
|
27
|
+
today: 'text-accent',
|
|
28
|
+
outside: 'day-outside text-muted-foreground aria-selected:bg-accent/50 aria-selected:text-muted-foreground',
|
|
29
|
+
disabled: 'text-muted-foreground opacity-50',
|
|
30
|
+
hidden: 'invisible',
|
|
31
|
+
...classNames,
|
|
32
|
+
}, components: {
|
|
33
|
+
Chevron: ({ ...props }) => {
|
|
34
|
+
if (props.orientation === 'left') {
|
|
35
|
+
return _jsx(ChevronLeftIcon, { className: "h-4 w-4" });
|
|
36
|
+
}
|
|
37
|
+
return _jsx(ChevronRightIcon, { className: "h-4 w-4" });
|
|
38
|
+
},
|
|
39
|
+
}, ...props }));
|
|
40
|
+
}
|
|
41
|
+
export { Calendar };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
declare const Popover: React.FC<PopoverPrimitive.PopoverProps>;
|
|
4
|
+
declare const PopoverTrigger: React.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
declare const PopoverContent: React.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
|
+
export { Popover, PopoverTrigger, PopoverContent };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
const Popover = PopoverPrimitive.Root;
|
|
6
|
+
const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
7
|
+
const PopoverContent = React.forwardRef(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (_jsx(PopoverPrimitive.Portal, { children: _jsx(PopoverPrimitive.Content, { ref: ref, align: align, sideOffset: sideOffset, className: cn('z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2', className), ...props }) })));
|
|
8
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
9
|
+
export { Popover, PopoverTrigger, PopoverContent };
|
package/dist/index.css
CHANGED
|
@@ -134,67 +134,131 @@
|
|
|
134
134
|
.gap-xl { gap: 32px; }
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
@layer base {
|
|
138
|
+
.dark {
|
|
139
|
+
--background: 0 0% 14%;
|
|
140
|
+
--foreground: 0 0% 85%;
|
|
141
|
+
|
|
142
|
+
--card: 222.2 84% 4.9%;
|
|
143
|
+
--card-foreground: 210 40% 98%;
|
|
144
|
+
|
|
145
|
+
--popover: 222.2 84% 4.9%;
|
|
146
|
+
--popover-foreground: 210 40% 98%;
|
|
147
|
+
|
|
148
|
+
--primary: 210 40% 98%;
|
|
149
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
150
|
+
|
|
151
|
+
--secondary: 0 0% 23%;
|
|
152
|
+
--secondary-foreground: 0 0% 60%;
|
|
153
|
+
|
|
154
|
+
--muted: 217.2 32.6% 17.5%;
|
|
155
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
156
|
+
|
|
157
|
+
--accent: 346 84% 58%;
|
|
158
|
+
--accent-foreground: 0 0% 100%;
|
|
159
|
+
|
|
160
|
+
--destructive: 0 62.8% 30.6%;
|
|
161
|
+
--destructive-foreground: 210 40% 98%;
|
|
162
|
+
|
|
163
|
+
--border: 217.2 32.6% 17.5%;
|
|
164
|
+
--input: 217.2 32.6% 17.5%;
|
|
165
|
+
--ring: 212.7 26.8% 83.9%;
|
|
166
|
+
|
|
167
|
+
--background-accent: #272727;
|
|
168
|
+
--shadow: rgba(0, 0, 0, 0.1);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
:root {
|
|
172
|
+
--background: 0 0% 14%;
|
|
173
|
+
--foreground: 0 0% 85%;
|
|
174
|
+
|
|
175
|
+
--card: 222.2 84% 4.9%;
|
|
176
|
+
--card-foreground: 210 40% 98%;
|
|
177
|
+
|
|
178
|
+
--popover: 222.2 84% 4.9%;
|
|
179
|
+
--popover-foreground: 210 40% 98%;
|
|
180
|
+
|
|
181
|
+
--primary: 210 40% 98%;
|
|
182
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
183
|
+
|
|
184
|
+
--secondary: 0 0% 23%;
|
|
185
|
+
--secondary-foreground: 0 0% 60%;
|
|
186
|
+
|
|
187
|
+
--muted: 217.2 32.6% 17.5%;
|
|
188
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
189
|
+
|
|
190
|
+
--accent: 346 84% 58%;
|
|
191
|
+
--accent-foreground: 0 0% 100%;
|
|
192
|
+
|
|
193
|
+
--destructive: 0 62.8% 30.6%;
|
|
194
|
+
--destructive-foreground: 210 40% 98%;
|
|
195
|
+
|
|
196
|
+
--border: 217.2 32.6% 17.5%;
|
|
197
|
+
--input: 217.2 32.6% 17.5%;
|
|
198
|
+
--ring: 212.7 26.8% 83.9%;
|
|
199
|
+
|
|
200
|
+
--radius: 0.5rem;
|
|
201
|
+
|
|
202
|
+
--background-accent: #272727;
|
|
203
|
+
--shadow: rgba(0, 0, 0, 0.1);
|
|
204
|
+
--success: #22c55e;
|
|
205
|
+
--warning: #f59e0b;
|
|
206
|
+
--error: #ef4444;
|
|
139
207
|
|
|
140
|
-
/* Text Sizes */
|
|
141
208
|
--text-xl: 18px;
|
|
142
209
|
--text-l: 16px;
|
|
143
210
|
--text-m: 14px;
|
|
144
211
|
--text-s: 12px;
|
|
145
212
|
--text-xs: 10px;
|
|
213
|
+
}
|
|
146
214
|
|
|
147
|
-
|
|
148
|
-
--background:
|
|
149
|
-
--
|
|
150
|
-
--foreground: #d9d9d9;
|
|
215
|
+
.light {
|
|
216
|
+
--background: 0 0% 96%;
|
|
217
|
+
--foreground: 240 10% 4%;
|
|
151
218
|
|
|
152
|
-
--
|
|
153
|
-
--
|
|
219
|
+
--card: 0 0% 100%;
|
|
220
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
154
221
|
|
|
155
|
-
--
|
|
156
|
-
--
|
|
157
|
-
--shadow: rgba(0, 0, 0, 0.1);
|
|
222
|
+
--popover: 0 0% 100%;
|
|
223
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
158
224
|
|
|
159
|
-
--
|
|
160
|
-
--
|
|
161
|
-
--error: #ef4444;
|
|
225
|
+
--primary: 222.2 47.4% 11.2%;
|
|
226
|
+
--primary-foreground: 210 40% 98%;
|
|
162
227
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
-webkit-font-smoothing: antialiased;
|
|
166
|
-
}
|
|
228
|
+
--secondary: 220 14% 91%;
|
|
229
|
+
--secondary-foreground: 240 0% 57%;
|
|
167
230
|
|
|
168
|
-
.
|
|
169
|
-
|
|
170
|
-
--background: #232323;
|
|
171
|
-
--background-accent: #272727;
|
|
172
|
-
--foreground: #d9d9d9;
|
|
231
|
+
--muted: 210 40% 96.1%;
|
|
232
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
173
233
|
|
|
174
|
-
--
|
|
175
|
-
--
|
|
234
|
+
--accent: 346 84% 58%;
|
|
235
|
+
--accent-foreground: 0 0% 100%;
|
|
176
236
|
|
|
177
|
-
--
|
|
178
|
-
--
|
|
179
|
-
--shadow: rgba(0, 0, 0, 0.1);
|
|
180
|
-
}
|
|
237
|
+
--destructive: 0 84.2% 60.2%;
|
|
238
|
+
--destructive-foreground: 210 40% 98%;
|
|
181
239
|
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
--
|
|
185
|
-
--background-accent: #fafafa;
|
|
186
|
-
--foreground: #080809;
|
|
240
|
+
--border: 214.3 31.8% 91.4%;
|
|
241
|
+
--input: 214.3 31.8% 91.4%;
|
|
242
|
+
--ring: 222.2 84% 4.9%;
|
|
187
243
|
|
|
188
|
-
--
|
|
189
|
-
--secondary-foreground: #919191;
|
|
244
|
+
--background-accent: #fafafa;
|
|
190
245
|
--shadow: rgba(0, 0, 0, 0.03);
|
|
246
|
+
}
|
|
191
247
|
}
|
|
192
248
|
|
|
193
|
-
|
|
249
|
+
@layer base {
|
|
250
|
+
* {
|
|
251
|
+
@apply border;
|
|
194
252
|
box-sizing: border-box;
|
|
195
253
|
margin: 0;
|
|
196
254
|
padding: 0;
|
|
197
255
|
font-family: Roboto, sans-serif;
|
|
256
|
+
}
|
|
257
|
+
body {
|
|
258
|
+
@apply bg-background text-foreground;
|
|
259
|
+
width: 100%;
|
|
260
|
+
height: 100vh;
|
|
261
|
+
}
|
|
198
262
|
}
|
|
199
263
|
|
|
200
264
|
.cursor {
|
|
@@ -206,16 +270,9 @@ a {
|
|
|
206
270
|
color: inherit;
|
|
207
271
|
}
|
|
208
272
|
|
|
209
|
-
body {
|
|
210
|
-
width: 100%;
|
|
211
|
-
height: 100vh;
|
|
212
|
-
background-color: var(--background);
|
|
213
|
-
color: var(--foreground);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
273
|
.scrollbar-custom {
|
|
217
274
|
scrollbar-width: thin;
|
|
218
|
-
scrollbar-color: var(--secondary) transparent;
|
|
275
|
+
scrollbar-color: hsl(var(--secondary)) transparent;
|
|
219
276
|
}
|
|
220
277
|
.scrollbar-custom::-webkit-scrollbar {
|
|
221
278
|
width: 4px;
|
|
@@ -225,7 +282,7 @@ body {
|
|
|
225
282
|
background: transparent;
|
|
226
283
|
}
|
|
227
284
|
.scrollbar-custom::-webkit-scrollbar-thumb {
|
|
228
|
-
background-color: var(--secondary);
|
|
285
|
+
background-color: hsl(var(--secondary));
|
|
229
286
|
border-radius: 10px;
|
|
230
287
|
}
|
|
231
288
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Temporal } from '@js-temporal/polyfill';
|
|
3
|
-
import { Calendar } from 'lucide-react';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { Calendar as CalendarIcon } from 'lucide-react';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { Popover, PopoverContent, PopoverTrigger } from '../../../components/ui/popover';
|
|
6
6
|
import { DatePicker } from '../date-picker/date-picker';
|
|
7
7
|
import { Input } from '../input/input';
|
|
8
|
-
export const DateInput = ({ value, onChange, label, placeholder, size = 'm', disabled }) => {
|
|
8
|
+
export const DateInput = ({ value, onChange, label, placeholder, size = 'm', disabled, showTime, }) => {
|
|
9
9
|
const [isOpen, setIsOpen] = useState(false);
|
|
10
|
-
const containerRef = useRef(null);
|
|
11
10
|
const handleDateSelect = (date) => {
|
|
12
11
|
if (date) {
|
|
13
12
|
const plainDate = Temporal.PlainDate.from({
|
|
@@ -15,14 +14,29 @@ export const DateInput = ({ value, onChange, label, placeholder, size = 'm', dis
|
|
|
15
14
|
month: date.getMonth() + 1,
|
|
16
15
|
day: date.getDate(),
|
|
17
16
|
});
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
if (showTime) {
|
|
18
|
+
// Если уже есть время в value, сохраняем его
|
|
19
|
+
let currentTime = '00:00';
|
|
20
|
+
if (value && value.includes('T')) {
|
|
21
|
+
currentTime = value.split('T')[1].substring(0, 5);
|
|
22
|
+
}
|
|
23
|
+
else if (value && value.includes(':')) {
|
|
24
|
+
currentTime = value.split(' ')[1] || value;
|
|
25
|
+
}
|
|
26
|
+
onChange(`${plainDate.toString()}T${currentTime}`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
onChange(plainDate.toString());
|
|
30
|
+
setIsOpen(false);
|
|
31
|
+
}
|
|
20
32
|
}
|
|
21
33
|
};
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
const handleTimeChange = (e) => {
|
|
35
|
+
const time = e.target.value;
|
|
36
|
+
const datePart = value.split('T')[0] || new Date().toISOString().split('T')[0];
|
|
37
|
+
onChange(`${datePart}T${time}`);
|
|
38
|
+
};
|
|
39
|
+
const selectedDate = value ? new Date(value.split('T')[0]) : undefined;
|
|
40
|
+
const timeValue = value && value.includes('T') ? value.split('T')[1].substring(0, 5) : '';
|
|
41
|
+
return (_jsx("div", { className: "relative w-full", children: _jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsxs("div", { className: "flex items-end gap-2", children: [_jsx(Input, { label: label, value: value, onChange: (e) => onChange(e.target.value), type: "text", placeholder: placeholder || (showTime ? 'YYYY-MM-DDTHH:mm' : 'YYYY-MM-DD'), size: size, disabled: disabled, rightAcc: _jsx("div", { className: "flex items-center h-full", children: _jsx(PopoverTrigger, { asChild: true, children: _jsx(CalendarIcon, { size: 16, className: "cursor-pointer text-secondary transition-colors hover:text-accent" }) }) }) }), showTime && (_jsx("div", { className: "w-24", children: _jsx(Input, { type: "text", value: timeValue, onChange: handleTimeChange, placeholder: "HH:mm", size: size, disabled: disabled }) }))] }), _jsx(PopoverContent, { className: "w-auto p-0", align: "end", children: _jsx(DatePicker, { selected: selectedDate, onSelect: handleDateSelect }) })] }) }));
|
|
28
42
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { DateInput } from './date-input';
|
|
3
|
+
declare const meta: Meta<typeof DateInput>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Empty: Story;
|
|
8
|
+
export declare const Sizes: Story;
|
|
9
|
+
export declare const Disabled: Story;
|
|
10
|
+
export declare const WithTime: Story;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { DateInput } from './date-input';
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Controls/DateInput',
|
|
6
|
+
component: DateInput,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
};
|
|
9
|
+
export default meta;
|
|
10
|
+
export const Default = {
|
|
11
|
+
render: (args) => {
|
|
12
|
+
const [value, setValue] = useState(args.value);
|
|
13
|
+
return _jsx(DateInput, { ...args, value: value, onChange: setValue });
|
|
14
|
+
},
|
|
15
|
+
args: {
|
|
16
|
+
value: '2024-05-20',
|
|
17
|
+
label: 'Выберите дату',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export const Empty = {
|
|
21
|
+
render: (args) => {
|
|
22
|
+
const [value, setValue] = useState(args.value);
|
|
23
|
+
return _jsx(DateInput, { ...args, value: value, onChange: setValue });
|
|
24
|
+
},
|
|
25
|
+
args: {
|
|
26
|
+
value: '',
|
|
27
|
+
label: 'Пустая дата',
|
|
28
|
+
placeholder: 'Выберите день...',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const Sizes = {
|
|
32
|
+
render: (args) => {
|
|
33
|
+
const [v1, setV1] = useState('2024-01-01');
|
|
34
|
+
const [v2, setV2] = useState('2024-01-01');
|
|
35
|
+
const [v3, setV3] = useState('2024-01-01');
|
|
36
|
+
return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx(DateInput, { ...args, size: "s", label: "Small", value: v1, onChange: setV1 }), _jsx(DateInput, { ...args, size: "m", label: "Medium", value: v2, onChange: setV2 }), _jsx(DateInput, { ...args, size: "l", label: "Large", value: v3, onChange: setV3 })] }));
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export const Disabled = {
|
|
40
|
+
args: {
|
|
41
|
+
value: '2024-05-20',
|
|
42
|
+
label: 'Заблокировано',
|
|
43
|
+
disabled: true,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export const WithTime = {
|
|
47
|
+
render: (args) => {
|
|
48
|
+
const [value, setValue] = useState(args.value);
|
|
49
|
+
return _jsx(DateInput, { ...args, value: value, onChange: setValue });
|
|
50
|
+
},
|
|
51
|
+
args: {
|
|
52
|
+
value: '2024-05-20T14:30',
|
|
53
|
+
label: 'С выбором времени',
|
|
54
|
+
showTime: true,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { FC } from 'react';
|
|
2
|
-
import 'react-day-picker
|
|
2
|
+
import type { DateRange } from 'react-day-picker';
|
|
3
3
|
export type TDatePickerProps = {
|
|
4
|
+
mode?: 'single';
|
|
4
5
|
selected?: Date;
|
|
5
|
-
onSelect
|
|
6
|
+
onSelect?: (date: Date | undefined) => void;
|
|
7
|
+
} | {
|
|
8
|
+
mode: 'range';
|
|
9
|
+
selected?: DateRange;
|
|
10
|
+
onSelect?: (range: DateRange | undefined) => void;
|
|
6
11
|
};
|
|
7
12
|
export declare const DatePicker: FC<TDatePickerProps>;
|
|
@@ -1,32 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
boxShadow: `0 4px 6px var(--shadow)`,
|
|
9
|
-
}, children: _jsx(DayPicker, { mode: "single", selected: selected, onSelect: onSelect, className: "react-day-picker", styles: {
|
|
10
|
-
caption: {
|
|
11
|
-
color: `var(--foreground)`,
|
|
12
|
-
},
|
|
13
|
-
day: {
|
|
14
|
-
borderRadius: '0.375rem',
|
|
15
|
-
color: `var(--foreground)`,
|
|
16
|
-
},
|
|
17
|
-
day_selected: {
|
|
18
|
-
backgroundColor: `var(--accent)`,
|
|
19
|
-
color: `var(--accent-foreground)`,
|
|
20
|
-
},
|
|
21
|
-
day_today: {
|
|
22
|
-
backgroundColor: `var(--background-secondary)`,
|
|
23
|
-
color: `var(--foreground)`,
|
|
24
|
-
},
|
|
25
|
-
day_outside: {
|
|
26
|
-
color: `var(--secondary-foreground)`,
|
|
27
|
-
},
|
|
28
|
-
root: {
|
|
29
|
-
background: `var(--background-accent)`,
|
|
30
|
-
},
|
|
31
|
-
} }) }));
|
|
2
|
+
import { Calendar } from '../../../components/ui/calendar';
|
|
3
|
+
export const DatePicker = (props) => {
|
|
4
|
+
if (props.mode === 'range') {
|
|
5
|
+
return (_jsx(Calendar, { mode: "range", selected: props.selected, onSelect: props.onSelect, className: 'rounded-lg border w-fit' }));
|
|
6
|
+
}
|
|
7
|
+
return (_jsx(Calendar, { mode: "single", selected: props.selected, onSelect: props.onSelect, className: 'rounded-lg border-accent w-fit' }));
|
|
32
8
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { type TDatePickerProps } from './date-picker';
|
|
3
|
+
declare const meta: Meta<TDatePickerProps>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<TDatePickerProps>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Range: Story;
|
|
8
|
+
export declare const Empty: Story;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { addDays } from 'date-fns';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { DatePicker } from './date-picker';
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'Controls/DatePicker',
|
|
7
|
+
component: DatePicker,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
};
|
|
10
|
+
export default meta;
|
|
11
|
+
export const Default = {
|
|
12
|
+
render: (args) => {
|
|
13
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
14
|
+
const [selected, setSelected] = useState(args.selected);
|
|
15
|
+
return _jsx(DatePicker, { ...args, selected: selected, onSelect: setSelected });
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
mode: 'single',
|
|
19
|
+
selected: new Date(),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
export const Range = {
|
|
23
|
+
render: (args) => {
|
|
24
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
25
|
+
const [selected, setSelected] = useState(args.selected);
|
|
26
|
+
return _jsx(DatePicker, { ...args, mode: "range", selected: selected, onSelect: setSelected });
|
|
27
|
+
},
|
|
28
|
+
args: {
|
|
29
|
+
mode: 'range',
|
|
30
|
+
selected: {
|
|
31
|
+
from: new Date(),
|
|
32
|
+
to: addDays(new Date(), 7),
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
export const Empty = {
|
|
37
|
+
render: (args) => {
|
|
38
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
39
|
+
const [selected, setSelected] = useState(args.selected);
|
|
40
|
+
return _jsx(DatePicker, { ...args, selected: selected, onSelect: setSelected });
|
|
41
|
+
},
|
|
42
|
+
args: {
|
|
43
|
+
mode: 'single',
|
|
44
|
+
selected: undefined,
|
|
45
|
+
},
|
|
46
|
+
};
|
package/package.json
CHANGED
|
@@ -1,70 +1,77 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@kkkarsss/ui",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "UI Kit for kkkarsss projects",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
],
|
|
11
|
-
"scripts": {
|
|
12
|
-
"build": "tsc && copy src\\index.css dist\\index.css",
|
|
13
|
-
"prepare": "npm run build",
|
|
14
|
-
"lint": "eslint .",
|
|
15
|
-
"format": "prettier --write .",
|
|
16
|
-
"storybook": "storybook dev -p 6006",
|
|
17
|
-
"build-storybook": "storybook build"
|
|
18
|
-
},
|
|
19
|
-
"keywords": [],
|
|
20
|
-
"author": "",
|
|
21
|
-
"license": "MIT",
|
|
22
|
-
"peerDependencies": {
|
|
23
|
-
"react": ">=18",
|
|
24
|
-
"react-dom": ">=18"
|
|
25
|
-
},
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"@chromatic-com/storybook": "^5.0.0",
|
|
28
|
-
"@eslint/js": "^9.39.2",
|
|
29
|
-
"@storybook/addon-a11y": "^10.2.7",
|
|
30
|
-
"@storybook/addon-docs": "^10.2.7",
|
|
31
|
-
"@storybook/addon-onboarding": "^10.2.7",
|
|
32
|
-
"@storybook/addon-vitest": "^10.2.7",
|
|
33
|
-
"@storybook/react": "^10.2.7",
|
|
34
|
-
"@storybook/react-vite": "^10.2.7",
|
|
35
|
-
"@tailwindcss/container-queries": "^0.1.1",
|
|
36
|
-
"@types/node": "^25.0.10",
|
|
37
|
-
"@types/react": "^19.2.9",
|
|
38
|
-
"@types/react-dom": "^19.2.3",
|
|
39
|
-
"@vitest/browser-playwright": "^4.0.18",
|
|
40
|
-
"@vitest/coverage-v8": "^4.0.18",
|
|
41
|
-
"autoprefixer": "^10.4.23",
|
|
42
|
-
"eslint": "^9.39.1",
|
|
43
|
-
"eslint-config-prettier": "^10.1.8",
|
|
44
|
-
"eslint-import-resolver-typescript": "^4.4.4",
|
|
45
|
-
"eslint-plugin-import": "^2.32.0",
|
|
46
|
-
"eslint-plugin-react-hooks": "^7.0.1",
|
|
47
|
-
"eslint-plugin-react-refresh": "^0.4.26",
|
|
48
|
-
"eslint-plugin-storybook": "^10.2.7",
|
|
49
|
-
"globals": "^16.5.0",
|
|
50
|
-
"lucide-react": "^0.563.0",
|
|
51
|
-
"playwright": "^1.58.0",
|
|
52
|
-
"postcss": "^8.5.6",
|
|
53
|
-
"prettier": "^3.8.1",
|
|
54
|
-
"react": "^19.2.3",
|
|
55
|
-
"react-dom": "^19.2.3",
|
|
56
|
-
"storybook": "^10.2.7",
|
|
57
|
-
"tailwindcss": "^3.4.19",
|
|
58
|
-
"typescript": "5.9.3",
|
|
59
|
-
"typescript-eslint": "^8.53.1",
|
|
60
|
-
"vite": "^7.3.1",
|
|
61
|
-
"vitest": "^4.0.18"
|
|
62
|
-
},
|
|
63
|
-
"dependencies": {
|
|
64
|
-
"@js-temporal/polyfill": "^0.5.1",
|
|
65
|
-
"@react-spring/web": "^10.0.3",
|
|
66
|
-
"date-fns": "^4.1.0",
|
|
67
|
-
"react-datepicker": "^9.1.0",
|
|
68
|
-
"react-day-picker": "^9.13.0"
|
|
69
|
-
|
|
70
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@kkkarsss/ui",
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "UI Kit for kkkarsss projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc && copy src\\index.css dist\\index.css",
|
|
13
|
+
"prepare": "npm run build",
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"format": "prettier --write .",
|
|
16
|
+
"storybook": "storybook dev -p 6006",
|
|
17
|
+
"build-storybook": "storybook build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [],
|
|
20
|
+
"author": "",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": ">=18",
|
|
24
|
+
"react-dom": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@chromatic-com/storybook": "^5.0.0",
|
|
28
|
+
"@eslint/js": "^9.39.2",
|
|
29
|
+
"@storybook/addon-a11y": "^10.2.7",
|
|
30
|
+
"@storybook/addon-docs": "^10.2.7",
|
|
31
|
+
"@storybook/addon-onboarding": "^10.2.7",
|
|
32
|
+
"@storybook/addon-vitest": "^10.2.7",
|
|
33
|
+
"@storybook/react": "^10.2.7",
|
|
34
|
+
"@storybook/react-vite": "^10.2.7",
|
|
35
|
+
"@tailwindcss/container-queries": "^0.1.1",
|
|
36
|
+
"@types/node": "^25.0.10",
|
|
37
|
+
"@types/react": "^19.2.9",
|
|
38
|
+
"@types/react-dom": "^19.2.3",
|
|
39
|
+
"@vitest/browser-playwright": "^4.0.18",
|
|
40
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
41
|
+
"autoprefixer": "^10.4.23",
|
|
42
|
+
"eslint": "^9.39.1",
|
|
43
|
+
"eslint-config-prettier": "^10.1.8",
|
|
44
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
45
|
+
"eslint-plugin-import": "^2.32.0",
|
|
46
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
47
|
+
"eslint-plugin-react-refresh": "^0.4.26",
|
|
48
|
+
"eslint-plugin-storybook": "^10.2.7",
|
|
49
|
+
"globals": "^16.5.0",
|
|
50
|
+
"lucide-react": "^0.563.0",
|
|
51
|
+
"playwright": "^1.58.0",
|
|
52
|
+
"postcss": "^8.5.6",
|
|
53
|
+
"prettier": "^3.8.1",
|
|
54
|
+
"react": "^19.2.3",
|
|
55
|
+
"react-dom": "^19.2.3",
|
|
56
|
+
"storybook": "^10.2.7",
|
|
57
|
+
"tailwindcss": "^3.4.19",
|
|
58
|
+
"typescript": "5.9.3",
|
|
59
|
+
"typescript-eslint": "^8.53.1",
|
|
60
|
+
"vite": "^7.3.1",
|
|
61
|
+
"vitest": "^4.0.18"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@js-temporal/polyfill": "^0.5.1",
|
|
65
|
+
"@react-spring/web": "^10.0.3",
|
|
66
|
+
"date-fns": "^4.1.0",
|
|
67
|
+
"react-datepicker": "^9.1.0",
|
|
68
|
+
"react-day-picker": "^9.13.0",
|
|
69
|
+
"clsx": "^2.1.1",
|
|
70
|
+
"tailwind-merge": "^2.5.2",
|
|
71
|
+
"class-variance-authority": "^0.7.0",
|
|
72
|
+
"radix-ui": "^1.1.0",
|
|
73
|
+
"@radix-ui/react-popover": "^1.1.2",
|
|
74
|
+
"@radix-ui/react-slot": "^1.1.0",
|
|
75
|
+
"tailwindcss-animate": "^1.0.7"
|
|
76
|
+
}
|
|
77
|
+
}
|