Skip to content

Commit 74e4cf6

Browse files
authored
Merge pull request #83 from kleros/chore/refactors-and-updates
Chore/refactors and updates
2 parents dde7171 + b1e282e commit 74e4cf6

File tree

13 files changed

+156
-24
lines changed

13 files changed

+156
-24
lines changed

src/lib/button/ButtonIcon.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@ const ButtonIcon: React.FC<
66
Pick<ButtonProps, "Icon" | "icon" | "isDisabled" | "isLoading" | "variant">
77
> = ({ Icon, icon, isDisabled, isLoading, variant }) => {
88
const isSecondary = variant === "secondary";
9-
return (
10-
icon ??
11-
(Icon && (
9+
return icon ? (
10+
isLoading ? (
11+
<span
12+
className={cn("button-svg", "mr-2 size-4", "invisible")}
13+
aria-hidden
14+
/>
15+
) : (
16+
icon
17+
)
18+
) : (
19+
Icon && (
1220
<Icon
1321
className={cn(
1422
"button-svg",
@@ -19,7 +27,7 @@ const ButtonIcon: React.FC<
1927
isDisabled && ["fill-klerosUIComponentsStroke"],
2028
)}
2129
/>
22-
))
30+
)
2331
);
2432
};
2533
export default ButtonIcon;

src/lib/dropdown/cascader/dropdown-container.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ interface IDropdownContainer
1919
"disabledKeys" | "defaultSelectedKey" | "items" | "callback"
2020
> {
2121
isOpen?: boolean;
22+
className?: string;
2223
}
2324

2425
const DropdownContainer: React.FC<IDropdownContainer> = ({
@@ -27,6 +28,7 @@ const DropdownContainer: React.FC<IDropdownContainer> = ({
2728
disabledKeys,
2829
defaultSelectedKey,
2930
callback,
31+
className,
3032
}) => {
3133
const gridRef = useRef<HTMLDivElement>(null);
3234
const [selectedKey, setSelectedKey] = useState<Key | null>(
@@ -78,17 +80,19 @@ const DropdownContainer: React.FC<IDropdownContainer> = ({
7880

7981
return (
8082
<Popover
81-
className={clsx(
83+
className={cn(
8284
"bg-klerosUIComponentsWhiteBackground rounded-base border-klerosUIComponentsStroke box-border border",
8385
"shadow-default focus-visible:outline-klerosUIComponentsPrimaryBlue overflow-hidden",
8486
"w-60 origin-top transform transition lg:w-max lg:max-w-6xl",
8587
isOpen
8688
? "entering:animate-scale-in scale-y-100"
8789
: "exiting:animate-scale-out scale-y-0",
90+
className,
8891
)}
8992
>
9093
<Dialog aria-label="dropdown-dialog">
9194
<Tree
95+
id="dropdown-tree"
9296
ref={gridRef}
9397
autoFocus="first"
9498
items={items}

src/lib/dropdown/cascader/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface IDropdownCascader extends AriaSelectProps {
1616
/** Callback function passes the Item object as argument. */
1717
callback: (item: IItem) => void;
1818
label?: string;
19+
dropdownClassName?: string;
1920
}
2021

2122
/** A Dropdown Cascader provides users with a way to navigate nested hierarchical information,
@@ -29,6 +30,7 @@ function DropdownCascader({
2930
disabledKeys,
3031
selectedKey,
3132
defaultSelectedKey,
33+
dropdownClassName,
3234
...props
3335
}: Readonly<IDropdownCascader>) {
3436
return (
@@ -56,6 +58,7 @@ function DropdownCascader({
5658
defaultSelectedKey: selectedKey ?? defaultSelectedKey,
5759
disabledKeys,
5860
callback,
61+
className: dropdownClassName,
5962
}}
6063
/>
6164
</>

src/lib/dropdown/select/dropdown-container.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,28 @@ import React from "react";
33
import { Collection, ListBox, Popover } from "react-aria-components";
44
import Scrollbar from "../../scrollbar";
55
import Item, { IItem } from "./item";
6+
import { cn } from "../../../utils";
67

7-
const DropdownContainer: React.FC<{ isOpen?: boolean; items: IItem[] }> = ({
8-
isOpen,
9-
items,
10-
}) => {
8+
const DropdownContainer: React.FC<{
9+
isOpen?: boolean;
10+
items: IItem[];
11+
className?: string;
12+
}> = ({ isOpen, items, className }) => {
1113
return (
1214
<Popover
13-
className={clsx(
15+
className={cn(
1416
"bg-klerosUIComponentsWhiteBackground rounded-base border-klerosUIComponentsStroke border",
1517
"shadow-default focus:outline-klerosUIComponentsPrimaryBlue box-border overflow-hidden outline-none",
1618
"origin-top transform transition",
1719
isOpen
1820
? "entering:animate-scale-in scale-y-100"
1921
: "exiting:animate-scale-out scale-y-0",
22+
className,
2023
)}
2124
>
2225
<Scrollbar className="max-h-87.5 w-59.5">
2326
<ListBox
27+
id="listbox"
2428
className={clsx(
2529
"bg-klerosUIComponentsWhiteBackground box-border w-59.5",
2630
"cols-[repeat(auto-fill,_minmax(0,_45px))] grid grow py-4",

src/lib/dropdown/select/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface SelectProps extends AriaSelectProps {
2121
/** When `simpleButton` is `true`, this scales down the dropdown button size. */
2222
smallButton?: boolean;
2323
label?: string;
24+
dropdownClassName?: string;
2425
}
2526

2627
/** A select displays a collapsible list of options and allows a user to select one of them. */
@@ -32,6 +33,7 @@ function DropdownSelect({
3233
callback,
3334
placeholder,
3435
className,
36+
dropdownClassName,
3537
...props
3638
}: Readonly<SelectProps>) {
3739
const handleSelection = useCallback(
@@ -64,7 +66,9 @@ function DropdownSelect({
6466
<DropdownButton {...{ placeholder }} />
6567
)}
6668
<FieldError className="text-klerosUIComponentsError text-sm" />
67-
<DropdownContainer {...{ isOpen, items }} />
69+
<DropdownContainer
70+
{...{ isOpen, items, className: dropdownClassName }}
71+
/>
6872
</>
6973
)}
7074
</AriaSelect>

src/lib/form/bignumber-field/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ interface BigNumberFieldComponentProps extends BigNumberFieldProps {
1717
className?: string;
1818
/** The name of the input element, used when submitting an HTML form.*/
1919
name?: string;
20+
inputRef?: React.Ref<HTMLInputElement>;
21+
buttonRef?: React.Ref<HTMLButtonElement>;
2022
}
2123

2224
/** A number field that handles big numbers.
@@ -31,6 +33,8 @@ function BigNumberField({
3133
isDisabled,
3234
isReadOnly,
3335
name,
36+
inputRef,
37+
buttonRef,
3438
...props
3539
}: Readonly<BigNumberFieldComponentProps>) {
3640
// Use our custom hook to get all the props and state
@@ -44,7 +48,6 @@ function BigNumberField({
4448
errorMessageProps,
4549
validationResult,
4650
} = useBigNumberField({ isDisabled, placeholder, isReadOnly, ...props });
47-
4851
return (
4952
<div className={cn("flex w-[278px] flex-col", className)}>
5053
{label && (
@@ -64,6 +67,7 @@ function BigNumberField({
6467
<>
6568
<Input
6669
{...inputProps}
70+
ref={inputRef}
6771
aria-errormessage={`BigNumberFieldError-${inputProps.id}`}
6872
name={name}
6973
className={cn(
@@ -98,6 +102,7 @@ function BigNumberField({
98102
>
99103
<Button
100104
{...incrementButtonProps}
105+
ref={buttonRef}
101106
excludeFromTabOrder
102107
className={clsx(
103108
"rounded-base hover:bg-klerosUIComponentsStroke size-3.5 cursor-pointer border-none bg-transparent",

src/lib/form/datepicker/index.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ interface DatePickerProps
2525
/** Show time selection if true. */
2626
time?: boolean;
2727
label?: string;
28+
popoverClassName?: string;
2829
}
2930

3031
/** A date picker allow users to enter or select a date and time value. */
@@ -34,6 +35,7 @@ function DatePicker({
3435
minValue,
3536
defaultValue = now(getLocalTimeZone()),
3637
shouldCloseOnSelect = false,
38+
popoverClassName,
3739
...props
3840
}: Readonly<DatePickerProps>) {
3941
return (
@@ -59,14 +61,20 @@ function DatePicker({
5961

6062
<Popover
6163
className={clsx(
62-
"bg-klerosUIComponentsWhiteBackground shadow-default rounded-base overflow-y-scroll",
64+
"bg-klerosUIComponentsWhiteBackground shadow-default rounded-base overflow-scroll",
6365
"border-klerosUIComponentsStroke ease-ease scrollbar border transition",
6466
time ? "w-82.5 lg:w-112.5" : "w-82.5",
67+
popoverClassName,
6568
)}
6669
>
6770
<Dialog className="flex size-full flex-wrap">
68-
<Calendar />
69-
{time && <TimeControl {...{ minValue }} />}
71+
<div
72+
className={clsx("flex", time ? "w-82.5 lg:w-112.5" : "w-82.5")}
73+
>
74+
<Calendar />
75+
{time && <TimeControl {...{ minValue }} />}
76+
</div>
77+
7078
<div
7179
className={clsx(
7280
"flex h-16 w-full items-center justify-between px-4",

src/lib/form/file-uploader.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react";
1+
import React, { useEffect, useState } from "react";
22
import UploadIcon from "../../assets/svgs/form/upload-icon.svg";
33
import SuccessIcon from "../../assets/svgs/status-icons/success.svg";
44
import ErrorIcon from "../../assets/svgs/status-icons/error.svg";
@@ -25,6 +25,10 @@ interface FileUploaderProps {
2525
/** Whether the drop target is disabled. If true, the drop target will not accept any drops. */
2626
isDisabled?: boolean;
2727
className?: string;
28+
/** Provide a custom validation function, returning false invalidates the file */
29+
validationFunction?: (file?: File) => boolean;
30+
/** Provide File for controlled behaviour */
31+
selectedFile?: File;
2832
}
2933

3034
/** Allows to upload a file by either dropping it on the dropzone or
@@ -37,8 +41,16 @@ function FileUploader({
3741
acceptedFileTypes,
3842
fileTriggerProps,
3943
isDisabled = false,
44+
validationFunction,
45+
selectedFile,
4046
}: Readonly<FileUploaderProps>) {
41-
const [fileSelected, setFileSelected] = useState<File>();
47+
const [fileSelected, setFileSelected] = useState<File | undefined>(
48+
selectedFile,
49+
);
50+
51+
useEffect(() => {
52+
setFileSelected(selectedFile);
53+
}, [selectedFile]);
4254

4355
return (
4456
<div className={cn("box-border h-fit w-50", className)}>
@@ -71,7 +83,10 @@ function FileUploader({
7183

7284
if (item) {
7385
const file = await item.getFile();
74-
setFileSelected(file);
86+
const validated = validationFunction?.(file) ?? true;
87+
if (!validated) return;
88+
if (selectedFile === undefined) setFileSelected(file);
89+
7590
callback(file);
7691
}
7792
}}
@@ -82,7 +97,9 @@ function FileUploader({
8297
onSelect={(e) => {
8398
if (e) {
8499
const file = e[0];
85-
setFileSelected(file);
100+
const validated = validationFunction?.(file) ?? true;
101+
if (!validated) return;
102+
if (selectedFile === undefined) setFileSelected(file);
86103
callback(file);
87104
}
88105
}}
@@ -109,7 +126,7 @@ function FileUploader({
109126
</FileTrigger>
110127
</DropZone>
111128
{msg && (
112-
<div className="mt-4 flex items-start">
129+
<div className="mt-4 flex items-center">
113130
{variant === "success" && (
114131
<SuccessIcon className="fill-klerosUIComponentsSuccess mr-2 max-w-4 min-w-4" />
115132
)}

src/lib/progress/timeline/custom.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22
import Bullet, { StateProp, VariantProp } from "./bullet";
33
import { cn } from "../../../utils";
44

5-
interface TimelineItem extends VariantProp, StateProp {
5+
export interface TimelineItem extends VariantProp, StateProp {
66
title: string;
77
party: string | React.ReactElement;
88
subtitle: string;

src/lib/progress/timeline/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import Bullet, { SideProp, VariantProp } from "./bullet";
33
import clsx from "clsx";
44
import { cn } from "../../../utils";
55

6-
interface TimelineItem extends SideProp, VariantProp {
6+
export interface TimelineItem extends SideProp, VariantProp {
77
title: string;
88
party: string;
99
subtitle: string;
1010
}
1111

12-
interface TimelineProps {
12+
export interface TimelineProps {
1313
items: [TimelineItem, ...TimelineItem[]];
1414
className?: string;
1515
}

0 commit comments

Comments
 (0)