untitledui 0.1.5 → 0.1.8
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/config/postcss.config.mjs +6 -0
- package/{templates/default/src → config}/styles/globals.css +2 -33
- package/{templates/default/src → config}/styles/theme.css +31 -33
- package/{templates/default/src → config}/styles/typography.css +24 -24
- package/dist/index.mjs +54 -15
- package/package.json +4 -3
- package/templates/default/.prettierrc +0 -10
- package/templates/default/README.md +0 -36
- package/templates/default/eslint.config.mjs +0 -58
- package/templates/default/next.config.ts +0 -6
- package/templates/default/package.json +0 -56
- package/templates/default/postcss.config.js +0 -5
- package/templates/default/public/favicon.ico +0 -0
- package/templates/default/public/marketing/smiling-girl.png +0 -0
- package/templates/default/public/marketing/spirals.webp +0 -0
- package/templates/default/src/app/home-screen.tsx +0 -108
- package/templates/default/src/app/layout.tsx +0 -34
- package/templates/default/src/app/not-found.tsx +0 -40
- package/templates/default/src/app/page.tsx +0 -3
- package/templates/default/src/components/foundations/dot-icon.tsx +0 -27
- package/templates/default/src/components/foundations/featured-icon/featured-icons.tsx +0 -153
- package/templates/default/src/components/foundations/logo/UntitledLogo.tsx +0 -63
- package/templates/default/src/components/foundations/logo/UntitledLogoMinimal.tsx +0 -164
- package/templates/default/src/components/foundations/payment-icons/amex-icon.tsx +0 -19
- package/templates/default/src/components/foundations/payment-icons/apple-pay-icon.tsx +0 -27
- package/templates/default/src/components/foundations/payment-icons/discover-icon.tsx +0 -34
- package/templates/default/src/components/foundations/payment-icons/index.tsx +0 -10
- package/templates/default/src/components/foundations/payment-icons/mastercard-icon.tsx +0 -39
- package/templates/default/src/components/foundations/payment-icons/paypal-icon.tsx +0 -45
- package/templates/default/src/components/foundations/payment-icons/stripe-icon.tsx +0 -27
- package/templates/default/src/components/foundations/payment-icons/union-pay-icon.tsx +0 -37
- package/templates/default/src/components/foundations/payment-icons/visa-icon.tsx +0 -27
- package/templates/default/src/components/marketing/header-navigation/base-components/nav-menu-item.tsx +0 -41
- package/templates/default/src/components/marketing/header-navigation/components/header.tsx +0 -245
- package/templates/default/src/components/marketing/header-navigation/dropdown-header-navigation.tsx +0 -53
- package/templates/default/src/components/shared/avatar/avatar-label-group.tsx +0 -32
- package/templates/default/src/components/shared/avatar/avatar-profile-photo.tsx +0 -84
- package/templates/default/src/components/shared/avatar/avatar.tsx +0 -131
- package/templates/default/src/components/shared/avatar/base-components/avatar-add-button.tsx +0 -33
- package/templates/default/src/components/shared/avatar/base-components/avatar-company-icon.tsx +0 -26
- package/templates/default/src/components/shared/avatar/base-components/avatar-online-indicator.tsx +0 -31
- package/templates/default/src/components/shared/avatar/base-components/index.ts +0 -4
- package/templates/default/src/components/shared/avatar/base-components/verified-tick.tsx +0 -34
- package/templates/default/src/components/shared/avatar/utils.ts +0 -12
- package/templates/default/src/components/shared/badges/badge-groups.tsx +0 -176
- package/templates/default/src/components/shared/badges/badge-types.ts +0 -264
- package/templates/default/src/components/shared/badges/badges.tsx +0 -479
- package/templates/default/src/components/shared/button-group/button-group.tsx +0 -97
- package/templates/default/src/components/shared/buttons/app-store-buttons-outline.tsx +0 -454
- package/templates/default/src/components/shared/buttons/app-store-buttons.tsx +0 -806
- package/templates/default/src/components/shared/buttons/button-utility.tsx +0 -87
- package/templates/default/src/components/shared/buttons/button.tsx +0 -285
- package/templates/default/src/components/shared/buttons/close-button.tsx +0 -39
- package/templates/default/src/components/shared/buttons/social-button.tsx +0 -135
- package/templates/default/src/components/shared/buttons/social-logos.tsx +0 -115
- package/templates/default/src/components/shared/checkbox/checkbox.tsx +0 -120
- package/templates/default/src/components/shared/dropdown/dropdown.tsx +0 -147
- package/templates/default/src/components/shared/file-upload-trigger/file-upload-trigger.tsx +0 -74
- package/templates/default/src/components/shared/form/form.tsx +0 -10
- package/templates/default/src/components/shared/form/hook-form.tsx +0 -75
- package/templates/default/src/components/shared/input/hint-text.tsx +0 -34
- package/templates/default/src/components/shared/input/index.tsx +0 -189
- package/templates/default/src/components/shared/input/input-payment.tsx +0 -134
- package/templates/default/src/components/shared/input/input-with-button.tsx +0 -69
- package/templates/default/src/components/shared/input/input-with-dropdown.tsx +0 -178
- package/templates/default/src/components/shared/input/input-with-prefix.tsx +0 -74
- package/templates/default/src/components/shared/input/label.tsx +0 -46
- package/templates/default/src/components/shared/progress-indicators/progress-circles.tsx +0 -176
- package/templates/default/src/components/shared/progress-indicators/progress-indicators.tsx +0 -86
- package/templates/default/src/components/shared/progress-indicators/simple-circle.tsx +0 -29
- package/templates/default/src/components/shared/radio-buttons/radio-buttons.tsx +0 -125
- package/templates/default/src/components/shared/radio-groups/radio-group-avatar.tsx +0 -62
- package/templates/default/src/components/shared/radio-groups/radio-group-checkbox.tsx +0 -72
- package/templates/default/src/components/shared/radio-groups/radio-group-icon-card.tsx +0 -95
- package/templates/default/src/components/shared/radio-groups/radio-group-icon-simple.tsx +0 -70
- package/templates/default/src/components/shared/radio-groups/radio-group-payment-icon.tsx +0 -71
- package/templates/default/src/components/shared/radio-groups/radio-group-radio-button.tsx +0 -76
- package/templates/default/src/components/shared/radio-groups/radio-groups.tsx +0 -8
- package/templates/default/src/components/shared/select/combobox.tsx +0 -161
- package/templates/default/src/components/shared/select/multi-select.tsx +0 -373
- package/templates/default/src/components/shared/select/popover.tsx +0 -36
- package/templates/default/src/components/shared/select/select-item.tsx +0 -70
- package/templates/default/src/components/shared/select/select-native.tsx +0 -63
- package/templates/default/src/components/shared/select/select.tsx +0 -143
- package/templates/default/src/components/shared/slider/slider.tsx +0 -76
- package/templates/default/src/components/shared/tags/base-components/tag-checkbox.tsx +0 -47
- package/templates/default/src/components/shared/tags/base-components/tag-close-x.tsx +0 -34
- package/templates/default/src/components/shared/tags/tags.tsx +0 -162
- package/templates/default/src/components/shared/textarea/textarea.tsx +0 -82
- package/templates/default/src/components/shared/toggle/toggle.tsx +0 -140
- package/templates/default/src/components/shared/tooltips/tooltips.tsx +0 -140
- package/templates/default/src/components/utils/index.ts +0 -48
- package/templates/default/src/components/utils/isDeepEqual.ts +0 -31
- package/templates/default/src/components/utils/isReactComponent.ts +0 -22
- package/templates/default/src/components/utils/mergeRefs.ts +0 -19
- package/templates/default/src/components/utils/useBreakpoint.ts +0 -36
- package/templates/default/src/components/utils/uuid.ts +0 -9
- package/templates/default/src/hooks/use-resize-observer.tsx +0 -55
- package/templates/default/src/providers/theme.tsx +0 -11
- package/templates/default/src/styles/text-styles.css +0 -177
- package/templates/default/tsconfig.json +0 -27
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { cx } from "@/components/utils/cx";
|
|
4
|
-
|
|
5
|
-
export interface ProgressBarProps {
|
|
6
|
-
value: number;
|
|
7
|
-
min?: number;
|
|
8
|
-
max?: number;
|
|
9
|
-
className?: string;
|
|
10
|
-
progressClassName?: string;
|
|
11
|
-
valueFormatter?: (value: number, valueInPercentage: number) => string | number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const ProgressBar = ({ value, min = 0, max = 100, className, progressClassName }: ProgressBarProps) => {
|
|
15
|
-
const percentage = ((value - min) * 100) / (max - min);
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div
|
|
19
|
-
role="progressbar"
|
|
20
|
-
aria-valuenow={value}
|
|
21
|
-
aria-valuemin={min}
|
|
22
|
-
aria-valuemax={max}
|
|
23
|
-
className={cx("h-2 w-full overflow-hidden rounded-md bg-quaternary", className)}
|
|
24
|
-
>
|
|
25
|
-
<div
|
|
26
|
-
// Use transform instead of width to avoid layout thrashing (and for smoother animation)
|
|
27
|
-
style={{ transform: `translateX(-${100 - percentage}%)` }}
|
|
28
|
-
className={cx("size-full rounded-md bg-fg-brand-primary transition duration-75 ease-linear", progressClassName)}
|
|
29
|
-
/>
|
|
30
|
-
</div>
|
|
31
|
-
);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const ProgressBarTextRight = ({ value, min = 0, max = 100, valueFormatter }: ProgressBarProps) => {
|
|
35
|
-
const percentage = ((value - min) * 100) / (max - min);
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className="flex items-center gap-3">
|
|
39
|
-
<ProgressBar min={min} max={max} value={value} />
|
|
40
|
-
<span className="tt-sm-md text-secondary tabular-nums">{valueFormatter ? valueFormatter(value, percentage) : `${percentage}%`}</span>
|
|
41
|
-
</div>
|
|
42
|
-
);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const ProgressBarTextBottom = ({ value, min = 0, max = 100, valueFormatter }: ProgressBarProps) => {
|
|
46
|
-
const percentage = ((value - min) * 100) / (max - min);
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<div className="flex flex-col items-end gap-2">
|
|
50
|
-
<ProgressBar min={min} max={max} value={value} />
|
|
51
|
-
<span className="tt-sm-md text-secondary tabular-nums">{valueFormatter ? valueFormatter(value, percentage) : `${percentage}%`}</span>
|
|
52
|
-
</div>
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export const ProgressBarTextTopFloating = ({ value, min = 0, max = 100, valueFormatter }: ProgressBarProps) => {
|
|
57
|
-
const percentage = ((value - min) * 100) / (max - min);
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<div className="relative flex flex-col items-end gap-2">
|
|
61
|
-
<ProgressBar min={min} max={max} value={value} />
|
|
62
|
-
<div
|
|
63
|
-
style={{ left: `${percentage}%` }}
|
|
64
|
-
className="absolute -top-2 -translate-x-1/2 -translate-y-full rounded-lg bg-primary_alt px-3 py-2 shadow-lg ring-1 ring-border-secondary_alt"
|
|
65
|
-
>
|
|
66
|
-
<div className="tt-xs-semi text-secondary tabular-nums">{valueFormatter ? valueFormatter(value, percentage) : `${percentage}%`}</div>
|
|
67
|
-
</div>
|
|
68
|
-
</div>
|
|
69
|
-
);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export const ProgressBarTextBottomFloating = ({ value, min = 0, max = 100, valueFormatter }: ProgressBarProps) => {
|
|
73
|
-
const percentage = ((value - min) * 100) / (max - min);
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<div className="relative flex flex-col items-end gap-2">
|
|
77
|
-
<ProgressBar min={min} max={max} value={value} />
|
|
78
|
-
<div
|
|
79
|
-
style={{ left: `${percentage}%` }}
|
|
80
|
-
className="absolute -bottom-2 -translate-x-1/2 translate-y-full rounded-lg bg-primary_alt px-3 py-2 shadow-lg ring-1 ring-border-secondary_alt"
|
|
81
|
-
>
|
|
82
|
-
<div className="tt-xs-semi text-secondary">{valueFormatter ? valueFormatter(value, percentage) : `${percentage}%`}</div>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
const CircleProgressBar = (props: { value: number; min?: 0; max?: 100 }) => {
|
|
4
|
-
const { value, min = 0, max = 100 } = props;
|
|
5
|
-
const percentage = ((value - min) * 100) / (max - min);
|
|
6
|
-
|
|
7
|
-
return (
|
|
8
|
-
<div role="progressbar" aria-valuenow={value} aria-valuemin={min} aria-valuemax={max} className="relative flex w-max items-center justify-center">
|
|
9
|
-
<span className="absolute tt-sm-md text-primary">{percentage}%</span>
|
|
10
|
-
<svg className="size-16 -rotate-90" viewBox="0 0 60 60">
|
|
11
|
-
<circle className="stroke-bg-quaternary" cx="30" cy="30" r="26" fill="none" strokeWidth="6" />
|
|
12
|
-
<circle
|
|
13
|
-
className="stroke-fg-brand-primary"
|
|
14
|
-
style={{
|
|
15
|
-
strokeDashoffset: `calc(100 - ${percentage})`,
|
|
16
|
-
}}
|
|
17
|
-
cx="30"
|
|
18
|
-
cy="30"
|
|
19
|
-
r="26"
|
|
20
|
-
fill="none"
|
|
21
|
-
strokeWidth="6"
|
|
22
|
-
strokeDasharray="100"
|
|
23
|
-
pathLength="100"
|
|
24
|
-
strokeLinecap="round"
|
|
25
|
-
/>
|
|
26
|
-
</svg>
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
29
|
-
};
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { type ReactNode, type Ref, createContext, useContext } from "react";
|
|
4
|
-
import type { RadioGroupProps as AriaRadioGroupProps } from "react-aria-components";
|
|
5
|
-
import { type RadioProps as AriaRadioProps, Radio, RadioGroup } from "react-aria-components";
|
|
6
|
-
import { cx } from "@/components/utils/cx";
|
|
7
|
-
|
|
8
|
-
export interface RadioButtonGroupContextType {
|
|
9
|
-
size?: "sm" | "md";
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const RadioButtonGroupContext = createContext<RadioButtonGroupContextType | null>(null);
|
|
13
|
-
|
|
14
|
-
export interface RadioButtonBaseProps {
|
|
15
|
-
size?: "sm" | "md";
|
|
16
|
-
className?: string;
|
|
17
|
-
isFocused?: boolean;
|
|
18
|
-
isSelected?: boolean;
|
|
19
|
-
isDisabled?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const RadioButtonBase = ({ className, isFocused, isSelected, isDisabled, size = "sm" }: RadioButtonBaseProps) => {
|
|
23
|
-
return (
|
|
24
|
-
<div
|
|
25
|
-
className={cx(
|
|
26
|
-
"flex size-4 min-h-4 min-w-4 cursor-pointer appearance-none items-center justify-center rounded-full bg-primary ring-1 ring-border-primary ring-inset",
|
|
27
|
-
size === "md" && "size-5 min-h-5 min-w-5",
|
|
28
|
-
isSelected && !isDisabled && "bg-brand-solid ring-bg-brand-solid",
|
|
29
|
-
isDisabled && "cursor-not-allowed border-disabled bg-disabled_subtle",
|
|
30
|
-
isFocused && "outline-2 outline-offset-2 outline-focus-ring",
|
|
31
|
-
className,
|
|
32
|
-
)}
|
|
33
|
-
>
|
|
34
|
-
<div
|
|
35
|
-
className={cx(
|
|
36
|
-
"size-1.5 rounded-full bg-fg-white opacity-0 transition-inherit-all",
|
|
37
|
-
size === "md" && "size-2",
|
|
38
|
-
isDisabled && "bg-fg-disabled_subtle",
|
|
39
|
-
isSelected && "opacity-100",
|
|
40
|
-
)}
|
|
41
|
-
/>
|
|
42
|
-
</div>
|
|
43
|
-
);
|
|
44
|
-
};
|
|
45
|
-
RadioButtonBase.displayName = "RadioButtonBase";
|
|
46
|
-
|
|
47
|
-
interface RadioButtonProps extends AriaRadioProps {
|
|
48
|
-
size?: "sm" | "md";
|
|
49
|
-
label?: ReactNode;
|
|
50
|
-
hint?: ReactNode;
|
|
51
|
-
ref?: Ref<HTMLLabelElement>;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const RadioButton = ({ label, hint, className, size = "sm", ...ariaRadioProps }: RadioButtonProps) => {
|
|
55
|
-
const context = useContext(RadioButtonGroupContext);
|
|
56
|
-
|
|
57
|
-
size = context?.size ?? size;
|
|
58
|
-
|
|
59
|
-
const sizes = {
|
|
60
|
-
sm: {
|
|
61
|
-
root: "gap-2",
|
|
62
|
-
textWrapper: "",
|
|
63
|
-
label: "tt-sm-md",
|
|
64
|
-
hint: "tt-sm",
|
|
65
|
-
},
|
|
66
|
-
md: {
|
|
67
|
-
root: "gap-3",
|
|
68
|
-
textWrapper: "gap-0.5",
|
|
69
|
-
label: "tt-md-md",
|
|
70
|
-
hint: "tt-md",
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Radio
|
|
76
|
-
{...ariaRadioProps}
|
|
77
|
-
className={(renderProps) =>
|
|
78
|
-
cx(
|
|
79
|
-
"flex items-start",
|
|
80
|
-
renderProps.isDisabled && "cursor-not-allowed",
|
|
81
|
-
sizes[size].root,
|
|
82
|
-
typeof className === "function" ? className(renderProps) : className,
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
>
|
|
86
|
-
{({ isSelected, isDisabled, isFocused }) => (
|
|
87
|
-
<>
|
|
88
|
-
<RadioButtonBase
|
|
89
|
-
size={size}
|
|
90
|
-
isSelected={isSelected}
|
|
91
|
-
isDisabled={isDisabled}
|
|
92
|
-
isFocused={isFocused}
|
|
93
|
-
className={label || hint ? "mt-0.5" : ""}
|
|
94
|
-
/>
|
|
95
|
-
{(label || hint) && (
|
|
96
|
-
<div className={cx("inline-flex flex-col", sizes[size].textWrapper)}>
|
|
97
|
-
{label && <p className={cx("text-secondary select-none", sizes[size].label)}>{label}</p>}
|
|
98
|
-
{hint && (
|
|
99
|
-
<span className={cx("pointer-events-none text-tertiary", sizes[size].hint)} onClick={(event) => event.stopPropagation()}>
|
|
100
|
-
{hint}
|
|
101
|
-
</span>
|
|
102
|
-
)}
|
|
103
|
-
</div>
|
|
104
|
-
)}
|
|
105
|
-
</>
|
|
106
|
-
)}
|
|
107
|
-
</Radio>
|
|
108
|
-
);
|
|
109
|
-
};
|
|
110
|
-
RadioButton.displayName = "Checkbox";
|
|
111
|
-
|
|
112
|
-
interface RadioButtonGroupProps extends RadioButtonGroupContextType, AriaRadioGroupProps {
|
|
113
|
-
children: ReactNode;
|
|
114
|
-
className?: string;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export const RadioButtonGroup = ({ children, className, size = "sm", ...props }: RadioButtonGroupProps) => {
|
|
118
|
-
return (
|
|
119
|
-
<RadioButtonGroupContext.Provider value={{ size }}>
|
|
120
|
-
<RadioGroup {...props} className={cx("flex flex-col gap-4", className)}>
|
|
121
|
-
{children}
|
|
122
|
-
</RadioGroup>
|
|
123
|
-
</RadioButtonGroupContext.Provider>
|
|
124
|
-
);
|
|
125
|
-
};
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { RadioGroupProps } from "react-aria-components";
|
|
4
|
-
import { Label, Radio, RadioGroup, Text } from "react-aria-components";
|
|
5
|
-
import AvatarComponent from "@/components/shared/avatar/avatar";
|
|
6
|
-
import { CheckboxBase } from "@/components/shared/checkbox/checkbox";
|
|
7
|
-
import { cx } from "@/components/utils/cx";
|
|
8
|
-
|
|
9
|
-
interface AvatarItemType {
|
|
10
|
-
id: string;
|
|
11
|
-
name: string;
|
|
12
|
-
username: string;
|
|
13
|
-
title: string;
|
|
14
|
-
avatarUrl: string;
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface RadioGroupAvatarProps extends RadioGroupProps {
|
|
19
|
-
size?: "sm" | "md";
|
|
20
|
-
items: AvatarItemType[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const RadioGroupAvatar = ({ items, size = "sm", className, ...props }: RadioGroupAvatarProps) => {
|
|
24
|
-
return (
|
|
25
|
-
<RadioGroup {...props} className={(states) => cx("flex flex-col gap-3", typeof className === "function" ? className(states) : className)}>
|
|
26
|
-
{items.map((person) => (
|
|
27
|
-
<Radio
|
|
28
|
-
isDisabled={person.disabled}
|
|
29
|
-
key={person.id}
|
|
30
|
-
value={person.id}
|
|
31
|
-
className={({ isDisabled, isSelected, isFocusVisible }) =>
|
|
32
|
-
cx(
|
|
33
|
-
"relative flex cursor-pointer items-start gap-1 rounded-xl bg-primary p-4 transition duration-100 ring-inset",
|
|
34
|
-
isSelected ? "ring-2 ring-border-brand" : "ring-1 ring-border-secondary",
|
|
35
|
-
isDisabled && "cursor-not-allowed bg-disabled_subtle ring-border-disabled_subtle",
|
|
36
|
-
isFocusVisible && "outline-2 outline-offset-2 outline-focus-ring",
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
>
|
|
40
|
-
{({ isDisabled, isSelected, isFocusVisible }) => (
|
|
41
|
-
<>
|
|
42
|
-
<div className={cx("flex flex-1", size === "md" ? "gap-3 md:gap-4" : "gap-3")}>
|
|
43
|
-
<AvatarComponent alt={person.name} src={person.avatarUrl} size={size === "md" ? "md" : "sm"} />
|
|
44
|
-
|
|
45
|
-
<div className={cx("flex flex-col", size === "md" ? "gap-0.5" : "")}>
|
|
46
|
-
<Label className={cx("pointer-events-none flex", size === "md" ? "gap-1.5" : "gap-1")}>
|
|
47
|
-
<span className={cx("text-secondary", size === "md" ? "tt-md-md" : "tt-sm-md")}>{person.name}</span>
|
|
48
|
-
<span className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>{person.username}</span>
|
|
49
|
-
</Label>
|
|
50
|
-
<Text slot="description" className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>
|
|
51
|
-
{person.title}
|
|
52
|
-
</Text>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
<CheckboxBase size={size === "md" ? "md" : "sm"} isDisabled={isDisabled} isSelected={isSelected} isFocused={isFocusVisible} />
|
|
56
|
-
</>
|
|
57
|
-
)}
|
|
58
|
-
</Radio>
|
|
59
|
-
))}
|
|
60
|
-
</RadioGroup>
|
|
61
|
-
);
|
|
62
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { FC } from "react";
|
|
4
|
-
import type { RadioGroupProps } from "react-aria-components";
|
|
5
|
-
import { Label, Radio, RadioGroup, Text } from "react-aria-components";
|
|
6
|
-
import { CheckboxBase } from "@/components/shared/checkbox/checkbox";
|
|
7
|
-
import { cx } from "@/components/utils/cx";
|
|
8
|
-
|
|
9
|
-
type RadioGroupItemType = {
|
|
10
|
-
value: string;
|
|
11
|
-
title: string;
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
description: string;
|
|
14
|
-
secondaryTitle: string;
|
|
15
|
-
icon: FC<{ className?: string }>;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
interface RadioGroupCheckboxProps extends RadioGroupProps {
|
|
19
|
-
size?: "sm" | "md";
|
|
20
|
-
items: RadioGroupItemType[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const RadioGroupCheckbox = ({ items, size = "sm", className, ...props }: RadioGroupCheckboxProps) => {
|
|
24
|
-
return (
|
|
25
|
-
<RadioGroup {...props} className={(states) => cx("flex flex-col gap-3", typeof className === "function" ? className(states) : className)}>
|
|
26
|
-
{items.map((plan) => (
|
|
27
|
-
<Radio
|
|
28
|
-
isDisabled={plan.disabled}
|
|
29
|
-
key={plan.value}
|
|
30
|
-
value={plan.value}
|
|
31
|
-
className={({ isDisabled, isFocusVisible, isSelected }) =>
|
|
32
|
-
cx(
|
|
33
|
-
"relative flex cursor-pointer items-start gap-1 rounded-xl bg-primary p-4 transition duration-100 ring-inset",
|
|
34
|
-
size === "md" ? "gap-3" : "gap-2",
|
|
35
|
-
isSelected ? "ring-2 ring-border-brand" : "ring-1 ring-border-secondary",
|
|
36
|
-
isDisabled && "cursor-not-allowed bg-disabled_subtle ring-border-disabled_subtle",
|
|
37
|
-
isFocusVisible && "outline-2 outline-offset-2 outline-focus-ring",
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
>
|
|
41
|
-
{({ isDisabled, isSelected, isFocusVisible }) => (
|
|
42
|
-
<>
|
|
43
|
-
<CheckboxBase
|
|
44
|
-
size={size === "md" ? "md" : "sm"}
|
|
45
|
-
isDisabled={isDisabled}
|
|
46
|
-
isSelected={isSelected}
|
|
47
|
-
isFocused={isFocusVisible}
|
|
48
|
-
className="mt-0.5"
|
|
49
|
-
/>
|
|
50
|
-
|
|
51
|
-
<div
|
|
52
|
-
className={cx(
|
|
53
|
-
"flex flex-col",
|
|
54
|
-
|
|
55
|
-
size === "md" ? "gap-0.5" : "",
|
|
56
|
-
)}
|
|
57
|
-
>
|
|
58
|
-
<Label className={cx("pointer-events-none flex", size === "md" ? "gap-1.5" : "gap-1")}>
|
|
59
|
-
<span className={cx("text-secondary", size === "md" ? "tt-md-md" : "tt-sm-md")}>{plan.title}</span>
|
|
60
|
-
<span className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>{plan.secondaryTitle}</span>
|
|
61
|
-
</Label>
|
|
62
|
-
<Text slot="description" className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>
|
|
63
|
-
{plan.description}
|
|
64
|
-
</Text>
|
|
65
|
-
</div>
|
|
66
|
-
</>
|
|
67
|
-
)}
|
|
68
|
-
</Radio>
|
|
69
|
-
))}
|
|
70
|
-
</RadioGroup>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { FC, ReactNode } from "react";
|
|
4
|
-
import type { RadioGroupProps } from "react-aria-components";
|
|
5
|
-
import { Radio, RadioGroup } from "react-aria-components";
|
|
6
|
-
import { FeaturedIcon } from "@/components/foundations/featured-icon/featured-icons";
|
|
7
|
-
import { BadgeWithDot } from "@/components/shared/badges/badges";
|
|
8
|
-
import { CheckboxBase } from "@/components/shared/checkbox/checkbox";
|
|
9
|
-
import { cx } from "@/components/utils/cx";
|
|
10
|
-
|
|
11
|
-
type IconCardItemType = {
|
|
12
|
-
value: string;
|
|
13
|
-
title: string;
|
|
14
|
-
description: string;
|
|
15
|
-
secondaryTitle?: string;
|
|
16
|
-
disabled?: boolean;
|
|
17
|
-
price?: string;
|
|
18
|
-
badge?: ReactNode;
|
|
19
|
-
icon: FC<{ className?: string }>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
interface RadioGroupIconCardProps extends RadioGroupProps {
|
|
23
|
-
size?: "sm" | "md";
|
|
24
|
-
items: IconCardItemType[];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const RadioGroupIconCard = ({ items, size = "sm", className, ...props }: RadioGroupIconCardProps) => {
|
|
28
|
-
return (
|
|
29
|
-
<RadioGroup {...props} className={(states) => cx("flex flex-col gap-3", typeof className === "function" ? className(states) : className)}>
|
|
30
|
-
{items.map((plan) => (
|
|
31
|
-
<Radio
|
|
32
|
-
isDisabled={plan.disabled}
|
|
33
|
-
key={plan.value}
|
|
34
|
-
value={plan.value}
|
|
35
|
-
className={({ isDisabled, isSelected, isFocusVisible }) =>
|
|
36
|
-
cx(
|
|
37
|
-
"relative block cursor-pointer rounded-xl bg-primary transition duration-100 ring-inset",
|
|
38
|
-
isSelected ? "ring-2 ring-border-brand" : "ring-1 ring-border-secondary",
|
|
39
|
-
isDisabled && "cursor-not-allowed bg-disabled_subtle ring-border-disabled",
|
|
40
|
-
isSelected && isDisabled && "ring-border-disabled_subtle",
|
|
41
|
-
isFocusVisible && "outline-2 outline-offset-2 outline-focus-ring",
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
>
|
|
45
|
-
{({ isDisabled, isSelected, isFocusVisible }) => (
|
|
46
|
-
<>
|
|
47
|
-
<div
|
|
48
|
-
className={cx(
|
|
49
|
-
"flex items-center gap-3 rounded-t-xl p-3 pr-5 transition-inherit-all ring-inset",
|
|
50
|
-
isSelected ? "ring-2 ring-border-brand" : "ring-1 ring-border-secondary",
|
|
51
|
-
isDisabled && "ring-border-disabled",
|
|
52
|
-
isSelected && isDisabled && "ring-border-disabled_subtle",
|
|
53
|
-
isFocusVisible && "outline-hidden",
|
|
54
|
-
)}
|
|
55
|
-
>
|
|
56
|
-
<FeaturedIcon
|
|
57
|
-
size={size === "md" ? "md" : "sm"}
|
|
58
|
-
icon={plan.icon}
|
|
59
|
-
color="gray"
|
|
60
|
-
theme="modern"
|
|
61
|
-
className={cx(isDisabled && "bg-disabled text-fg-disabled")}
|
|
62
|
-
/>
|
|
63
|
-
|
|
64
|
-
<span className={cx("mr-1 text-secondary", size === "md" ? "tt-lg-semi" : "tt-md-semi")}>{plan.title}</span>
|
|
65
|
-
|
|
66
|
-
<CheckboxBase
|
|
67
|
-
size={size === "md" ? "md" : "sm"}
|
|
68
|
-
className="ml-auto"
|
|
69
|
-
isDisabled={isDisabled}
|
|
70
|
-
isSelected={isSelected}
|
|
71
|
-
isFocused={isFocusVisible}
|
|
72
|
-
/>
|
|
73
|
-
</div>
|
|
74
|
-
|
|
75
|
-
<div className="flex flex-col-reverse items-start justify-between gap-4 rounded-b-lg p-4 sm:flex-row sm:gap-1">
|
|
76
|
-
<div className={cx("flex flex-col", size === "md" ? "gap-2" : "gap-1")}>
|
|
77
|
-
<p className="flex items-baseline gap-1">
|
|
78
|
-
<span className={cx("text-secondary", size === "md" ? "td-md-semi" : "td-sm-semi")}>{plan.price}</span>
|
|
79
|
-
<span className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>{plan.secondaryTitle}</span>
|
|
80
|
-
</p>
|
|
81
|
-
<p className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>{plan.description}</p>
|
|
82
|
-
</div>
|
|
83
|
-
{plan.badge && (
|
|
84
|
-
<BadgeWithDot size="sm" type="modern" color="success">
|
|
85
|
-
{plan.badge}
|
|
86
|
-
</BadgeWithDot>
|
|
87
|
-
)}
|
|
88
|
-
</div>
|
|
89
|
-
</>
|
|
90
|
-
)}
|
|
91
|
-
</Radio>
|
|
92
|
-
))}
|
|
93
|
-
</RadioGroup>
|
|
94
|
-
);
|
|
95
|
-
};
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { FC } from "react";
|
|
4
|
-
import type { RadioGroupProps } from "react-aria-components";
|
|
5
|
-
import { Label, Radio, RadioGroup, Text } from "react-aria-components";
|
|
6
|
-
import { FeaturedIcon } from "@/components/foundations/featured-icon/featured-icons";
|
|
7
|
-
import { CheckboxBase } from "@/components/shared/checkbox/checkbox";
|
|
8
|
-
import { cx } from "@/components/utils/cx";
|
|
9
|
-
|
|
10
|
-
type RadioGroupItemType = {
|
|
11
|
-
value: string;
|
|
12
|
-
title: string;
|
|
13
|
-
disabled?: boolean;
|
|
14
|
-
description: string;
|
|
15
|
-
secondaryTitle: string;
|
|
16
|
-
icon: FC<{ className?: string }>;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
interface RadioGroupIconSimpleProps extends RadioGroupProps {
|
|
20
|
-
size?: "sm" | "md";
|
|
21
|
-
items: RadioGroupItemType[];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const RadioGroupIconSimple = ({ items, size = "sm", className, ...props }: RadioGroupIconSimpleProps) => {
|
|
25
|
-
return (
|
|
26
|
-
<RadioGroup {...props} className={(states) => cx("flex flex-col gap-3", typeof className === "function" ? className(states) : className)}>
|
|
27
|
-
{items.map((plan) => (
|
|
28
|
-
<Radio
|
|
29
|
-
isDisabled={plan.disabled}
|
|
30
|
-
key={plan.value}
|
|
31
|
-
value={plan.value}
|
|
32
|
-
className={({ isDisabled, isSelected, isFocusVisible }) =>
|
|
33
|
-
cx(
|
|
34
|
-
"relative flex cursor-pointer items-start gap-1 rounded-xl bg-primary p-4 transition duration-100 ring-inset",
|
|
35
|
-
isSelected ? "ring-2 ring-border-brand" : "ring-1 ring-border-secondary",
|
|
36
|
-
isDisabled && "cursor-not-allowed bg-disabled_subtle ring-border-disabled",
|
|
37
|
-
isFocusVisible && "outline-2 outline-offset-2 outline-focus-ring",
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
>
|
|
41
|
-
{({ isDisabled, isSelected, isFocusVisible }) => (
|
|
42
|
-
<>
|
|
43
|
-
<div className="flex flex-1 gap-3">
|
|
44
|
-
<FeaturedIcon
|
|
45
|
-
icon={plan.icon}
|
|
46
|
-
size={size === "md" ? "md" : "sm"}
|
|
47
|
-
color="gray"
|
|
48
|
-
theme="modern"
|
|
49
|
-
className={cx(isDisabled && "bg-disabled text-fg-disabled")}
|
|
50
|
-
/>
|
|
51
|
-
|
|
52
|
-
<div className={cx("flex flex-col", size === "md" ? "gap-0.5" : "")}>
|
|
53
|
-
<Label className={cx("pointer-events-none flex", size === "md" ? "gap-1.5" : "gap-1")}>
|
|
54
|
-
<span className={cx("text-secondary", size === "md" ? "tt-md-md" : "tt-sm-md")}>{plan.title}</span>
|
|
55
|
-
<span className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>{plan.secondaryTitle}</span>
|
|
56
|
-
</Label>
|
|
57
|
-
<Text slot="description" className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>
|
|
58
|
-
{plan.description}
|
|
59
|
-
</Text>
|
|
60
|
-
</div>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<CheckboxBase size={size === "md" ? "md" : "sm"} isDisabled={isDisabled} isSelected={isSelected} isFocused={isFocusVisible} />
|
|
64
|
-
</>
|
|
65
|
-
)}
|
|
66
|
-
</Radio>
|
|
67
|
-
))}
|
|
68
|
-
</RadioGroup>
|
|
69
|
-
);
|
|
70
|
-
};
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from "react";
|
|
4
|
-
import type { RadioGroupProps } from "react-aria-components";
|
|
5
|
-
import { Label, Radio, RadioGroup, Text } from "react-aria-components";
|
|
6
|
-
import Button from "@/components/shared/buttons/button";
|
|
7
|
-
import { CheckboxBase } from "@/components/shared/checkbox/checkbox";
|
|
8
|
-
import { cx } from "@/components/utils/cx";
|
|
9
|
-
|
|
10
|
-
interface PaymentCardItemType {
|
|
11
|
-
value: string;
|
|
12
|
-
title: string;
|
|
13
|
-
description: string;
|
|
14
|
-
logo: ReactNode;
|
|
15
|
-
disabled?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface RadioGroupPaymentIconProps extends RadioGroupProps {
|
|
19
|
-
size?: "sm" | "md";
|
|
20
|
-
items: PaymentCardItemType[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const RadioGroupPaymentIcon = ({ items, size = "sm", className, ...props }: RadioGroupPaymentIconProps) => {
|
|
24
|
-
return (
|
|
25
|
-
<RadioGroup {...props} className={(states) => cx("flex flex-col gap-3", typeof className === "function" ? className(states) : className)}>
|
|
26
|
-
{items.map((card) => (
|
|
27
|
-
<Radio
|
|
28
|
-
isDisabled={card.disabled}
|
|
29
|
-
key={card.value}
|
|
30
|
-
value={card.value}
|
|
31
|
-
className={({ isDisabled, isSelected, isFocusVisible }) =>
|
|
32
|
-
cx(
|
|
33
|
-
"relative flex cursor-pointer items-start gap-1 rounded-xl bg-primary p-4 transition duration-100 ring-inset",
|
|
34
|
-
isSelected ? "ring-2 ring-border-brand" : "ring-1 ring-border-secondary",
|
|
35
|
-
isDisabled && "cursor-not-allowed bg-disabled_subtle ring-border-disabled_subtle",
|
|
36
|
-
isFocusVisible && "outline-2 outline-offset-2 outline-focus-ring",
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
>
|
|
40
|
-
{({ isDisabled, isSelected, isFocusVisible }) => (
|
|
41
|
-
<>
|
|
42
|
-
<div className={cx("flex flex-1", size === "md" ? "gap-3 md:gap-4" : "gap-3")}>
|
|
43
|
-
<span className="shrink-0">{card.logo}</span>
|
|
44
|
-
<div>
|
|
45
|
-
<div className={cx("flex flex-col", size === "md" ? "gap-0.5" : "")}>
|
|
46
|
-
<Label className={cx("pointer-events-none text-secondary", size === "md" ? "tt-md-md" : "tt-sm-md")}>
|
|
47
|
-
{card.title}
|
|
48
|
-
</Label>
|
|
49
|
-
<Text slot="description" className={cx("text-tertiary", size === "md" ? "tt-md" : "tt-sm")}>
|
|
50
|
-
{card.description}
|
|
51
|
-
</Text>
|
|
52
|
-
</div>
|
|
53
|
-
<div className={cx("flex gap-3", size === "md" ? "mt-3" : "mt-2")}>
|
|
54
|
-
<Button color="link-gray" size={size === "md" ? "md" : "sm"} isDisabled={isDisabled}>
|
|
55
|
-
Set as default
|
|
56
|
-
</Button>
|
|
57
|
-
<Button color="link-color" size={size === "md" ? "md" : "sm"} isDisabled={isDisabled}>
|
|
58
|
-
Edit
|
|
59
|
-
</Button>
|
|
60
|
-
</div>
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<CheckboxBase size={size === "md" ? "md" : "sm"} isDisabled={isDisabled} isSelected={isSelected} isFocused={isFocusVisible} />
|
|
65
|
-
</>
|
|
66
|
-
)}
|
|
67
|
-
</Radio>
|
|
68
|
-
))}
|
|
69
|
-
</RadioGroup>
|
|
70
|
-
);
|
|
71
|
-
};
|