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.
Files changed (101) hide show
  1. package/config/postcss.config.mjs +6 -0
  2. package/{templates/default/src → config}/styles/globals.css +2 -33
  3. package/{templates/default/src → config}/styles/theme.css +31 -33
  4. package/{templates/default/src → config}/styles/typography.css +24 -24
  5. package/dist/index.mjs +54 -15
  6. package/package.json +4 -3
  7. package/templates/default/.prettierrc +0 -10
  8. package/templates/default/README.md +0 -36
  9. package/templates/default/eslint.config.mjs +0 -58
  10. package/templates/default/next.config.ts +0 -6
  11. package/templates/default/package.json +0 -56
  12. package/templates/default/postcss.config.js +0 -5
  13. package/templates/default/public/favicon.ico +0 -0
  14. package/templates/default/public/marketing/smiling-girl.png +0 -0
  15. package/templates/default/public/marketing/spirals.webp +0 -0
  16. package/templates/default/src/app/home-screen.tsx +0 -108
  17. package/templates/default/src/app/layout.tsx +0 -34
  18. package/templates/default/src/app/not-found.tsx +0 -40
  19. package/templates/default/src/app/page.tsx +0 -3
  20. package/templates/default/src/components/foundations/dot-icon.tsx +0 -27
  21. package/templates/default/src/components/foundations/featured-icon/featured-icons.tsx +0 -153
  22. package/templates/default/src/components/foundations/logo/UntitledLogo.tsx +0 -63
  23. package/templates/default/src/components/foundations/logo/UntitledLogoMinimal.tsx +0 -164
  24. package/templates/default/src/components/foundations/payment-icons/amex-icon.tsx +0 -19
  25. package/templates/default/src/components/foundations/payment-icons/apple-pay-icon.tsx +0 -27
  26. package/templates/default/src/components/foundations/payment-icons/discover-icon.tsx +0 -34
  27. package/templates/default/src/components/foundations/payment-icons/index.tsx +0 -10
  28. package/templates/default/src/components/foundations/payment-icons/mastercard-icon.tsx +0 -39
  29. package/templates/default/src/components/foundations/payment-icons/paypal-icon.tsx +0 -45
  30. package/templates/default/src/components/foundations/payment-icons/stripe-icon.tsx +0 -27
  31. package/templates/default/src/components/foundations/payment-icons/union-pay-icon.tsx +0 -37
  32. package/templates/default/src/components/foundations/payment-icons/visa-icon.tsx +0 -27
  33. package/templates/default/src/components/marketing/header-navigation/base-components/nav-menu-item.tsx +0 -41
  34. package/templates/default/src/components/marketing/header-navigation/components/header.tsx +0 -245
  35. package/templates/default/src/components/marketing/header-navigation/dropdown-header-navigation.tsx +0 -53
  36. package/templates/default/src/components/shared/avatar/avatar-label-group.tsx +0 -32
  37. package/templates/default/src/components/shared/avatar/avatar-profile-photo.tsx +0 -84
  38. package/templates/default/src/components/shared/avatar/avatar.tsx +0 -131
  39. package/templates/default/src/components/shared/avatar/base-components/avatar-add-button.tsx +0 -33
  40. package/templates/default/src/components/shared/avatar/base-components/avatar-company-icon.tsx +0 -26
  41. package/templates/default/src/components/shared/avatar/base-components/avatar-online-indicator.tsx +0 -31
  42. package/templates/default/src/components/shared/avatar/base-components/index.ts +0 -4
  43. package/templates/default/src/components/shared/avatar/base-components/verified-tick.tsx +0 -34
  44. package/templates/default/src/components/shared/avatar/utils.ts +0 -12
  45. package/templates/default/src/components/shared/badges/badge-groups.tsx +0 -176
  46. package/templates/default/src/components/shared/badges/badge-types.ts +0 -264
  47. package/templates/default/src/components/shared/badges/badges.tsx +0 -479
  48. package/templates/default/src/components/shared/button-group/button-group.tsx +0 -97
  49. package/templates/default/src/components/shared/buttons/app-store-buttons-outline.tsx +0 -454
  50. package/templates/default/src/components/shared/buttons/app-store-buttons.tsx +0 -806
  51. package/templates/default/src/components/shared/buttons/button-utility.tsx +0 -87
  52. package/templates/default/src/components/shared/buttons/button.tsx +0 -285
  53. package/templates/default/src/components/shared/buttons/close-button.tsx +0 -39
  54. package/templates/default/src/components/shared/buttons/social-button.tsx +0 -135
  55. package/templates/default/src/components/shared/buttons/social-logos.tsx +0 -115
  56. package/templates/default/src/components/shared/checkbox/checkbox.tsx +0 -120
  57. package/templates/default/src/components/shared/dropdown/dropdown.tsx +0 -147
  58. package/templates/default/src/components/shared/file-upload-trigger/file-upload-trigger.tsx +0 -74
  59. package/templates/default/src/components/shared/form/form.tsx +0 -10
  60. package/templates/default/src/components/shared/form/hook-form.tsx +0 -75
  61. package/templates/default/src/components/shared/input/hint-text.tsx +0 -34
  62. package/templates/default/src/components/shared/input/index.tsx +0 -189
  63. package/templates/default/src/components/shared/input/input-payment.tsx +0 -134
  64. package/templates/default/src/components/shared/input/input-with-button.tsx +0 -69
  65. package/templates/default/src/components/shared/input/input-with-dropdown.tsx +0 -178
  66. package/templates/default/src/components/shared/input/input-with-prefix.tsx +0 -74
  67. package/templates/default/src/components/shared/input/label.tsx +0 -46
  68. package/templates/default/src/components/shared/progress-indicators/progress-circles.tsx +0 -176
  69. package/templates/default/src/components/shared/progress-indicators/progress-indicators.tsx +0 -86
  70. package/templates/default/src/components/shared/progress-indicators/simple-circle.tsx +0 -29
  71. package/templates/default/src/components/shared/radio-buttons/radio-buttons.tsx +0 -125
  72. package/templates/default/src/components/shared/radio-groups/radio-group-avatar.tsx +0 -62
  73. package/templates/default/src/components/shared/radio-groups/radio-group-checkbox.tsx +0 -72
  74. package/templates/default/src/components/shared/radio-groups/radio-group-icon-card.tsx +0 -95
  75. package/templates/default/src/components/shared/radio-groups/radio-group-icon-simple.tsx +0 -70
  76. package/templates/default/src/components/shared/radio-groups/radio-group-payment-icon.tsx +0 -71
  77. package/templates/default/src/components/shared/radio-groups/radio-group-radio-button.tsx +0 -76
  78. package/templates/default/src/components/shared/radio-groups/radio-groups.tsx +0 -8
  79. package/templates/default/src/components/shared/select/combobox.tsx +0 -161
  80. package/templates/default/src/components/shared/select/multi-select.tsx +0 -373
  81. package/templates/default/src/components/shared/select/popover.tsx +0 -36
  82. package/templates/default/src/components/shared/select/select-item.tsx +0 -70
  83. package/templates/default/src/components/shared/select/select-native.tsx +0 -63
  84. package/templates/default/src/components/shared/select/select.tsx +0 -143
  85. package/templates/default/src/components/shared/slider/slider.tsx +0 -76
  86. package/templates/default/src/components/shared/tags/base-components/tag-checkbox.tsx +0 -47
  87. package/templates/default/src/components/shared/tags/base-components/tag-close-x.tsx +0 -34
  88. package/templates/default/src/components/shared/tags/tags.tsx +0 -162
  89. package/templates/default/src/components/shared/textarea/textarea.tsx +0 -82
  90. package/templates/default/src/components/shared/toggle/toggle.tsx +0 -140
  91. package/templates/default/src/components/shared/tooltips/tooltips.tsx +0 -140
  92. package/templates/default/src/components/utils/index.ts +0 -48
  93. package/templates/default/src/components/utils/isDeepEqual.ts +0 -31
  94. package/templates/default/src/components/utils/isReactComponent.ts +0 -22
  95. package/templates/default/src/components/utils/mergeRefs.ts +0 -19
  96. package/templates/default/src/components/utils/useBreakpoint.ts +0 -36
  97. package/templates/default/src/components/utils/uuid.ts +0 -9
  98. package/templates/default/src/hooks/use-resize-observer.tsx +0 -55
  99. package/templates/default/src/providers/theme.tsx +0 -11
  100. package/templates/default/src/styles/text-styles.css +0 -177
  101. 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
- };