@peerbots/core 0.1.0
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/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.github/workflows/publish.yml +42 -0
- package/.github/workflows/storybook.yml +46 -0
- package/.storybook/main.ts +28 -0
- package/.storybook/preview.ts +22 -0
- package/README.md +9 -0
- package/dist/index.css +1 -0
- package/dist/index.d.mts +704 -0
- package/dist/index.d.ts +704 -0
- package/dist/index.js +5 -0
- package/dist/index.mjs +5 -0
- package/package.json +60 -0
- package/src/charts/DistributionBarChart.stories.tsx +41 -0
- package/src/charts/DistributionBarChart.tsx +170 -0
- package/src/charts/DistributionHistogram.stories.tsx +56 -0
- package/src/charts/DistributionHistogram.tsx +193 -0
- package/src/charts/index.ts +10 -0
- package/src/global.d.ts +1 -0
- package/src/helpers/SEO.tsx +41 -0
- package/src/index.ts +6 -0
- package/src/styles/theme.css +60 -0
- package/src/ui/Alert.stories.tsx +41 -0
- package/src/ui/Alert.tsx +72 -0
- package/src/ui/Anchor.stories.tsx +25 -0
- package/src/ui/Anchor.tsx +32 -0
- package/src/ui/AuthFormUI.stories.tsx +67 -0
- package/src/ui/AuthFormUI.tsx +217 -0
- package/src/ui/BasePanel.stories.tsx +36 -0
- package/src/ui/BasePanel.tsx +59 -0
- package/src/ui/Button.stories.tsx +108 -0
- package/src/ui/Button.tsx +121 -0
- package/src/ui/Checkbox.stories.tsx +61 -0
- package/src/ui/Checkbox.tsx +45 -0
- package/src/ui/Collapsible.stories.tsx +91 -0
- package/src/ui/Collapsible.tsx +52 -0
- package/src/ui/Colors.stories.tsx +67 -0
- package/src/ui/Dialog.stories.tsx +29 -0
- package/src/ui/Dialog.tsx +56 -0
- package/src/ui/Dropdown.tsx +66 -0
- package/src/ui/Field.stories.tsx +181 -0
- package/src/ui/Field.tsx +108 -0
- package/src/ui/Icon.stories.tsx +192 -0
- package/src/ui/Icon.tsx +42 -0
- package/src/ui/IconRegistry.tsx +189 -0
- package/src/ui/Input.stories.tsx +67 -0
- package/src/ui/Input.tsx +43 -0
- package/src/ui/Label.stories.tsx +42 -0
- package/src/ui/Label.tsx +26 -0
- package/src/ui/NumberField.stories.tsx +86 -0
- package/src/ui/NumberField.tsx +116 -0
- package/src/ui/Popover.tsx +42 -0
- package/src/ui/Select.stories.tsx +74 -0
- package/src/ui/Select.tsx +122 -0
- package/src/ui/Separator.stories.tsx +61 -0
- package/src/ui/Separator.tsx +28 -0
- package/src/ui/SettingsPanel.stories.tsx +83 -0
- package/src/ui/SettingsPanel.tsx +81 -0
- package/src/ui/Skeleton.stories.tsx +43 -0
- package/src/ui/Skeleton.tsx +15 -0
- package/src/ui/Slider.stories.tsx +140 -0
- package/src/ui/Slider.tsx +95 -0
- package/src/ui/SliderWithNumberField.stories.tsx +101 -0
- package/src/ui/SliderWithNumberField.tsx +88 -0
- package/src/ui/Switch.stories.tsx +81 -0
- package/src/ui/Switch.tsx +60 -0
- package/src/ui/TabRadio.stories.tsx +153 -0
- package/src/ui/TabRadio.tsx +68 -0
- package/src/ui/TabSelection.stories.tsx +44 -0
- package/src/ui/TabSelection.tsx +91 -0
- package/src/ui/TextArea.stories.tsx +64 -0
- package/src/ui/TextArea.tsx +24 -0
- package/src/ui/Tooltip.stories.tsx +84 -0
- package/src/ui/Tooltip.tsx +61 -0
- package/src/ui/Typography.stories.tsx +87 -0
- package/src/ui/Typography.tsx +80 -0
- package/src/ui/index.ts +28 -0
- package/src/ui/utils.ts +6 -0
- package/tsconfig.json +12 -0
- package/vitest.config.ts +36 -0
- package/vitest.shims.d.ts +1 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Icon, IconName } from "./Icon";
|
|
3
|
+
import { Text } from "./Typography";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Icon> = {
|
|
6
|
+
title: "UI/Icon",
|
|
7
|
+
component: Icon,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
size: {
|
|
11
|
+
control: "select",
|
|
12
|
+
options: ["sm", "md", "lg", "xl"],
|
|
13
|
+
},
|
|
14
|
+
name: {
|
|
15
|
+
control: "select",
|
|
16
|
+
options: [
|
|
17
|
+
"arrowDown",
|
|
18
|
+
"arrowDownToLine",
|
|
19
|
+
"arrowDownTray",
|
|
20
|
+
"arrowPath",
|
|
21
|
+
"arrowRightOnRectangle",
|
|
22
|
+
"arrowUp",
|
|
23
|
+
"arrowUpFromLine",
|
|
24
|
+
"arrowUpTray",
|
|
25
|
+
"arrowsPointingIn",
|
|
26
|
+
"arrowsPointingOut",
|
|
27
|
+
"arrowsRightLeft",
|
|
28
|
+
"arrowsUpDown",
|
|
29
|
+
"check",
|
|
30
|
+
"checkCircle",
|
|
31
|
+
"chevronDownSmall",
|
|
32
|
+
"chevronDownTable",
|
|
33
|
+
"chevronRight",
|
|
34
|
+
"chevronUpSmall",
|
|
35
|
+
"chevronUpTable",
|
|
36
|
+
"clipboard",
|
|
37
|
+
"close",
|
|
38
|
+
"cloudArrowUp",
|
|
39
|
+
"code",
|
|
40
|
+
"document",
|
|
41
|
+
"edit",
|
|
42
|
+
"envelope",
|
|
43
|
+
"exclamationCircle",
|
|
44
|
+
"exclamationTriangle",
|
|
45
|
+
"export",
|
|
46
|
+
"externalLink",
|
|
47
|
+
"eye",
|
|
48
|
+
"folder",
|
|
49
|
+
"google",
|
|
50
|
+
"home",
|
|
51
|
+
"import",
|
|
52
|
+
"lock",
|
|
53
|
+
"lockClosed",
|
|
54
|
+
"magnifyingGlassPlus",
|
|
55
|
+
"megaphone",
|
|
56
|
+
"minus",
|
|
57
|
+
"pencilSquare",
|
|
58
|
+
"pencilSquareContinued",
|
|
59
|
+
"play",
|
|
60
|
+
"plus",
|
|
61
|
+
"questionMarkCircle",
|
|
62
|
+
"search",
|
|
63
|
+
"shoppingCart",
|
|
64
|
+
"speakerWave",
|
|
65
|
+
"squares",
|
|
66
|
+
"tableCells",
|
|
67
|
+
"userCircle",
|
|
68
|
+
"x",
|
|
69
|
+
"xCircle",
|
|
70
|
+
"zap",
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default meta;
|
|
77
|
+
type Story = StoryObj<typeof Icon>;
|
|
78
|
+
|
|
79
|
+
const CheckPath = <path d="M20 6 9 17l-5-5" />;
|
|
80
|
+
const XPath = <path d="M18 6 6 18M6 6l12 12" />;
|
|
81
|
+
|
|
82
|
+
export const Default: Story = {
|
|
83
|
+
args: {
|
|
84
|
+
children: CheckPath,
|
|
85
|
+
className: "text-green-500",
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const NamedIcons: Story = {
|
|
90
|
+
render: () => (
|
|
91
|
+
<div className="grid grid-cols-6 gap-4 p-4">
|
|
92
|
+
{[
|
|
93
|
+
"arrowDown",
|
|
94
|
+
"arrowDownToLine",
|
|
95
|
+
"arrowDownTray",
|
|
96
|
+
"arrowPath",
|
|
97
|
+
"arrowRightOnRectangle",
|
|
98
|
+
"arrowUp",
|
|
99
|
+
"arrowUpFromLine",
|
|
100
|
+
"arrowUpTray",
|
|
101
|
+
"arrowsPointingIn",
|
|
102
|
+
"arrowsPointingOut",
|
|
103
|
+
"arrowsRightLeft",
|
|
104
|
+
"arrowsUpDown",
|
|
105
|
+
"check",
|
|
106
|
+
"checkCircle",
|
|
107
|
+
"chevronDownSmall",
|
|
108
|
+
"chevronDownTable",
|
|
109
|
+
"chevronRight",
|
|
110
|
+
"chevronUpSmall",
|
|
111
|
+
"chevronUpTable",
|
|
112
|
+
"clipboard",
|
|
113
|
+
"close",
|
|
114
|
+
"cloudArrowUp",
|
|
115
|
+
"code",
|
|
116
|
+
"document",
|
|
117
|
+
"edit",
|
|
118
|
+
"envelope",
|
|
119
|
+
"exclamationCircle",
|
|
120
|
+
"exclamationTriangle",
|
|
121
|
+
"export",
|
|
122
|
+
"externalLink",
|
|
123
|
+
"eye",
|
|
124
|
+
"folder",
|
|
125
|
+
"google",
|
|
126
|
+
"home",
|
|
127
|
+
"import",
|
|
128
|
+
"lock",
|
|
129
|
+
"lockClosed",
|
|
130
|
+
"magnifyingGlassPlus",
|
|
131
|
+
"megaphone",
|
|
132
|
+
"minus",
|
|
133
|
+
"pencilSquare",
|
|
134
|
+
"pencilSquareContinued",
|
|
135
|
+
"play",
|
|
136
|
+
"plus",
|
|
137
|
+
"questionMarkCircle",
|
|
138
|
+
"search",
|
|
139
|
+
"shoppingCart",
|
|
140
|
+
"speakerWave",
|
|
141
|
+
"squares",
|
|
142
|
+
"tableCells",
|
|
143
|
+
"userCircle",
|
|
144
|
+
"x",
|
|
145
|
+
"xCircle",
|
|
146
|
+
"zap",
|
|
147
|
+
].map((name) => (
|
|
148
|
+
<div key={name} className="flex flex-col items-center">
|
|
149
|
+
<Icon name={name as IconName} />
|
|
150
|
+
<Text variant="small">{name}</Text>
|
|
151
|
+
</div>
|
|
152
|
+
))}
|
|
153
|
+
</div>
|
|
154
|
+
),
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const Variations: Story = {
|
|
158
|
+
render: () => (
|
|
159
|
+
<div className="flex flex-col gap-12 p-4">
|
|
160
|
+
<div className="space-y-4">
|
|
161
|
+
<Text variant="small" className="font-bold underline uppercase">
|
|
162
|
+
Different Sizes
|
|
163
|
+
</Text>
|
|
164
|
+
<div className="flex items-end gap-4">
|
|
165
|
+
<Icon size="sm">{CheckPath}</Icon>
|
|
166
|
+
<Icon size="md">{CheckPath}</Icon>
|
|
167
|
+
<Icon size="lg">{CheckPath}</Icon>
|
|
168
|
+
<Icon size="xl">{CheckPath}</Icon>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
<div className="space-y-4">
|
|
172
|
+
<Text variant="small" className="font-bold underline uppercase">
|
|
173
|
+
Different Content & Colors
|
|
174
|
+
</Text>
|
|
175
|
+
<div className="flex gap-4">
|
|
176
|
+
<Icon className="text-red-500">{XPath}</Icon>
|
|
177
|
+
<Icon className="text-primary">{CheckPath}</Icon>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
<div className="space-y-4">
|
|
181
|
+
<Text variant="small" className="font-bold underline uppercase">
|
|
182
|
+
Using Named Icons
|
|
183
|
+
</Text>
|
|
184
|
+
<div className="flex gap-4">
|
|
185
|
+
<Icon name="check" className="text-green-500" />
|
|
186
|
+
<Icon name="x" className="text-red-500" />
|
|
187
|
+
<Icon name="plus" className="text-blue-500" />
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
),
|
|
192
|
+
};
|
package/src/ui/Icon.tsx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "./utils";
|
|
3
|
+
import { IconName, icons } from "./IconRegistry";
|
|
4
|
+
|
|
5
|
+
export type { IconName };
|
|
6
|
+
|
|
7
|
+
export interface IconProps extends React.SVGProps<SVGSVGElement> {
|
|
8
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
9
|
+
name?: IconName;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Icon = React.forwardRef<SVGSVGElement, IconProps>(
|
|
13
|
+
({ className, size = "md", name, children, ...props }, ref) => {
|
|
14
|
+
const sizes = {
|
|
15
|
+
sm: "w-3 h-3",
|
|
16
|
+
md: "w-4 h-4",
|
|
17
|
+
lg: "w-6 h-6",
|
|
18
|
+
xl: "w-8 h-8",
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const iconContent = name ? icons[name] : children;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<svg
|
|
25
|
+
ref={ref}
|
|
26
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
+
viewBox="0 0 24 24"
|
|
28
|
+
fill="none"
|
|
29
|
+
stroke="currentColor"
|
|
30
|
+
strokeWidth="1.5"
|
|
31
|
+
strokeLinecap="round"
|
|
32
|
+
strokeLinejoin="round"
|
|
33
|
+
className={cn(sizes[size], "inline-block", className)}
|
|
34
|
+
{...props}
|
|
35
|
+
>
|
|
36
|
+
{iconContent}
|
|
37
|
+
</svg>
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
Icon.displayName = "Icon";
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Raw path data for icons, useful for non-React contexts (like PixiJS Graphics.svg)
|
|
5
|
+
*/
|
|
6
|
+
export const iconPaths = {
|
|
7
|
+
check: "M20 6 9 17l-5-5",
|
|
8
|
+
x: "M18 6 6 18M6 6l12 12",
|
|
9
|
+
edit: "M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125",
|
|
10
|
+
close: "M6 18L18 6M6 6l12 12",
|
|
11
|
+
plus: "M12 4.5v15m7.5-7.5h-15",
|
|
12
|
+
arrowDown: "M19.5 13.5L12 21m0 0l-7.5-7.5M12 21V3", // Points DOWN
|
|
13
|
+
arrowUp: "M4.5 10.5L12 3m0 0l7.5 7.5M12 3v18", // Points UP
|
|
14
|
+
clipboard:
|
|
15
|
+
"M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 0 1-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 0 1 1.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 0 0-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 0 1-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H9.75",
|
|
16
|
+
cloudArrowUp:
|
|
17
|
+
"M12 16.5V9.75m0 0 3 3m-3-3-3 3M6.75 19.5a4.5 4.5 0 0 1-1.41-8.775 5.25 5.25 0 0 1 10.233-2.33 3 3 0 0 1 3.758 3.848A3.752 3.752 0 0 1 18 19.5H6.75Z",
|
|
18
|
+
arrowDownToLine: "M9 12l3 3m0 0 3-3m-3 3V2.25",
|
|
19
|
+
folder:
|
|
20
|
+
"M9 8.25H7.5a2.25 2.25 0 0 0-2.25 2.25v9a2.25 2.25 0 0 0 2.25 2.25h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25H15m0-3-3-3m0 0-3 3m3-3V15",
|
|
21
|
+
arrowUpFromLine:
|
|
22
|
+
"M9 8.25H7.5a2.25 2.25 0 0 0-2.25 2.25v9a2.25 2.25 0 0 0 2.25 2.25h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25H15m0-3-3-3m0 0-3 3m3-3V15",
|
|
23
|
+
squares:
|
|
24
|
+
"M2.25 7.125C2.25 6.504 2.754 6 3.375 6h6c.621 0 1.125.504 1.125 1.125v3.75c0 .621-.504 1.125-1.125 1.125h-6a1.125 1.125 0 0 1-1.125-1.125v-3.75ZM14.25 8.625c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v8.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 0 1-1.125-1.125v-8.25ZM3.75 16.125c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v2.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 0 1-1.125-1.125v-2.25Z",
|
|
25
|
+
tableCells:
|
|
26
|
+
"M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5",
|
|
27
|
+
arrowsRightLeft:
|
|
28
|
+
"M7.5 21 3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5",
|
|
29
|
+
document:
|
|
30
|
+
"M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z",
|
|
31
|
+
externalLink:
|
|
32
|
+
"M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25",
|
|
33
|
+
lock: "M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z",
|
|
34
|
+
shoppingCart:
|
|
35
|
+
"M2.25 3h1.386c.51 0 .955.343 1.087.835l.383 1.437M7.5 14.25a3 3 0 00-3 3h15.75m-12.75-3h11.218c1.121-2.3 2.1-4.684 2.924-7.138a60.114 60.114 0 00-16.536-1.84M7.5 14.25L5.106 5.272M6 20.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm12.75 0a.75.75 0 11-1.5 0 .75.75 0 011.5 0z",
|
|
36
|
+
minus: "M5 12h14",
|
|
37
|
+
pencilSquare:
|
|
38
|
+
"M21.731 2.269a2.625 2.625 0 0 0-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 0 0 0-3.712ZM19.513 8.199l-3.712-3.712-8.4 8.4a5.25 5.25 0 0 0-1.32 2.214l-.8 2.685a.75.75 0 0 0 .933.933l2.685-.8a5.25 5.25 0 0 0 2.214-1.32l8.4-8.4Z",
|
|
39
|
+
pencilSquareContinued:
|
|
40
|
+
"M5.25 5.25a3 3 0 0 0-3 3v10.5a3 3 0 0 0 3 3h10.5a3 3 0 0 0 3-3V13.5a.75.75 0 0 0-1.5 0v5.25a1.5 1.5 0 0 1-1.5 1.5H5.25a1.5 1.5 0 0 1-1.5-1.5V8.25a1.5 1.5 0 0 1 1.5-1.5h5.25a.75.75 0 0 0 0-1.5H5.25Z",
|
|
41
|
+
chevronUpSmall: "M4.5 15.75l7.5-7.5 7.5 7.5", // Points UP
|
|
42
|
+
chevronDownSmall: "M19.5 8.25l-7.5 7.5-7.5-7.5", // Points DOWN
|
|
43
|
+
chevronUpTable: "M8.25 6.75 12 3m0 0 3.75 3.75M12 3v18", // Points UP
|
|
44
|
+
chevronDownTable: "M15.75 17.25 12 21m0 0-3.75-3.75M12 21V3", // Points DOWN
|
|
45
|
+
speakerWave:
|
|
46
|
+
"M19.114 5.636a9 9 0 010 12.728M16.463 8.288a5.25 5.25 0 010 7.424M6.75 8.25l4.72-4.72a.75.75 0 011.28.53v15.88a.75.75 0 01-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 012.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75z",
|
|
47
|
+
zap: "m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75Z",
|
|
48
|
+
code: "M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5",
|
|
49
|
+
questionMarkCircle:
|
|
50
|
+
"M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z",
|
|
51
|
+
search:
|
|
52
|
+
"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z",
|
|
53
|
+
exclamationCircle:
|
|
54
|
+
"M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z",
|
|
55
|
+
exclamationTriangle:
|
|
56
|
+
"M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z",
|
|
57
|
+
checkCircle:
|
|
58
|
+
"M9 12.75 11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 0 1-1.043 3.296 3.745 3.745 0 0 1-3.296 1.043A3.745 3.745 0 0 1 12 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 0 1-3.296-1.043 3.745 3.745 0 0 1-1.043-3.296A3.745 3.745 0 0 1 3 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 0 1 1.043-3.296 3.746 3.746 0 0 1 3.296-1.043A3.746 3.746 0 0 1 12 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 0 1 3.296 1.043 3.746 3.746 0 0 1 1.043 3.296A3.745 3.745 0 0 1 21 12Z",
|
|
59
|
+
megaphone:
|
|
60
|
+
"M10.34 15.84c-.688-.06-1.386-.09-2.09-.09H7.5a4.5 4.5 0 1 1 0-9h.75c.704 0 1.402-.03 2.09-.09m0 9.18c.253.962.584 1.892.985 2.783.247.55.06 1.21-.463 1.511l-.657.38c-.551.318-1.26.117-1.527-.461a20.845 20.845 0 0 1-1.44-4.282m3.102.069a18.03 18.03 0 0 1-.59-4.59c0-1.586.205-3.124.59-4.59m0 9.18a23.848 23.848 0 0 1 8.835 2.535M10.34 6.66a23.847 23.847 0 0 0 8.835-2.535m0 0A23.74 23.74 0 0 0 18.795 3m.38 1.125a23.91 23.91 0 0 1 1.014 5.395m-1.014 8.855c-.118.38-.245.754-.38 1.125m.38-1.125a23.91 23.91 0 0 0 1.014-5.395m0-3.46c.495.413.811 1.035.811 1.73 0 .695-.316 1.317-.811 1.73m0-3.46a24.347 24.347 0 0 1 0 3.46",
|
|
61
|
+
xCircle:
|
|
62
|
+
"m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z",
|
|
63
|
+
arrowsPointingIn:
|
|
64
|
+
"M9 9V4.5M9 9H4.5M9 9 3.75 3.75M9 15v4.5M9 15H4.5M9 15l-5.25 5.25M15 9h4.5M15 9V4.5M15 9l5.25-5.25M15 15h4.5M15 15v4.5m0-4.5 5.25 5.25",
|
|
65
|
+
arrowsPointingOut:
|
|
66
|
+
"M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15",
|
|
67
|
+
arrowPath:
|
|
68
|
+
"M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 0 0-3.7-3.7 48.678 48.678 0 0 0-7.324 0 4.006 4.006 0 0 0-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3-3-3m-12 3c0 1.232.046 2.453.138 3.662a4.006 4.006 0 0 0 3.7 3.7 48.656 48.656 0 0 0 7.324 0 4.006 4.006 0 0 0 3.7-3.7c.017-.22.032-.441.046-.662M4.5 12l3 3m-3-3-3 3",
|
|
69
|
+
arrowUturnLeft: "M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3",
|
|
70
|
+
magnifyingGlassPlus:
|
|
71
|
+
"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607ZM10.5 7.5v6m3-3h-6",
|
|
72
|
+
arrowsUpDown:
|
|
73
|
+
"M3 7.5 7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5",
|
|
74
|
+
envelope:
|
|
75
|
+
"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z",
|
|
76
|
+
lockClosed:
|
|
77
|
+
"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z",
|
|
78
|
+
userCircle:
|
|
79
|
+
"M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z",
|
|
80
|
+
arrowRightOnRectangle:
|
|
81
|
+
"M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15m3 0 3-3m0 0-3-3m3 3H9",
|
|
82
|
+
chevronRight: "m8.25 4.5 7.5 7.5-7.5 7.5",
|
|
83
|
+
arrowDownTray:
|
|
84
|
+
"M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3",
|
|
85
|
+
arrowUpTray:
|
|
86
|
+
"M3 7.5V5.25A2.25 2.25 0 0 1 5.25 3h13.5A2.25 2.25 0 0 1 21 5.25V7.5m-4.5 4.5L12 7.5m0 0L7.5 12m4.5-4.5v13.5",
|
|
87
|
+
import:
|
|
88
|
+
"M9 8.25H7.5a2.25 2.25 0 0 0-2.25 2.25v9a2.25 2.25 0 0 0 2.25 2.25h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25H15M9 12l3 3m0 0 3-3m-3 3V2.25",
|
|
89
|
+
export:
|
|
90
|
+
"M9 8.25H7.5a2.25 2.25 0 0 0-2.25 2.25v9a2.25 2.25 0 0 0 2.25 2.25h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25H15m0-3-3-3m0 0-3 3m3-3V15",
|
|
91
|
+
home: "m2.25 12 8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25",
|
|
92
|
+
play: "M5 3l14 9-14 9V3z",
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Icons that are complex React nodes
|
|
97
|
+
*/
|
|
98
|
+
export const complexIcons = {
|
|
99
|
+
eye: (
|
|
100
|
+
<>
|
|
101
|
+
<path d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
|
|
102
|
+
<path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
|
103
|
+
</>
|
|
104
|
+
),
|
|
105
|
+
google: (
|
|
106
|
+
<g transform="matrix(1, 0, 0, 1, 27.009001, -39.238998)">
|
|
107
|
+
<path
|
|
108
|
+
fill="#4285F4"
|
|
109
|
+
stroke="none"
|
|
110
|
+
d="M -3.264 51.509 C -3.264 50.719 -3.334 49.969 -3.454 49.239 L -14.754 49.239 L -14.754 53.749 L -8.284 53.749 C -8.574 55.229 -9.424 56.479 -10.684 57.329 L -10.684 60.329 L -6.824 60.329 C -4.564 58.239 -3.264 55.159 -3.264 51.509 Z"
|
|
111
|
+
/>
|
|
112
|
+
<path
|
|
113
|
+
fill="#34A853"
|
|
114
|
+
stroke="none"
|
|
115
|
+
d="M -14.754 63.239 C -11.514 63.239 -8.804 62.159 -6.824 60.329 L -10.684 57.329 C -11.764 58.049 -13.134 58.489 -14.754 58.489 C -17.884 58.489 -20.534 56.379 -21.484 53.529 L -25.464 53.529 L -25.464 56.619 C -23.494 60.539 -19.444 63.239 -14.754 63.239 Z"
|
|
116
|
+
/>
|
|
117
|
+
<path
|
|
118
|
+
fill="#FBBC05"
|
|
119
|
+
stroke="none"
|
|
120
|
+
d="M -21.484 53.529 C -21.734 52.809 -21.864 52.039 -21.864 51.239 C -21.864 50.439 -21.724 49.669 -21.484 48.949 L -21.484 45.859 L -25.464 45.859 C -26.284 47.479 -26.754 49.299 -26.754 51.239 C -26.754 53.179 -26.284 54.999 -25.464 56.619 L -21.484 53.529 Z"
|
|
121
|
+
/>
|
|
122
|
+
<path
|
|
123
|
+
fill="#EA4335"
|
|
124
|
+
stroke="none"
|
|
125
|
+
d="M -14.754 43.989 C -12.984 43.989 -11.404 44.599 -10.154 45.789 L -6.734 42.369 C -8.804 40.429 -11.514 39.239 -14.754 39.239 C -19.444 39.239 -23.494 41.939 -25.464 45.859 L -21.484 48.949 C -20.534 46.099 -17.884 43.989 -14.754 43.989 Z"
|
|
126
|
+
/>
|
|
127
|
+
</g>
|
|
128
|
+
),
|
|
129
|
+
} as const;
|
|
130
|
+
|
|
131
|
+
export type IconName = keyof typeof iconPaths | keyof typeof complexIcons;
|
|
132
|
+
|
|
133
|
+
export const icons: Record<IconName, React.ReactNode> = {
|
|
134
|
+
check: <path d={iconPaths.check} />,
|
|
135
|
+
x: <path d={iconPaths.x} />,
|
|
136
|
+
edit: <path d={iconPaths.edit} />,
|
|
137
|
+
close: <path d={iconPaths.close} />,
|
|
138
|
+
plus: <path d={iconPaths.plus} />,
|
|
139
|
+
arrowDown: <path d={iconPaths.arrowDown} />,
|
|
140
|
+
arrowUp: <path d={iconPaths.arrowUp} />,
|
|
141
|
+
clipboard: <path d={iconPaths.clipboard} />,
|
|
142
|
+
cloudArrowUp: <path d={iconPaths.cloudArrowUp} />,
|
|
143
|
+
arrowDownToLine: <path d={iconPaths.arrowDownToLine} />,
|
|
144
|
+
folder: <path d={iconPaths.folder} />,
|
|
145
|
+
arrowUpFromLine: <path d={iconPaths.arrowUpFromLine} />,
|
|
146
|
+
arrowRightOnRectangle: <path d={iconPaths.arrowRightOnRectangle} />,
|
|
147
|
+
squares: <path d={iconPaths.squares} />,
|
|
148
|
+
tableCells: <path d={iconPaths.tableCells} />,
|
|
149
|
+
arrowsRightLeft: <path d={iconPaths.arrowsRightLeft} />,
|
|
150
|
+
document: <path d={iconPaths.document} />,
|
|
151
|
+
externalLink: <path d={iconPaths.externalLink} />,
|
|
152
|
+
lock: <path d={iconPaths.lock} />,
|
|
153
|
+
shoppingCart: <path d={iconPaths.shoppingCart} />,
|
|
154
|
+
minus: <path d={iconPaths.minus} />,
|
|
155
|
+
pencilSquare: <path d={iconPaths.pencilSquare} />,
|
|
156
|
+
pencilSquareContinued: <path d={iconPaths.pencilSquareContinued} />,
|
|
157
|
+
chevronDownSmall: <path d={iconPaths.chevronDownSmall} />,
|
|
158
|
+
chevronUpSmall: <path d={iconPaths.chevronUpSmall} />,
|
|
159
|
+
chevronDownTable: <path d={iconPaths.chevronDownTable} />,
|
|
160
|
+
chevronUpTable: <path d={iconPaths.chevronUpTable} />,
|
|
161
|
+
speakerWave: <path d={iconPaths.speakerWave} />,
|
|
162
|
+
zap: <path d={iconPaths.zap} />,
|
|
163
|
+
code: <path d={iconPaths.code} />,
|
|
164
|
+
questionMarkCircle: <path d={iconPaths.questionMarkCircle} />,
|
|
165
|
+
search: <path d={iconPaths.search} />,
|
|
166
|
+
exclamationCircle: <path d={iconPaths.exclamationCircle} />,
|
|
167
|
+
exclamationTriangle: <path d={iconPaths.exclamationTriangle} />,
|
|
168
|
+
checkCircle: <path d={iconPaths.checkCircle} />,
|
|
169
|
+
megaphone: <path d={iconPaths.megaphone} />,
|
|
170
|
+
xCircle: <path d={iconPaths.xCircle} />,
|
|
171
|
+
arrowsPointingIn: <path d={iconPaths.arrowsPointingIn} />,
|
|
172
|
+
arrowsPointingOut: <path d={iconPaths.arrowsPointingOut} />,
|
|
173
|
+
arrowPath: <path d={iconPaths.arrowPath} />,
|
|
174
|
+
arrowUturnLeft: <path d={iconPaths.arrowUturnLeft} />,
|
|
175
|
+
magnifyingGlassPlus: <path d={iconPaths.magnifyingGlassPlus} />,
|
|
176
|
+
arrowsUpDown: <path d={iconPaths.arrowsUpDown} />,
|
|
177
|
+
envelope: <path d={iconPaths.envelope} />,
|
|
178
|
+
lockClosed: <path d={iconPaths.lockClosed} />,
|
|
179
|
+
userCircle: <path d={iconPaths.userCircle} />,
|
|
180
|
+
chevronRight: <path d={iconPaths.chevronRight} />,
|
|
181
|
+
arrowDownTray: <path d={iconPaths.arrowDownTray} />,
|
|
182
|
+
arrowUpTray: <path d={iconPaths.arrowUpTray} />,
|
|
183
|
+
import: <path d={iconPaths.import} />,
|
|
184
|
+
export: <path d={iconPaths.export} />,
|
|
185
|
+
home: <path d={iconPaths.home} />,
|
|
186
|
+
play: <path d={iconPaths.play} />,
|
|
187
|
+
eye: complexIcons.eye,
|
|
188
|
+
google: complexIcons.google,
|
|
189
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Input } from "./Input";
|
|
3
|
+
import { Heading, Text } from "./Typography";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Input> = {
|
|
6
|
+
title: "UI/Input",
|
|
7
|
+
component: Input,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
disabled: { control: "boolean" },
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof Input>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
placeholder: "Enter text...",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const Variations: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<div className="flex flex-col gap-8 p-4 max-w-sm">
|
|
26
|
+
<div className="space-y-4">
|
|
27
|
+
<Heading level={4} className="text-sm font-medium text-black uppercase">
|
|
28
|
+
Input Styles
|
|
29
|
+
</Heading>
|
|
30
|
+
<div className="space-y-4">
|
|
31
|
+
<div className="space-y-1">
|
|
32
|
+
<Text variant="small" className="font-bold">
|
|
33
|
+
With Placeholder
|
|
34
|
+
</Text>
|
|
35
|
+
<Input placeholder="Type here..." />
|
|
36
|
+
</div>
|
|
37
|
+
<div className="space-y-1">
|
|
38
|
+
<Text variant="small" className="font-bold">
|
|
39
|
+
With Value
|
|
40
|
+
</Text>
|
|
41
|
+
<Input defaultValue="Initial value" />
|
|
42
|
+
</div>
|
|
43
|
+
<div className="space-y-1">
|
|
44
|
+
<Text variant="small" className="font-bold">
|
|
45
|
+
Password Type
|
|
46
|
+
</Text>
|
|
47
|
+
<Input type="password" placeholder="Password..." />
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div className="space-y-4">
|
|
53
|
+
<Heading level={4} className="text-sm font-medium text-black uppercase">
|
|
54
|
+
States
|
|
55
|
+
</Heading>
|
|
56
|
+
<div className="space-y-4">
|
|
57
|
+
<div className="space-y-1">
|
|
58
|
+
<Text variant="small" className="font-bold">
|
|
59
|
+
Disabled
|
|
60
|
+
</Text>
|
|
61
|
+
<Input disabled defaultValue="Can't edit me" />
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
),
|
|
67
|
+
};
|
package/src/ui/Input.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Input as BaseInput } from "@base-ui/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { cn } from "./utils";
|
|
4
|
+
|
|
5
|
+
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
6
|
+
leftIcon?: React.ReactNode;
|
|
7
|
+
rightIcon?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
11
|
+
({ className, leftIcon, rightIcon, id, ...props }, ref) => {
|
|
12
|
+
const inputClasses = cn(
|
|
13
|
+
"block w-full rounded-md border-0 px-1.5 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary sm:text-sm sm:leading-6 bg-primary/10 appearance-none",
|
|
14
|
+
leftIcon && "pl-10",
|
|
15
|
+
rightIcon && "pr-10",
|
|
16
|
+
className,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (!leftIcon && !rightIcon) {
|
|
20
|
+
return (
|
|
21
|
+
<BaseInput ref={ref} id={id} className={inputClasses} {...props} />
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="relative">
|
|
27
|
+
{leftIcon && (
|
|
28
|
+
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
29
|
+
<span className="text-gray-500 sm:text-sm">{leftIcon}</span>
|
|
30
|
+
</div>
|
|
31
|
+
)}
|
|
32
|
+
<BaseInput ref={ref} id={id} className={inputClasses} {...props} />
|
|
33
|
+
{rightIcon && (
|
|
34
|
+
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
|
35
|
+
<span className="text-gray-500 sm:text-sm">{rightIcon}</span>
|
|
36
|
+
</div>
|
|
37
|
+
)}
|
|
38
|
+
</div>
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
Input.displayName = "Input";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Label } from "./Label";
|
|
3
|
+
import { Input } from "./Input";
|
|
4
|
+
import { Text } from "./Typography";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Label> = {
|
|
7
|
+
title: "UI/Label",
|
|
8
|
+
component: Label,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
args: {
|
|
11
|
+
children: "Label Text",
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
type Story = StoryObj<typeof Label>;
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {};
|
|
19
|
+
|
|
20
|
+
export const Variations: Story = {
|
|
21
|
+
render: () => (
|
|
22
|
+
<div className="flex flex-col gap-12 p-4">
|
|
23
|
+
<div className="space-y-2">
|
|
24
|
+
<Text variant="small" className="font-bold underline uppercase">
|
|
25
|
+
With Tooltip
|
|
26
|
+
</Text>
|
|
27
|
+
<Label tooltip="Extra information here.">Hover the help icon</Label>
|
|
28
|
+
</div>
|
|
29
|
+
<div className="space-y-2">
|
|
30
|
+
<Text variant="small" className="font-bold underline uppercase">
|
|
31
|
+
With Associated Input
|
|
32
|
+
</Text>
|
|
33
|
+
<div className="space-y-1">
|
|
34
|
+
<Label htmlFor="v-input" tooltip="This is required">
|
|
35
|
+
Email Address
|
|
36
|
+
</Label>
|
|
37
|
+
<Input id="v-input" placeholder="user@example.com" />
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
),
|
|
42
|
+
};
|
package/src/ui/Label.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cn } from "./utils";
|
|
3
|
+
import { HelperTooltip } from "./Tooltip";
|
|
4
|
+
|
|
5
|
+
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
tooltip?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function Label({ children, tooltip, className, ...props }: LabelProps) {
|
|
12
|
+
return (
|
|
13
|
+
<label
|
|
14
|
+
className={cn(
|
|
15
|
+
"relative block text-sm font-bold leading-6 text-gray-600 mb-1 group-focus-within:text-gray-800",
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
>
|
|
20
|
+
<div className="flex items-center gap-1">
|
|
21
|
+
{children}
|
|
22
|
+
{tooltip && <HelperTooltip content={tooltip} />}
|
|
23
|
+
</div>
|
|
24
|
+
</label>
|
|
25
|
+
);
|
|
26
|
+
}
|