@rovula/ui 0.0.13 → 0.0.14
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 +227 -16
- package/dist/cjs/bundle.js +3 -3
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/ActionButton/ActionButton.d.ts +20 -0
- package/dist/cjs/types/components/ActionButton/ActionButton.stories.d.ts +311 -0
- package/dist/cjs/types/components/ActionButton/ActionButton.styles.d.ts +6 -0
- package/dist/cjs/types/components/Avatar/Avatar.d.ts +32 -0
- package/dist/cjs/types/components/Avatar/Avatar.stories.d.ts +64 -0
- package/dist/cjs/types/components/Avatar/Avatar.styles.d.ts +4 -0
- package/dist/cjs/types/components/Avatar/AvatarBase.d.ts +6 -0
- package/dist/cjs/types/components/Avatar/AvatarGroup.d.ts +11 -0
- package/dist/cjs/types/components/Avatar/AvatarGroup.stories.d.ts +31 -0
- package/dist/cjs/types/components/Input/Input.d.ts +21 -4
- package/dist/cjs/types/components/Input/Input.stories.d.ts +340 -22
- package/dist/cjs/types/components/Input/Input.styles.d.ts +9 -0
- package/dist/cjs/types/components/Label/Label.d.ts +6 -1
- package/dist/cjs/types/components/Label/Label.stories.d.ts +10 -1
- package/dist/cjs/types/components/Label/Label.styles.d.ts +6 -0
- package/dist/cjs/types/components/Navbar/Navbar.d.ts +12 -0
- package/dist/cjs/types/components/Navbar/Navbar.stories.d.ts +35 -0
- package/dist/cjs/types/components/Search/Search.d.ts +2 -0
- package/dist/cjs/types/components/Search/Search.stories.d.ts +21 -0
- package/dist/cjs/types/components/ThemeToggle.d.ts +2 -0
- package/dist/components/ActionButton/ActionButton.js +38 -0
- package/dist/components/ActionButton/ActionButton.stories.js +45 -0
- package/dist/components/ActionButton/ActionButton.styles.js +71 -0
- package/dist/components/Avatar/Avatar.js +22 -0
- package/dist/components/Avatar/Avatar.stories.js +47 -0
- package/dist/components/Avatar/Avatar.styles.js +23 -0
- package/dist/components/Avatar/AvatarBase.js +43 -0
- package/dist/components/Avatar/AvatarGroup.js +21 -0
- package/dist/components/Avatar/AvatarGroup.stories.js +47 -0
- package/dist/components/Button/Button.styles.js +6 -6
- package/dist/components/Input/Input.js +5 -4
- package/dist/components/Input/Input.stories.js +2 -4
- package/dist/components/Input/Input.styles.js +45 -0
- package/dist/components/Label/Label.js +7 -3
- package/dist/components/Label/Label.styles.js +57 -0
- package/dist/components/Navbar/Navbar.js +9 -0
- package/dist/components/Navbar/Navbar.stories.js +41 -0
- package/dist/components/Search/Search.js +19 -0
- package/dist/components/Search/Search.stories.js +36 -0
- package/dist/components/Text/Text.js +2 -1
- package/dist/components/ThemeToggle.js +17 -0
- package/dist/esm/bundle.css +227 -16
- package/dist/esm/bundle.js +3 -3
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/ActionButton/ActionButton.d.ts +20 -0
- package/dist/esm/types/components/ActionButton/ActionButton.stories.d.ts +311 -0
- package/dist/esm/types/components/ActionButton/ActionButton.styles.d.ts +6 -0
- package/dist/esm/types/components/Avatar/Avatar.d.ts +32 -0
- package/dist/esm/types/components/Avatar/Avatar.stories.d.ts +64 -0
- package/dist/esm/types/components/Avatar/Avatar.styles.d.ts +4 -0
- package/dist/esm/types/components/Avatar/AvatarBase.d.ts +6 -0
- package/dist/esm/types/components/Avatar/AvatarGroup.d.ts +11 -0
- package/dist/esm/types/components/Avatar/AvatarGroup.stories.d.ts +31 -0
- package/dist/esm/types/components/Input/Input.d.ts +21 -4
- package/dist/esm/types/components/Input/Input.stories.d.ts +340 -22
- package/dist/esm/types/components/Input/Input.styles.d.ts +9 -0
- package/dist/esm/types/components/Label/Label.d.ts +6 -1
- package/dist/esm/types/components/Label/Label.stories.d.ts +10 -1
- package/dist/esm/types/components/Label/Label.styles.d.ts +6 -0
- package/dist/esm/types/components/Navbar/Navbar.d.ts +12 -0
- package/dist/esm/types/components/Navbar/Navbar.stories.d.ts +35 -0
- package/dist/esm/types/components/Search/Search.d.ts +2 -0
- package/dist/esm/types/components/Search/Search.stories.d.ts +21 -0
- package/dist/esm/types/components/ThemeToggle.d.ts +2 -0
- package/dist/index.d.ts +22 -10
- package/dist/src/theme/global.css +290 -21
- package/dist/theme/global.css +11 -0
- package/dist/theme/presets/colors.js +28 -0
- package/package.json +2 -1
- package/src/components/ActionButton/ActionButton.stories.tsx +176 -0
- package/src/components/ActionButton/ActionButton.styles.ts +79 -0
- package/src/components/ActionButton/ActionButton.tsx +42 -0
- package/src/components/Avatar/Avatar.stories.tsx +107 -0
- package/src/components/Avatar/Avatar.styles.ts +28 -0
- package/src/components/Avatar/Avatar.tsx +88 -0
- package/src/components/Avatar/AvatarBase.tsx +50 -0
- package/src/components/Avatar/AvatarGroup.stories.tsx +77 -0
- package/src/components/Avatar/AvatarGroup.tsx +55 -0
- package/src/components/Button/Button.styles.ts +6 -6
- package/src/components/Input/Input.stories.tsx +8 -6
- package/src/components/Input/Input.styles.tsx +51 -0
- package/src/components/Input/Input.tsx +30 -6
- package/src/components/Label/Label.styles.ts +61 -0
- package/src/components/Label/Label.tsx +13 -7
- package/src/components/Navbar/Navbar.stories.tsx +86 -0
- package/src/components/Navbar/Navbar.tsx +56 -0
- package/src/components/Search/Search.stories.tsx +44 -0
- package/src/components/Search/Search.tsx +25 -0
- package/src/components/Text/Text.tsx +2 -1
- package/src/components/ThemeToggle.tsx +19 -0
- package/src/theme/global.css +11 -0
- package/src/theme/presets/colors.js +28 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
|
|
4
|
+
import ActionButton from "./ActionButton";
|
|
5
|
+
import { ArrowsUpDownIcon } from "@heroicons/react/16/solid";
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: "Components/ActionButton",
|
|
9
|
+
component: ActionButton,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "fullscreen",
|
|
13
|
+
},
|
|
14
|
+
decorators: [
|
|
15
|
+
(Story) => (
|
|
16
|
+
<div className="p-5">
|
|
17
|
+
<Story />
|
|
18
|
+
</div>
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
} satisfies Meta<typeof ActionButton>;
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
|
|
25
|
+
export const Default = {
|
|
26
|
+
args: {
|
|
27
|
+
variant: "solid",
|
|
28
|
+
size: "lg",
|
|
29
|
+
},
|
|
30
|
+
render: (args) => {
|
|
31
|
+
console.log("args ", args);
|
|
32
|
+
const props: typeof args = {
|
|
33
|
+
...args,
|
|
34
|
+
};
|
|
35
|
+
return (
|
|
36
|
+
<div className="flex flex-row justify-between">
|
|
37
|
+
<ActionButton {...props}>
|
|
38
|
+
<ArrowsUpDownIcon />
|
|
39
|
+
</ActionButton>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
},
|
|
43
|
+
} satisfies StoryObj;
|
|
44
|
+
|
|
45
|
+
export const Preview = {
|
|
46
|
+
args: {},
|
|
47
|
+
render: (args) => {
|
|
48
|
+
console.log("args ", args);
|
|
49
|
+
const props: typeof args = {
|
|
50
|
+
...args,
|
|
51
|
+
};
|
|
52
|
+
return (
|
|
53
|
+
<div className="flex flex-col gap-2 w-full bg-black p-20">
|
|
54
|
+
<div className="flex flex-row justify-between items-center">
|
|
55
|
+
<h6 className="w-[20px] text-white">Default:</h6>
|
|
56
|
+
<div className="flex flex-row gap-2 ">
|
|
57
|
+
<ActionButton variant="solid" size="lg">
|
|
58
|
+
<ArrowsUpDownIcon />
|
|
59
|
+
</ActionButton>
|
|
60
|
+
<ActionButton variant="solid" size="md">
|
|
61
|
+
<ArrowsUpDownIcon />
|
|
62
|
+
</ActionButton>
|
|
63
|
+
<ActionButton variant="solid" size="sm">
|
|
64
|
+
<ArrowsUpDownIcon />
|
|
65
|
+
</ActionButton>
|
|
66
|
+
</div>
|
|
67
|
+
<div className="flex flex-row gap-2">
|
|
68
|
+
<ActionButton variant="outline" size="lg">
|
|
69
|
+
<ArrowsUpDownIcon />
|
|
70
|
+
</ActionButton>
|
|
71
|
+
<ActionButton variant="outline" size="md">
|
|
72
|
+
<ArrowsUpDownIcon />
|
|
73
|
+
</ActionButton>
|
|
74
|
+
<ActionButton variant="outline" size="sm">
|
|
75
|
+
<ArrowsUpDownIcon />
|
|
76
|
+
</ActionButton>
|
|
77
|
+
</div>
|
|
78
|
+
<div className="flex flex-row gap-2">
|
|
79
|
+
<ActionButton variant="icon" size="lg">
|
|
80
|
+
<ArrowsUpDownIcon />
|
|
81
|
+
</ActionButton>
|
|
82
|
+
<ActionButton variant="icon" size="md">
|
|
83
|
+
<ArrowsUpDownIcon />
|
|
84
|
+
</ActionButton>
|
|
85
|
+
<ActionButton variant="icon" size="sm">
|
|
86
|
+
<ArrowsUpDownIcon />
|
|
87
|
+
</ActionButton>
|
|
88
|
+
<ActionButton variant="icon" size="xs">
|
|
89
|
+
<ArrowsUpDownIcon />
|
|
90
|
+
</ActionButton>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div className="flex flex-row justify-between">
|
|
95
|
+
<h6 className="w-[20px] text-white">Active:</h6>
|
|
96
|
+
<div className="flex flex-row gap-2">
|
|
97
|
+
<ActionButton variant="solid" size="lg" active>
|
|
98
|
+
<ArrowsUpDownIcon />
|
|
99
|
+
</ActionButton>
|
|
100
|
+
<ActionButton variant="solid" size="md" active>
|
|
101
|
+
<ArrowsUpDownIcon />
|
|
102
|
+
</ActionButton>
|
|
103
|
+
<ActionButton variant="solid" size="sm" active>
|
|
104
|
+
<ArrowsUpDownIcon />
|
|
105
|
+
</ActionButton>
|
|
106
|
+
</div>
|
|
107
|
+
<div className="flex flex-row gap-2">
|
|
108
|
+
<ActionButton variant="outline" size="lg" active>
|
|
109
|
+
<ArrowsUpDownIcon />
|
|
110
|
+
</ActionButton>
|
|
111
|
+
<ActionButton variant="outline" size="md" active>
|
|
112
|
+
<ArrowsUpDownIcon />
|
|
113
|
+
</ActionButton>
|
|
114
|
+
<ActionButton variant="outline" size="sm" active>
|
|
115
|
+
<ArrowsUpDownIcon />
|
|
116
|
+
</ActionButton>
|
|
117
|
+
</div>
|
|
118
|
+
<div className="flex flex-row gap-2">
|
|
119
|
+
<ActionButton variant="icon" size="lg" active>
|
|
120
|
+
<ArrowsUpDownIcon />
|
|
121
|
+
</ActionButton>
|
|
122
|
+
<ActionButton variant="icon" size="md" active>
|
|
123
|
+
<ArrowsUpDownIcon />
|
|
124
|
+
</ActionButton>
|
|
125
|
+
<ActionButton variant="icon" size="sm" active>
|
|
126
|
+
<ArrowsUpDownIcon />
|
|
127
|
+
</ActionButton>
|
|
128
|
+
<ActionButton variant="icon" size="xs" active>
|
|
129
|
+
<ArrowsUpDownIcon />
|
|
130
|
+
</ActionButton>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<div className="flex flex-row justify-between">
|
|
135
|
+
<h6 className="w-[20px] text-white">Disabled:</h6>
|
|
136
|
+
<div className="flex flex-row gap-2">
|
|
137
|
+
<ActionButton variant="solid" size="lg" disabled>
|
|
138
|
+
<ArrowsUpDownIcon />
|
|
139
|
+
</ActionButton>
|
|
140
|
+
<ActionButton variant="solid" size="md" disabled>
|
|
141
|
+
<ArrowsUpDownIcon />
|
|
142
|
+
</ActionButton>
|
|
143
|
+
<ActionButton variant="solid" size="sm" disabled>
|
|
144
|
+
<ArrowsUpDownIcon />
|
|
145
|
+
</ActionButton>
|
|
146
|
+
</div>
|
|
147
|
+
<div className="flex flex-row gap-2">
|
|
148
|
+
<ActionButton variant="outline" size="lg" disabled>
|
|
149
|
+
<ArrowsUpDownIcon />
|
|
150
|
+
</ActionButton>
|
|
151
|
+
<ActionButton variant="outline" size="md" disabled>
|
|
152
|
+
<ArrowsUpDownIcon />
|
|
153
|
+
</ActionButton>
|
|
154
|
+
<ActionButton variant="outline" size="sm" disabled>
|
|
155
|
+
<ArrowsUpDownIcon />
|
|
156
|
+
</ActionButton>
|
|
157
|
+
</div>
|
|
158
|
+
<div className="flex flex-row gap-2">
|
|
159
|
+
<ActionButton variant="icon" size="lg" disabled>
|
|
160
|
+
<ArrowsUpDownIcon />
|
|
161
|
+
</ActionButton>
|
|
162
|
+
<ActionButton variant="icon" size="md" disabled>
|
|
163
|
+
<ArrowsUpDownIcon />
|
|
164
|
+
</ActionButton>
|
|
165
|
+
<ActionButton variant="icon" size="sm" disabled>
|
|
166
|
+
<ArrowsUpDownIcon />
|
|
167
|
+
</ActionButton>
|
|
168
|
+
<ActionButton variant="icon" size="xs" disabled>
|
|
169
|
+
<ArrowsUpDownIcon />
|
|
170
|
+
</ActionButton>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
},
|
|
176
|
+
} satisfies StoryObj;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { cva } from "class-variance-authority";
|
|
2
|
+
|
|
3
|
+
export const actionButtonVariants = cva(
|
|
4
|
+
["bg-primary rounded box-border flex items-center justify-center"],
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
solid:
|
|
9
|
+
" bg-secondary-20 hover:bg-secondary-5 fill-secondary-foreground text-secondary-foreground",
|
|
10
|
+
outline: [
|
|
11
|
+
"bg-transparent border border-main-transparent-secondary-32 fill-secondary-70 text-secondary-70",
|
|
12
|
+
"hover:bg-main-transparent-secondary-8 hover:border-main-secondary-48 hover:fill-secondary-5 hover:text-secondary-5",
|
|
13
|
+
],
|
|
14
|
+
icon: [
|
|
15
|
+
"rounded-full bg-transparent fill-secondary-70 text-secondary-70",
|
|
16
|
+
"hover:bg-main-transparent-secondary-8 hover:fill-secondary-5 hover:text-secondary-5",
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
size: {
|
|
20
|
+
xs: "p-[2px] w-[18px] h-[18px]",
|
|
21
|
+
sm: "px-2 py-1 w-[38px] h-[30px]",
|
|
22
|
+
md: "px-3 py-2 w-[46px] h-[38px]",
|
|
23
|
+
lg: "px-4 py-3 w-[64px] h-[56px]",
|
|
24
|
+
},
|
|
25
|
+
disabled: {
|
|
26
|
+
true: "pointer-events-none border-grey2-500/[.32] text-grey2-500/[.32] fill-red-500",
|
|
27
|
+
},
|
|
28
|
+
active: {
|
|
29
|
+
false: "",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
compoundVariants: [
|
|
33
|
+
{
|
|
34
|
+
variant: "solid",
|
|
35
|
+
disabled: true,
|
|
36
|
+
className: "bg-grey2-500 text-textcolor-medium fill-textcolor-medium",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
variant: "solid",
|
|
40
|
+
active: true,
|
|
41
|
+
className:
|
|
42
|
+
"bg-primary-120 hover:bg-primary-100 text-primary-foreground",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
variant: "outline",
|
|
46
|
+
active: true,
|
|
47
|
+
className:
|
|
48
|
+
"border-main-transparent-primary-48 hover:bg-main-transparent-primary-8 hover:text-primary text-primary",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
variant: "icon",
|
|
52
|
+
active: true,
|
|
53
|
+
className:
|
|
54
|
+
"border-main-transparent-primary-48 hover:bg-main-transparent-primary-8 hover:text-primary text-primary",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
size: "lg",
|
|
58
|
+
variant: "icon",
|
|
59
|
+
className: "w-[56px] h-[56px]",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
size: "md",
|
|
63
|
+
variant: "icon",
|
|
64
|
+
className: "w-[38px] h-[38px]",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
size: "sm",
|
|
68
|
+
variant: "icon",
|
|
69
|
+
className: "w-[30px] h-[30px]",
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
defaultVariants: {
|
|
73
|
+
size: "md",
|
|
74
|
+
variant: "solid",
|
|
75
|
+
disabled: false,
|
|
76
|
+
active: false,
|
|
77
|
+
},
|
|
78
|
+
}
|
|
79
|
+
);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use-client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/utils/cn";
|
|
4
|
+
import React, { forwardRef } from "react";
|
|
5
|
+
import { actionButtonVariants } from "./ActionButton.styles";
|
|
6
|
+
|
|
7
|
+
export type ActionButtonProps = {
|
|
8
|
+
title?: string;
|
|
9
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
10
|
+
variant?: "solid" | "outline" | "icon";
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
active?: boolean;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
className?: string;
|
|
15
|
+
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
16
|
+
|
|
17
|
+
const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>(
|
|
18
|
+
({ children, disabled, active, className, size, variant, ...props }, ref) => {
|
|
19
|
+
const actionButtonClassname = actionButtonVariants({
|
|
20
|
+
size,
|
|
21
|
+
variant,
|
|
22
|
+
active,
|
|
23
|
+
disabled,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<button
|
|
28
|
+
{...props}
|
|
29
|
+
ref={ref}
|
|
30
|
+
type="button"
|
|
31
|
+
aria-disabled={disabled || undefined}
|
|
32
|
+
disabled={disabled}
|
|
33
|
+
tabIndex={disabled ? -1 : 0}
|
|
34
|
+
className={cn(actionButtonClassname, className)}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</button>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export default ActionButton;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
|
|
4
|
+
import Avatar, { AvatarProps } from "./Avatar";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "Components/Avatar/Avatar",
|
|
8
|
+
component: Avatar,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "fullscreen",
|
|
12
|
+
},
|
|
13
|
+
decorators: [
|
|
14
|
+
(Story) => (
|
|
15
|
+
<div className="p-5">
|
|
16
|
+
<Story />
|
|
17
|
+
</div>
|
|
18
|
+
),
|
|
19
|
+
],
|
|
20
|
+
} satisfies Meta<typeof Avatar>;
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
|
|
24
|
+
export const Default = {
|
|
25
|
+
args: {
|
|
26
|
+
imageUrl: "",
|
|
27
|
+
text: "AN",
|
|
28
|
+
size: "lg",
|
|
29
|
+
rounded: "full",
|
|
30
|
+
},
|
|
31
|
+
render: (args) => {
|
|
32
|
+
console.log("args ", args);
|
|
33
|
+
const props: any = {
|
|
34
|
+
...args,
|
|
35
|
+
};
|
|
36
|
+
return (
|
|
37
|
+
<div className="flex flex-row justify-between">
|
|
38
|
+
<Avatar {...props} />
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
},
|
|
42
|
+
} satisfies StoryObj;
|
|
43
|
+
|
|
44
|
+
export const Preview = {
|
|
45
|
+
args: {},
|
|
46
|
+
render: (args) => {
|
|
47
|
+
console.log("args ", args);
|
|
48
|
+
const props: typeof args = {
|
|
49
|
+
...args,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const BORDER: AvatarProps["rounded"][] = ["full", "normal", "none"];
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className="flex flex-col gap-2 w-full bg-black p-20">
|
|
56
|
+
{BORDER.map((rounded) => (
|
|
57
|
+
<div key={rounded} className="flex flex-row items-center gap-3">
|
|
58
|
+
<Avatar
|
|
59
|
+
size="xxs"
|
|
60
|
+
rounded={rounded}
|
|
61
|
+
type="image"
|
|
62
|
+
imageUrl="https://i.pravatar.cc/300?img=59"
|
|
63
|
+
fallback="AS"
|
|
64
|
+
/>
|
|
65
|
+
<Avatar
|
|
66
|
+
size="xs"
|
|
67
|
+
rounded={rounded}
|
|
68
|
+
type="image"
|
|
69
|
+
imageUrl="https://i.pravatar.cc/300?img=59"
|
|
70
|
+
fallback="AS"
|
|
71
|
+
/>
|
|
72
|
+
<Avatar
|
|
73
|
+
size="sm"
|
|
74
|
+
rounded={rounded}
|
|
75
|
+
type="image"
|
|
76
|
+
imageUrl="https://i.pravatar.cc/300?img=59"
|
|
77
|
+
fallback="AS"
|
|
78
|
+
/>
|
|
79
|
+
<Avatar
|
|
80
|
+
size="md"
|
|
81
|
+
rounded={rounded}
|
|
82
|
+
type="image"
|
|
83
|
+
imageUrl="https://i.pravatar.cc/300?img=59"
|
|
84
|
+
fallback="AS"
|
|
85
|
+
/>
|
|
86
|
+
<Avatar
|
|
87
|
+
size="lg"
|
|
88
|
+
rounded={rounded}
|
|
89
|
+
type="image"
|
|
90
|
+
imageUrl="https://i.pravatar.cc/300?img=59"
|
|
91
|
+
fallback="AS"
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
))}
|
|
95
|
+
{BORDER.map((rounded) => (
|
|
96
|
+
<div key={rounded} className="flex flex-row items-center gap-3">
|
|
97
|
+
<Avatar size="xxs" rounded={rounded} type="text" text="AS" />
|
|
98
|
+
<Avatar size="xs" rounded={rounded} type="text" text="AS" />
|
|
99
|
+
<Avatar size="sm" rounded={rounded} type="text" text="AS" />
|
|
100
|
+
<Avatar size="md" rounded={rounded} type="text" text="AS" />
|
|
101
|
+
<Avatar size="lg" rounded={rounded} type="text" text="AS" />
|
|
102
|
+
</div>
|
|
103
|
+
))}
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
},
|
|
107
|
+
} satisfies StoryObj;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cva } from "class-variance-authority";
|
|
2
|
+
|
|
3
|
+
export const avatarVariants = cva(
|
|
4
|
+
[
|
|
5
|
+
"flex items-center justify-center bg-grey2-700 text-white typography-subtitile2 truncate",
|
|
6
|
+
],
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
xxs: "w-[24px] h-[24px] typography-subtitile3",
|
|
11
|
+
xs: "w-[32px] h-[32px]",
|
|
12
|
+
sm: "w-[40px] h-[40px]",
|
|
13
|
+
md: "w-[48px] h-[48px]",
|
|
14
|
+
lg: "w-[64px] h-[64px]",
|
|
15
|
+
},
|
|
16
|
+
rounded: {
|
|
17
|
+
normal: "rounded",
|
|
18
|
+
full: "rounded-full",
|
|
19
|
+
none: "rounded-none",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
size: "md",
|
|
25
|
+
rounded: "normal",
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "@/utils/cn";
|
|
5
|
+
import { AvatarBase, AvatarFallback, AvatarImage } from "./AvatarBase";
|
|
6
|
+
import { avatarVariants } from "./Avatar.styles";
|
|
7
|
+
|
|
8
|
+
type BaseAvatarProps = {
|
|
9
|
+
imageUrl?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
fallback?: React.ReactNode;
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
size?: "xxs" | "xs" | "sm" | "md" | "lg";
|
|
15
|
+
rounded?: "full" | "normal" | "none";
|
|
16
|
+
className?: string;
|
|
17
|
+
imageClassName?: string;
|
|
18
|
+
fallbackClassName?: string;
|
|
19
|
+
style?: React.CSSProperties;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type AvatarText = {
|
|
23
|
+
text: string;
|
|
24
|
+
type: "text";
|
|
25
|
+
} & BaseAvatarProps;
|
|
26
|
+
|
|
27
|
+
type AvatarImage = {
|
|
28
|
+
imageUrl: string;
|
|
29
|
+
fallback: React.ReactNode;
|
|
30
|
+
type: "image";
|
|
31
|
+
} & BaseAvatarProps;
|
|
32
|
+
|
|
33
|
+
type AvatarIcon = {
|
|
34
|
+
icon: string;
|
|
35
|
+
type: "icon";
|
|
36
|
+
} & BaseAvatarProps;
|
|
37
|
+
|
|
38
|
+
export type AvatarProps = AvatarText | AvatarImage | AvatarIcon;
|
|
39
|
+
|
|
40
|
+
export const formatAvatarName = (text: string) => {
|
|
41
|
+
if (!text.length) return "-";
|
|
42
|
+
|
|
43
|
+
const spitWithSpace = text.split(" ");
|
|
44
|
+
const first = text?.charAt(0);
|
|
45
|
+
const last = spitWithSpace?.[1]?.charAt(0) ?? text?.charAt(1) ?? "";
|
|
46
|
+
|
|
47
|
+
return `${first}${last}`;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const Avatar: React.FC<AvatarProps> = ({
|
|
51
|
+
text,
|
|
52
|
+
imageUrl,
|
|
53
|
+
icon,
|
|
54
|
+
fallback,
|
|
55
|
+
size,
|
|
56
|
+
rounded,
|
|
57
|
+
className,
|
|
58
|
+
imageClassName,
|
|
59
|
+
fallbackClassName,
|
|
60
|
+
type = "text",
|
|
61
|
+
children,
|
|
62
|
+
style,
|
|
63
|
+
}) => {
|
|
64
|
+
const avatarClassname = avatarVariants({ size, rounded });
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<AvatarBase className={cn(avatarClassname, className)} style={style}>
|
|
68
|
+
{children || (
|
|
69
|
+
<>
|
|
70
|
+
{type === "image" && (
|
|
71
|
+
<>
|
|
72
|
+
<AvatarImage src={imageUrl} className={cn(imageClassName)} />
|
|
73
|
+
<AvatarFallback className={cn(fallbackClassName)}>
|
|
74
|
+
{typeof fallback === "string"
|
|
75
|
+
? formatAvatarName(fallback)
|
|
76
|
+
: fallback}
|
|
77
|
+
</AvatarFallback>
|
|
78
|
+
</>
|
|
79
|
+
)}
|
|
80
|
+
{type === "text" && formatAvatarName(text ?? "")}
|
|
81
|
+
{type === "icon" && icon}
|
|
82
|
+
</>
|
|
83
|
+
)}
|
|
84
|
+
</AvatarBase>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export default Avatar;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/utils/cn";
|
|
7
|
+
|
|
8
|
+
const AvatarBase = React.forwardRef<
|
|
9
|
+
React.ElementRef<typeof AvatarPrimitive.Root>,
|
|
10
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
|
11
|
+
>(({ className, ...props }, ref) => (
|
|
12
|
+
<AvatarPrimitive.Root
|
|
13
|
+
ref={ref}
|
|
14
|
+
className={cn(
|
|
15
|
+
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
|
16
|
+
className
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
));
|
|
21
|
+
AvatarBase.displayName = AvatarPrimitive.Root.displayName;
|
|
22
|
+
|
|
23
|
+
const AvatarImage = React.forwardRef<
|
|
24
|
+
React.ElementRef<typeof AvatarPrimitive.Image>,
|
|
25
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
|
26
|
+
>(({ className, ...props }, ref) => (
|
|
27
|
+
<AvatarPrimitive.Image
|
|
28
|
+
ref={ref}
|
|
29
|
+
className={cn("aspect-square h-full w-full", className)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
));
|
|
33
|
+
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
34
|
+
|
|
35
|
+
const AvatarFallback = React.forwardRef<
|
|
36
|
+
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
|
37
|
+
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
|
38
|
+
>(({ className, ...props }, ref) => (
|
|
39
|
+
<AvatarPrimitive.Fallback
|
|
40
|
+
ref={ref}
|
|
41
|
+
className={cn(
|
|
42
|
+
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
|
43
|
+
className
|
|
44
|
+
)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
));
|
|
48
|
+
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
49
|
+
|
|
50
|
+
export { AvatarBase, AvatarImage, AvatarFallback };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
|
|
4
|
+
import AvatarGroup from "./AvatarGroup";
|
|
5
|
+
import Avatar from "./Avatar";
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: "Components/Avatar/AvatarGroup",
|
|
9
|
+
component: AvatarGroup,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: "fullscreen",
|
|
13
|
+
},
|
|
14
|
+
decorators: [
|
|
15
|
+
(Story) => (
|
|
16
|
+
<div className="p-5">
|
|
17
|
+
<Story />
|
|
18
|
+
</div>
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
} satisfies Meta<typeof AvatarGroup>;
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
|
|
25
|
+
export const Default = {
|
|
26
|
+
args: {
|
|
27
|
+
imageUrl: "",
|
|
28
|
+
text: "AN",
|
|
29
|
+
size: "lg",
|
|
30
|
+
rounded: "full",
|
|
31
|
+
},
|
|
32
|
+
render: (args) => {
|
|
33
|
+
console.log("args ", args);
|
|
34
|
+
const props: any = {
|
|
35
|
+
...args,
|
|
36
|
+
};
|
|
37
|
+
return (
|
|
38
|
+
<div className="flex flex-row justify-between">
|
|
39
|
+
<AvatarGroup {...props}>
|
|
40
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
41
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
42
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
43
|
+
</AvatarGroup>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
},
|
|
47
|
+
} satisfies StoryObj;
|
|
48
|
+
|
|
49
|
+
export const Preview = {
|
|
50
|
+
args: {},
|
|
51
|
+
render: (args) => {
|
|
52
|
+
console.log("args ", args);
|
|
53
|
+
const props: typeof args = {
|
|
54
|
+
...args,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<div className="flex flex-col gap-2 w-full bg-black p-20">
|
|
59
|
+
<div className="flex flex-row items-center gap-3">
|
|
60
|
+
<AvatarGroup>
|
|
61
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
62
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
63
|
+
<Avatar
|
|
64
|
+
size="lg"
|
|
65
|
+
rounded="full"
|
|
66
|
+
type="image"
|
|
67
|
+
imageUrl="https://i.pravatar.cc/300?img=59"
|
|
68
|
+
fallback="AS"
|
|
69
|
+
/>
|
|
70
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
71
|
+
<Avatar size="lg" rounded="full" type="text" text="AS" />
|
|
72
|
+
</AvatarGroup>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
} satisfies StoryObj;
|