@rovula/ui 0.0.68 → 0.0.70
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/cjs/bundle.css +67 -0
- package/dist/cjs/bundle.js +3 -3
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
- package/dist/cjs/types/components/FocusedScrollView/FocusedScrollView.d.ts +12 -0
- package/dist/cjs/types/components/FocusedScrollView/FocusedScrollView.stories.d.ts +7 -0
- package/dist/cjs/types/components/InputFilter/InputFilter.stories.d.ts +2 -0
- package/dist/cjs/types/components/Search/Search.stories.d.ts +2 -0
- package/dist/cjs/types/components/TextInput/TextInput.d.ts +4 -0
- package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +11 -0
- package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +1 -0
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/components/FocusedScrollView/FocusedScrollView.js +67 -0
- package/dist/components/FocusedScrollView/FocusedScrollView.stories.js +33 -0
- package/dist/components/TextInput/TextInput.js +66 -14
- package/dist/components/TextInput/TextInput.stories.js +15 -0
- package/dist/components/TextInput/TextInput.styles.js +116 -7
- package/dist/esm/bundle.css +67 -0
- package/dist/esm/bundle.js +3 -3
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
- package/dist/esm/types/components/FocusedScrollView/FocusedScrollView.d.ts +12 -0
- package/dist/esm/types/components/FocusedScrollView/FocusedScrollView.stories.d.ts +7 -0
- package/dist/esm/types/components/InputFilter/InputFilter.stories.d.ts +2 -0
- package/dist/esm/types/components/Search/Search.stories.d.ts +2 -0
- package/dist/esm/types/components/TextInput/TextInput.d.ts +4 -0
- package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +11 -0
- package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +1 -0
- package/dist/esm/types/index.d.ts +1 -0
- package/dist/index.d.ts +17 -2
- package/dist/index.js +1 -0
- package/dist/src/theme/global.css +86 -0
- package/package.json +1 -1
- package/src/components/FocusedScrollView/FocusedScrollView.stories.tsx +114 -0
- package/src/components/FocusedScrollView/FocusedScrollView.tsx +112 -0
- package/src/components/TextInput/TextInput.stories.tsx +83 -0
- package/src/components/TextInput/TextInput.styles.ts +117 -7
- package/src/components/TextInput/TextInput.tsx +115 -21
- package/src/index.ts +1 -0
|
@@ -359,10 +359,12 @@ declare const meta: {
|
|
|
359
359
|
placeholder?: string | undefined | undefined;
|
|
360
360
|
readOnly?: boolean | undefined | undefined;
|
|
361
361
|
src?: string | undefined | undefined;
|
|
362
|
+
iconMode?: "flat" | "solid" | undefined;
|
|
362
363
|
keepCloseIconOnValue?: boolean | undefined;
|
|
363
364
|
labelClassName?: string | undefined;
|
|
364
365
|
onClickStartIcon?: (() => void) | undefined;
|
|
365
366
|
onClickEndIcon?: (() => void) | undefined;
|
|
367
|
+
renderStartIcon?: (() => React.ReactNode) | undefined;
|
|
366
368
|
renderEndIcon?: (() => React.ReactNode) | undefined;
|
|
367
369
|
ref?: React.LegacyRef<HTMLInputElement> | undefined;
|
|
368
370
|
key?: React.Key | null | undefined;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { ReactNode, HTMLAttributes } from "react";
|
|
2
|
+
type ScrollAlign = "start" | "center" | "end";
|
|
3
|
+
type FocusedScrollViewProps = {
|
|
4
|
+
selectedKey?: string;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
direction?: "vertical" | "horizontal";
|
|
7
|
+
className?: string;
|
|
8
|
+
containerProps?: HTMLAttributes<HTMLDivElement>;
|
|
9
|
+
scrollAlign?: ScrollAlign;
|
|
10
|
+
};
|
|
11
|
+
export declare const FocusedScrollView: React.FC<FocusedScrollViewProps>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { FocusedScrollView } from "./FocusedScrollView";
|
|
3
|
+
declare const meta: Meta<typeof FocusedScrollView>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof FocusedScrollView>;
|
|
6
|
+
export declare const VerticalScroll: Story;
|
|
7
|
+
export declare const HorizontalScroll: Story;
|
|
@@ -349,10 +349,12 @@ declare const meta: {
|
|
|
349
349
|
placeholder?: string | undefined | undefined;
|
|
350
350
|
readOnly?: boolean | undefined | undefined;
|
|
351
351
|
src?: string | undefined | undefined;
|
|
352
|
+
iconMode?: "flat" | "solid" | undefined;
|
|
352
353
|
keepCloseIconOnValue?: boolean | undefined;
|
|
353
354
|
labelClassName?: string | undefined;
|
|
354
355
|
onClickStartIcon?: (() => void) | undefined;
|
|
355
356
|
onClickEndIcon?: (() => void) | undefined;
|
|
357
|
+
renderStartIcon?: (() => React.ReactNode) | undefined;
|
|
356
358
|
renderEndIcon?: (() => React.ReactNode) | undefined;
|
|
357
359
|
ref?: React.LegacyRef<HTMLInputElement> | undefined;
|
|
358
360
|
key?: React.Key | null | undefined;
|
|
@@ -310,11 +310,13 @@ declare const meta: {
|
|
|
310
310
|
required?: boolean | undefined;
|
|
311
311
|
src?: string | undefined | undefined;
|
|
312
312
|
label?: string | undefined;
|
|
313
|
+
iconMode?: "flat" | "solid" | undefined;
|
|
313
314
|
helperText?: string | undefined;
|
|
314
315
|
errorMessage?: string | undefined;
|
|
315
316
|
labelClassName?: string | undefined;
|
|
316
317
|
onClickStartIcon?: (() => void) | undefined;
|
|
317
318
|
onClickEndIcon?: (() => void) | undefined;
|
|
319
|
+
renderStartIcon?: (() => React.ReactNode) | undefined;
|
|
318
320
|
renderEndIcon?: (() => React.ReactNode) | undefined;
|
|
319
321
|
modal?: boolean | undefined;
|
|
320
322
|
optionContainerClassName?: string | undefined;
|
|
@@ -5,6 +5,7 @@ export type InputProps = {
|
|
|
5
5
|
size?: "sm" | "md" | "lg";
|
|
6
6
|
rounded?: "none" | "normal" | "full";
|
|
7
7
|
variant?: "flat" | "outline" | "underline";
|
|
8
|
+
iconMode?: "flat" | "solid";
|
|
8
9
|
type?: React.HTMLInputTypeAttribute;
|
|
9
10
|
helperText?: string;
|
|
10
11
|
errorMessage?: string;
|
|
@@ -22,6 +23,7 @@ export type InputProps = {
|
|
|
22
23
|
labelClassName?: string;
|
|
23
24
|
onClickStartIcon?: () => void;
|
|
24
25
|
onClickEndIcon?: () => void;
|
|
26
|
+
renderStartIcon?: () => ReactNode;
|
|
25
27
|
renderEndIcon?: () => ReactNode;
|
|
26
28
|
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">;
|
|
27
29
|
export declare const TextInput: React.ForwardRefExoticComponent<{
|
|
@@ -30,6 +32,7 @@ export declare const TextInput: React.ForwardRefExoticComponent<{
|
|
|
30
32
|
size?: "sm" | "md" | "lg";
|
|
31
33
|
rounded?: "none" | "normal" | "full";
|
|
32
34
|
variant?: "flat" | "outline" | "underline";
|
|
35
|
+
iconMode?: "flat" | "solid";
|
|
33
36
|
type?: React.HTMLInputTypeAttribute;
|
|
34
37
|
helperText?: string;
|
|
35
38
|
errorMessage?: string;
|
|
@@ -47,6 +50,7 @@ export declare const TextInput: React.ForwardRefExoticComponent<{
|
|
|
47
50
|
labelClassName?: string;
|
|
48
51
|
onClickStartIcon?: () => void;
|
|
49
52
|
onClickEndIcon?: () => void;
|
|
53
|
+
renderStartIcon?: () => ReactNode;
|
|
50
54
|
renderEndIcon?: () => ReactNode;
|
|
51
55
|
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & React.RefAttributes<HTMLInputElement>>;
|
|
52
56
|
export default TextInput;
|
|
@@ -7,6 +7,7 @@ declare const meta: {
|
|
|
7
7
|
size?: "sm" | "md" | "lg";
|
|
8
8
|
rounded?: "none" | "normal" | "full";
|
|
9
9
|
variant?: "flat" | "outline" | "underline";
|
|
10
|
+
iconMode?: "flat" | "solid";
|
|
10
11
|
type?: React.HTMLInputTypeAttribute;
|
|
11
12
|
helperText?: string;
|
|
12
13
|
errorMessage?: string;
|
|
@@ -24,6 +25,7 @@ declare const meta: {
|
|
|
24
25
|
labelClassName?: string;
|
|
25
26
|
onClickStartIcon?: () => void;
|
|
26
27
|
onClickEndIcon?: () => void;
|
|
28
|
+
renderStartIcon?: () => React.ReactNode;
|
|
27
29
|
renderEndIcon?: () => React.ReactNode;
|
|
28
30
|
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & React.RefAttributes<HTMLInputElement>>;
|
|
29
31
|
tags: string[];
|
|
@@ -36,6 +38,7 @@ declare const meta: {
|
|
|
36
38
|
size?: "sm" | "md" | "lg" | undefined;
|
|
37
39
|
rounded?: "none" | "normal" | "full" | undefined;
|
|
38
40
|
variant?: "flat" | "outline" | "underline" | undefined;
|
|
41
|
+
iconMode?: "flat" | "solid" | undefined;
|
|
39
42
|
type?: React.HTMLInputTypeAttribute | undefined;
|
|
40
43
|
helperText?: string | undefined;
|
|
41
44
|
errorMessage?: string | undefined;
|
|
@@ -53,6 +56,7 @@ declare const meta: {
|
|
|
53
56
|
labelClassName?: string | undefined;
|
|
54
57
|
onClickStartIcon?: (() => void) | undefined;
|
|
55
58
|
onClickEndIcon?: (() => void) | undefined;
|
|
59
|
+
renderStartIcon?: (() => React.ReactNode) | undefined;
|
|
56
60
|
renderEndIcon?: (() => React.ReactNode) | undefined;
|
|
57
61
|
suppressHydrationWarning?: boolean | undefined | undefined;
|
|
58
62
|
color?: string | undefined | undefined;
|
|
@@ -371,3 +375,10 @@ export declare const FuctionInput: {
|
|
|
371
375
|
};
|
|
372
376
|
render: (args: {}) => import("react/jsx-runtime").JSX.Element;
|
|
373
377
|
};
|
|
378
|
+
export declare const CustomIcon: {
|
|
379
|
+
args: {
|
|
380
|
+
label: string;
|
|
381
|
+
disabled: boolean;
|
|
382
|
+
};
|
|
383
|
+
render: (args: {}) => import("react/jsx-runtime").JSX.Element;
|
|
384
|
+
};
|
|
@@ -15,6 +15,7 @@ export declare const labelVariant: (props?: ({
|
|
|
15
15
|
disabled?: boolean | null | undefined;
|
|
16
16
|
error?: boolean | null | undefined;
|
|
17
17
|
hasSearchIcon?: boolean | null | undefined;
|
|
18
|
+
hasLeftSectionIcon?: boolean | null | undefined;
|
|
18
19
|
isFloatingLabel?: boolean | null | undefined;
|
|
19
20
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
20
21
|
export declare const helperTextVariant: (props?: ({
|
|
@@ -33,6 +33,7 @@ export * from "./components/Toast/Toast";
|
|
|
33
33
|
export * from "./components/Toast/Toaster";
|
|
34
34
|
export * from "./components/Toast/useToast";
|
|
35
35
|
export * from "./components/Tree";
|
|
36
|
+
export * from "./components/FocusedScrollView/FocusedScrollView";
|
|
36
37
|
export type { ButtonProps } from "./components/Button/Button";
|
|
37
38
|
export type { InputProps } from "./components/TextInput/TextInput";
|
|
38
39
|
export type { DropdownProps, Options } from "./components/Dropdown/Dropdown";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import React__default, { ReactElement, ReactNode, CSSProperties, FC, ComponentPropsWithoutRef } from 'react';
|
|
2
|
+
import React__default, { ReactElement, ReactNode, CSSProperties, FC, ComponentPropsWithoutRef, HTMLAttributes } from 'react';
|
|
3
3
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
4
4
|
import * as class_variance_authority_dist_types from 'class-variance-authority/dist/types';
|
|
5
5
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
@@ -49,6 +49,7 @@ type InputProps = {
|
|
|
49
49
|
size?: "sm" | "md" | "lg";
|
|
50
50
|
rounded?: "none" | "normal" | "full";
|
|
51
51
|
variant?: "flat" | "outline" | "underline";
|
|
52
|
+
iconMode?: "flat" | "solid";
|
|
52
53
|
type?: React__default.HTMLInputTypeAttribute;
|
|
53
54
|
helperText?: string;
|
|
54
55
|
errorMessage?: string;
|
|
@@ -66,6 +67,7 @@ type InputProps = {
|
|
|
66
67
|
labelClassName?: string;
|
|
67
68
|
onClickStartIcon?: () => void;
|
|
68
69
|
onClickEndIcon?: () => void;
|
|
70
|
+
renderStartIcon?: () => ReactNode;
|
|
69
71
|
renderEndIcon?: () => ReactNode;
|
|
70
72
|
} & Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "size">;
|
|
71
73
|
declare const TextInput: React__default.ForwardRefExoticComponent<{
|
|
@@ -74,6 +76,7 @@ declare const TextInput: React__default.ForwardRefExoticComponent<{
|
|
|
74
76
|
size?: "sm" | "md" | "lg";
|
|
75
77
|
rounded?: "none" | "normal" | "full";
|
|
76
78
|
variant?: "flat" | "outline" | "underline";
|
|
79
|
+
iconMode?: "flat" | "solid";
|
|
77
80
|
type?: React__default.HTMLInputTypeAttribute;
|
|
78
81
|
helperText?: string;
|
|
79
82
|
errorMessage?: string;
|
|
@@ -91,6 +94,7 @@ declare const TextInput: React__default.ForwardRefExoticComponent<{
|
|
|
91
94
|
labelClassName?: string;
|
|
92
95
|
onClickStartIcon?: () => void;
|
|
93
96
|
onClickEndIcon?: () => void;
|
|
97
|
+
renderStartIcon?: () => ReactNode;
|
|
94
98
|
renderEndIcon?: () => ReactNode;
|
|
95
99
|
} & Omit<React__default.InputHTMLAttributes<HTMLInputElement>, "size"> & React__default.RefAttributes<HTMLInputElement>>;
|
|
96
100
|
|
|
@@ -732,6 +736,17 @@ declare const Tree: FC<TreeProps>;
|
|
|
732
736
|
|
|
733
737
|
declare const TreeItem: FC<TreeItemProps>;
|
|
734
738
|
|
|
739
|
+
type ScrollAlign = "start" | "center" | "end";
|
|
740
|
+
type FocusedScrollViewProps = {
|
|
741
|
+
selectedKey?: string;
|
|
742
|
+
children: ReactNode;
|
|
743
|
+
direction?: "vertical" | "horizontal";
|
|
744
|
+
className?: string;
|
|
745
|
+
containerProps?: HTMLAttributes<HTMLDivElement>;
|
|
746
|
+
scrollAlign?: ScrollAlign;
|
|
747
|
+
};
|
|
748
|
+
declare const FocusedScrollView: React__default.FC<FocusedScrollViewProps>;
|
|
749
|
+
|
|
735
750
|
declare const resloveTimestamp: (timestamp: number) => number;
|
|
736
751
|
declare const getStartDateOfDay: (date: Date) => Date;
|
|
737
752
|
declare const getEndDateOfDay: (date: Date) => Date;
|
|
@@ -745,4 +760,4 @@ declare function usePrevious<T>(value: T): T | undefined;
|
|
|
745
760
|
|
|
746
761
|
declare function cn(...inputs: ClassValue[]): string;
|
|
747
762
|
|
|
748
|
-
export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, DataTable, type DataTableProps, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, Navbar, type NavbarProps, type Options$1 as Options, Popover, PopoverContent, PopoverTrigger, ProgressBar, Search, type SearchProps, Slider, type SliderProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextInput, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, reducer, resloveTimestamp, toast, usePrevious, useToast };
|
|
763
|
+
export { ActionButton, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, Calendar, Checkbox, Collapsible, DataTable, type DataTableProps, DatePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type DropdownProps, FocusedScrollView, Icon, Input, InputFilter, type InputFilterProps, type InputProps, Label, Loading, Navbar, type NavbarProps, type Options$1 as Options, Popover, PopoverContent, PopoverTrigger, ProgressBar, Search, type SearchProps, Slider, type SliderProps, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextInput, Toast$1 as Toast, ToastAction, type ToastActionElement, ToastClose, ToastDescription, type ToastProps, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipSimple, TooltipTrigger, Tree, type TreeData, TreeItem, type TreeItemProps, type TreeProps, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, reducer, resloveTimestamp, toast, usePrevious, useToast };
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,7 @@ export * from "./components/Toast/Toast";
|
|
|
35
35
|
export * from "./components/Toast/Toaster";
|
|
36
36
|
export * from "./components/Toast/useToast";
|
|
37
37
|
export * from "./components/Tree";
|
|
38
|
+
export * from "./components/FocusedScrollView/FocusedScrollView";
|
|
38
39
|
// UTILS
|
|
39
40
|
export { resloveTimestamp, getStartDateOfDay, getEndDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, } from "./utils/datetime";
|
|
40
41
|
// Hooks
|
|
@@ -2284,10 +2284,22 @@ input[type=number] {
|
|
|
2284
2284
|
left: 2.25rem;
|
|
2285
2285
|
}
|
|
2286
2286
|
|
|
2287
|
+
.left-\[38px\] {
|
|
2288
|
+
left: 38px;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
.left-\[46px\] {
|
|
2292
|
+
left: 46px;
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2287
2295
|
.left-\[50\%\] {
|
|
2288
2296
|
left: 50%;
|
|
2289
2297
|
}
|
|
2290
2298
|
|
|
2299
|
+
.left-\[72px\] {
|
|
2300
|
+
left: 72px;
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2291
2303
|
.right-0 {
|
|
2292
2304
|
right: 0px;
|
|
2293
2305
|
}
|
|
@@ -2349,6 +2361,11 @@ input[type=number] {
|
|
|
2349
2361
|
margin-right: -0.5rem;
|
|
2350
2362
|
}
|
|
2351
2363
|
|
|
2364
|
+
.mx-2 {
|
|
2365
|
+
margin-left: 0.5rem;
|
|
2366
|
+
margin-right: 0.5rem;
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2352
2369
|
.mx-4 {
|
|
2353
2370
|
margin-left: 1rem;
|
|
2354
2371
|
margin-right: 1rem;
|
|
@@ -2440,6 +2457,10 @@ input[type=number] {
|
|
|
2440
2457
|
display: block;
|
|
2441
2458
|
}
|
|
2442
2459
|
|
|
2460
|
+
.inline-block {
|
|
2461
|
+
display: inline-block;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2443
2464
|
.flex {
|
|
2444
2465
|
display: flex;
|
|
2445
2466
|
}
|
|
@@ -2651,6 +2672,10 @@ input[type=number] {
|
|
|
2651
2672
|
width: 0.5rem;
|
|
2652
2673
|
}
|
|
2653
2674
|
|
|
2675
|
+
.w-28 {
|
|
2676
|
+
width: 7rem;
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2654
2679
|
.w-3 {
|
|
2655
2680
|
width: 0.75rem;
|
|
2656
2681
|
}
|
|
@@ -2741,6 +2766,10 @@ input[type=number] {
|
|
|
2741
2766
|
min-width: fit-content;
|
|
2742
2767
|
}
|
|
2743
2768
|
|
|
2769
|
+
.max-w-full {
|
|
2770
|
+
max-width: 100%;
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2744
2773
|
.max-w-lg {
|
|
2745
2774
|
max-width: 32rem;
|
|
2746
2775
|
}
|
|
@@ -3015,6 +3044,10 @@ input[type=number] {
|
|
|
3015
3044
|
text-overflow: ellipsis;
|
|
3016
3045
|
}
|
|
3017
3046
|
|
|
3047
|
+
.whitespace-nowrap {
|
|
3048
|
+
white-space: nowrap;
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3018
3051
|
.rounded {
|
|
3019
3052
|
border-radius: 0.25rem;
|
|
3020
3053
|
}
|
|
@@ -3047,6 +3080,21 @@ input[type=number] {
|
|
|
3047
3080
|
border-radius: var(--radius-radius-xs);
|
|
3048
3081
|
}
|
|
3049
3082
|
|
|
3083
|
+
.rounded-l-full {
|
|
3084
|
+
border-top-left-radius: 9999px;
|
|
3085
|
+
border-bottom-left-radius: 9999px;
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3088
|
+
.rounded-l-none {
|
|
3089
|
+
border-top-left-radius: 0px;
|
|
3090
|
+
border-bottom-left-radius: 0px;
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
.rounded-l-xl {
|
|
3094
|
+
border-top-left-radius: var(--radius-radius-xl);
|
|
3095
|
+
border-bottom-left-radius: var(--radius-radius-xl);
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3050
3098
|
.rounded-r-full {
|
|
3051
3099
|
border-top-right-radius: 9999px;
|
|
3052
3100
|
border-bottom-right-radius: 9999px;
|
|
@@ -3094,6 +3142,10 @@ input[type=number] {
|
|
|
3094
3142
|
border-left-width: 1px;
|
|
3095
3143
|
}
|
|
3096
3144
|
|
|
3145
|
+
.border-r {
|
|
3146
|
+
border-right-width: 1px;
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3097
3149
|
.border-t {
|
|
3098
3150
|
border-top-width: 1px;
|
|
3099
3151
|
}
|
|
@@ -3359,6 +3411,16 @@ input[type=number] {
|
|
|
3359
3411
|
border-left-color: color-mix(in srgb, var(--input-color-error) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
3360
3412
|
}
|
|
3361
3413
|
|
|
3414
|
+
.border-r-input-default-stroke {
|
|
3415
|
+
--tw-border-opacity: 1;
|
|
3416
|
+
border-right-color: color-mix(in srgb, var(--input-color-default-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
3417
|
+
}
|
|
3418
|
+
|
|
3419
|
+
.border-r-input-error {
|
|
3420
|
+
--tw-border-opacity: 1;
|
|
3421
|
+
border-right-color: color-mix(in srgb, var(--input-color-error) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3362
3424
|
.border-t-secondary {
|
|
3363
3425
|
--tw-border-opacity: 1;
|
|
3364
3426
|
border-top-color: color-mix(in srgb, var(--state-color-secondary-default) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
@@ -4848,6 +4910,11 @@ input[type=number] {
|
|
|
4848
4910
|
background-color: color-mix(in srgb, var(--other-transparency-warning-8) calc(100% * var(--tw-bg-opacity, 1)), transparent);
|
|
4849
4911
|
}
|
|
4850
4912
|
|
|
4913
|
+
.bg-white {
|
|
4914
|
+
--tw-bg-opacity: 1;
|
|
4915
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
|
|
4916
|
+
}
|
|
4917
|
+
|
|
4851
4918
|
.bg-white-transparent-12 {
|
|
4852
4919
|
--tw-bg-opacity: 1;
|
|
4853
4920
|
background-color: color-mix(in srgb, var(--other-transparency-white-12) calc(100% * var(--tw-bg-opacity, 1)), transparent);
|
|
@@ -5504,6 +5571,10 @@ input[type=number] {
|
|
|
5504
5571
|
text-transform: capitalize;
|
|
5505
5572
|
}
|
|
5506
5573
|
|
|
5574
|
+
.leading-\[3rem\] {
|
|
5575
|
+
line-height: 3rem;
|
|
5576
|
+
}
|
|
5577
|
+
|
|
5507
5578
|
.leading-none {
|
|
5508
5579
|
line-height: 1;
|
|
5509
5580
|
}
|
|
@@ -7977,6 +8048,11 @@ input[type=number] {
|
|
|
7977
8048
|
border-left-color: color-mix(in srgb, var(--input-color-active-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
7978
8049
|
}
|
|
7979
8050
|
|
|
8051
|
+
.peer:hover ~ .peer-hover\:border-r-input-active-stroke {
|
|
8052
|
+
--tw-border-opacity: 1;
|
|
8053
|
+
border-right-color: color-mix(in srgb, var(--input-color-active-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
8054
|
+
}
|
|
8055
|
+
|
|
7980
8056
|
.peer:hover ~ .peer-hover\:fill-input-filled-text {
|
|
7981
8057
|
fill: color-mix(in srgb, var(--input-color-filled-text) calc(100% * 1), transparent);
|
|
7982
8058
|
}
|
|
@@ -8006,6 +8082,11 @@ input[type=number] {
|
|
|
8006
8082
|
border-left-color: color-mix(in srgb, var(--input-color-active-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
8007
8083
|
}
|
|
8008
8084
|
|
|
8085
|
+
.peer:focus ~ .peer-focus\:border-r-input-active-stroke {
|
|
8086
|
+
--tw-border-opacity: 1;
|
|
8087
|
+
border-right-color: color-mix(in srgb, var(--input-color-active-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
8088
|
+
}
|
|
8089
|
+
|
|
8009
8090
|
.peer:focus ~ .peer-focus\:bg-input-label-bg {
|
|
8010
8091
|
--tw-bg-opacity: 1;
|
|
8011
8092
|
background-color: color-mix(in srgb, var(--input-color-label-bg) calc(100% * var(--tw-bg-opacity, 1)), transparent);
|
|
@@ -8062,6 +8143,11 @@ input[type=number] {
|
|
|
8062
8143
|
border-left-color: color-mix(in srgb, var(--input-color-disable-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
8063
8144
|
}
|
|
8064
8145
|
|
|
8146
|
+
.peer:disabled ~ .peer-disabled\:border-r-input-disable-stroke {
|
|
8147
|
+
--tw-border-opacity: 1;
|
|
8148
|
+
border-right-color: color-mix(in srgb, var(--input-color-disable-stroke) calc(100% * var(--tw-border-opacity, 1)), transparent);
|
|
8149
|
+
}
|
|
8150
|
+
|
|
8065
8151
|
.peer:disabled ~ .peer-disabled\:fill-input-disable-stroke {
|
|
8066
8152
|
fill: color-mix(in srgb, var(--input-color-disable-stroke) calc(100% * 1), transparent);
|
|
8067
8153
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { FocusedScrollView } from "./FocusedScrollView";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof FocusedScrollView> = {
|
|
6
|
+
title: "Components/FocusedScrollView",
|
|
7
|
+
component: FocusedScrollView,
|
|
8
|
+
args: {
|
|
9
|
+
direction: "vertical",
|
|
10
|
+
scrollAlign: "center",
|
|
11
|
+
className: "border border-input-default-stroke rounded",
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
|
|
17
|
+
type Story = StoryObj<typeof FocusedScrollView>;
|
|
18
|
+
|
|
19
|
+
const items = Array.from({ length: 30 }, (_, i) => `Item ${i + 1}`);
|
|
20
|
+
|
|
21
|
+
export const VerticalScroll: Story = {
|
|
22
|
+
render: (args) => {
|
|
23
|
+
const [selected, setSelected] = useState("item-5");
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="p-6 space-y-4">
|
|
27
|
+
<div className="flex gap-2">
|
|
28
|
+
<button
|
|
29
|
+
onClick={() => setSelected("item-5")}
|
|
30
|
+
className="px-3 py-1 bg-primary text-white rounded"
|
|
31
|
+
>
|
|
32
|
+
Scroll to Item 5
|
|
33
|
+
</button>
|
|
34
|
+
<button
|
|
35
|
+
onClick={() => setSelected("item-20")}
|
|
36
|
+
className="px-3 py-1 bg-primary text-white rounded"
|
|
37
|
+
>
|
|
38
|
+
Scroll to Item 20
|
|
39
|
+
</button>
|
|
40
|
+
<button
|
|
41
|
+
onClick={() => setSelected("item-29")}
|
|
42
|
+
className="px-3 py-1 bg-primary text-white rounded"
|
|
43
|
+
>
|
|
44
|
+
Scroll to Item 30
|
|
45
|
+
</button>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<FocusedScrollView {...args} selectedKey={selected}>
|
|
49
|
+
{items.map((item, index) => (
|
|
50
|
+
<div
|
|
51
|
+
key={`item-${index + 1}`}
|
|
52
|
+
className={`px-4 py-2 ${
|
|
53
|
+
selected === `item-${index + 1}`
|
|
54
|
+
? "bg-secondary text-secondary-foreground"
|
|
55
|
+
: "bg-white"
|
|
56
|
+
}`}
|
|
57
|
+
>
|
|
58
|
+
{item}
|
|
59
|
+
</div>
|
|
60
|
+
))}
|
|
61
|
+
</FocusedScrollView>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const HorizontalScroll: Story = {
|
|
68
|
+
args: {
|
|
69
|
+
direction: "horizontal",
|
|
70
|
+
},
|
|
71
|
+
render: (args) => {
|
|
72
|
+
const [selected, setSelected] = useState("item-15");
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<div className="p-6 space-y-4">
|
|
76
|
+
<div className="flex gap-2">
|
|
77
|
+
<button
|
|
78
|
+
onClick={() => setSelected("item-5")}
|
|
79
|
+
className="px-3 py-1 bg-primary text-white rounded"
|
|
80
|
+
>
|
|
81
|
+
Scroll to Item 5
|
|
82
|
+
</button>
|
|
83
|
+
<button
|
|
84
|
+
onClick={() => setSelected("item-15")}
|
|
85
|
+
className="px-3 py-1 bg-primary text-white rounded"
|
|
86
|
+
>
|
|
87
|
+
Scroll to Item 15
|
|
88
|
+
</button>
|
|
89
|
+
<button
|
|
90
|
+
onClick={() => setSelected("item-25")}
|
|
91
|
+
className="px-3 py-1 bg-primary text-white rounded"
|
|
92
|
+
>
|
|
93
|
+
Scroll to Item 25
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<FocusedScrollView {...args} selectedKey={selected}>
|
|
98
|
+
{items.map((item, index) => (
|
|
99
|
+
<div
|
|
100
|
+
key={`item-${index + 1}`}
|
|
101
|
+
className={`inline-block w-28 h-12 mx-2 text-center leading-[3rem] rounded ${
|
|
102
|
+
selected === `item-${index + 1}`
|
|
103
|
+
? "bg-secondary text-secondary-foreground"
|
|
104
|
+
: "bg-gray-200"
|
|
105
|
+
}`}
|
|
106
|
+
>
|
|
107
|
+
{item}
|
|
108
|
+
</div>
|
|
109
|
+
))}
|
|
110
|
+
</FocusedScrollView>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
},
|
|
114
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
useRef,
|
|
3
|
+
useEffect,
|
|
4
|
+
cloneElement,
|
|
5
|
+
ReactNode,
|
|
6
|
+
isValidElement,
|
|
7
|
+
HTMLAttributes,
|
|
8
|
+
} from "react";
|
|
9
|
+
|
|
10
|
+
type ScrollAlign = "start" | "center" | "end";
|
|
11
|
+
|
|
12
|
+
type FocusedScrollViewProps = {
|
|
13
|
+
selectedKey?: string;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
direction?: "vertical" | "horizontal";
|
|
16
|
+
className?: string;
|
|
17
|
+
containerProps?: HTMLAttributes<HTMLDivElement>;
|
|
18
|
+
scrollAlign?: ScrollAlign;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const FocusedScrollView: React.FC<FocusedScrollViewProps> = ({
|
|
22
|
+
selectedKey,
|
|
23
|
+
children,
|
|
24
|
+
direction = "vertical",
|
|
25
|
+
className,
|
|
26
|
+
containerProps,
|
|
27
|
+
scrollAlign = "center",
|
|
28
|
+
}) => {
|
|
29
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
30
|
+
const itemRefs = useRef<Record<string, HTMLDivElement | null>>({});
|
|
31
|
+
|
|
32
|
+
const scrollToItem = (key: string) => {
|
|
33
|
+
const container = containerRef.current;
|
|
34
|
+
const item = itemRefs.current[key];
|
|
35
|
+
|
|
36
|
+
if (container && item) {
|
|
37
|
+
if (direction === "vertical") {
|
|
38
|
+
const containerTop = container.getBoundingClientRect().top;
|
|
39
|
+
const itemTop = item.getBoundingClientRect().top;
|
|
40
|
+
const offset = itemTop - containerTop + container.scrollTop;
|
|
41
|
+
|
|
42
|
+
const containerHeight = container.clientHeight;
|
|
43
|
+
const itemHeight = item.offsetHeight;
|
|
44
|
+
|
|
45
|
+
let targetTop = offset;
|
|
46
|
+
|
|
47
|
+
if (scrollAlign === "center") {
|
|
48
|
+
targetTop = offset - (containerHeight / 2 - itemHeight / 2);
|
|
49
|
+
} else if (scrollAlign === "end") {
|
|
50
|
+
targetTop = offset + (itemHeight - containerHeight);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
container.scrollTo({
|
|
54
|
+
top: targetTop,
|
|
55
|
+
behavior: "smooth",
|
|
56
|
+
});
|
|
57
|
+
} else if (direction === "horizontal") {
|
|
58
|
+
const containerLeft = container.getBoundingClientRect().left;
|
|
59
|
+
const itemLeft = item.getBoundingClientRect().left;
|
|
60
|
+
const offset = itemLeft - containerLeft + container.scrollLeft;
|
|
61
|
+
|
|
62
|
+
const containerWidth = container.clientWidth;
|
|
63
|
+
const itemWidth = item.offsetWidth;
|
|
64
|
+
|
|
65
|
+
let targetLeft = offset;
|
|
66
|
+
|
|
67
|
+
if (scrollAlign === "center") {
|
|
68
|
+
targetLeft = offset - (containerWidth / 2 - itemWidth / 2);
|
|
69
|
+
} else if (scrollAlign === "end") {
|
|
70
|
+
targetLeft = offset + (itemWidth - containerWidth);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
container.scrollTo({
|
|
74
|
+
left: targetLeft,
|
|
75
|
+
behavior: "smooth",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (selectedKey) {
|
|
83
|
+
scrollToItem(selectedKey);
|
|
84
|
+
}
|
|
85
|
+
}, [selectedKey, direction, scrollAlign]);
|
|
86
|
+
|
|
87
|
+
const enhancedChildren = Array.isArray(children)
|
|
88
|
+
? children.map((child) => {
|
|
89
|
+
if (isValidElement(child) && child.key) {
|
|
90
|
+
return cloneElement(child, {
|
|
91
|
+
// @ts-ignore
|
|
92
|
+
ref: (el: HTMLDivElement) => {
|
|
93
|
+
itemRefs.current[String(child.key)] = el;
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return child;
|
|
98
|
+
})
|
|
99
|
+
: children;
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<div
|
|
103
|
+
ref={containerRef}
|
|
104
|
+
className={`overflow-auto ${
|
|
105
|
+
direction === "vertical" ? "max-h-60" : "max-w-full whitespace-nowrap"
|
|
106
|
+
} ${className ?? ""}`}
|
|
107
|
+
{...containerProps}
|
|
108
|
+
>
|
|
109
|
+
{enhancedChildren}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
};
|