Skip to content

Commit 5051b63

Browse files
committed
fix: add inline-block to popover so it doesn't grow. feat: add textarea
1 parent 4175fa0 commit 5051b63

File tree

4 files changed

+122
-93
lines changed

4 files changed

+122
-93
lines changed

packages/@holaplexui-playground/pages/form.tsx

Lines changed: 93 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,72 @@
1-
import { Form, Icon, Placement } from '@holaplex/ui-library-react';
2-
import clsx from 'clsx';
3-
import { watch } from 'fs';
4-
import { useCallback, useState } from 'react';
5-
import { useDropzone } from 'react-dropzone';
6-
import { Controller, useForm } from 'react-hook-form';
7-
import useUpload from '../hooks/useUpload';
1+
import { Form, Icon, Placement } from "@holaplex/ui-library-react";
2+
import clsx from "clsx";
3+
import { watch } from "fs";
4+
import { useCallback, useState } from "react";
5+
import { useDropzone } from "react-dropzone";
6+
import { Controller, useForm } from "react-hook-form";
7+
import useUpload from "../hooks/useUpload";
88

9-
function HidePasswordIcon({ size = 16, color = 'none', className = '' }) {
9+
function HidePasswordIcon({ size = 16, color = "none", className = "" }) {
1010
return (
1111
<svg
1212
width={size}
1313
height={size}
14-
viewBox='0 0 16 16'
14+
viewBox="0 0 16 16"
1515
fill={color}
1616
className={className}
17-
xmlns='http://www.w3.org/2000/svg'
17+
xmlns="http://www.w3.org/2000/svg"
1818
>
1919
<path
20-
d='M9.41452 6.5865C10.1952 7.36717 10.1952 8.6345 9.41452 9.4165C8.63386 10.1972 7.36652 10.1972 6.58452 9.4165C5.80386 8.63583 5.80386 7.3685 6.58452 6.5865C7.36652 5.8045 8.63319 5.8045 9.41452 6.5865'
21-
stroke='black'
22-
strokeLinecap='round'
23-
strokeLinejoin='round'
20+
d="M9.41452 6.5865C10.1952 7.36717 10.1952 8.6345 9.41452 9.4165C8.63386 10.1972 7.36652 10.1972 6.58452 9.4165C5.80386 8.63583 5.80386 7.3685 6.58452 6.5865C7.36652 5.8045 8.63319 5.8045 9.41452 6.5865"
21+
stroke="black"
22+
strokeLinecap="round"
23+
strokeLinejoin="round"
2424
/>
2525
<path
26-
fill-rule='evenodd'
27-
clip-rule='evenodd'
28-
d='M2 7.99992C2 7.56059 2.10133 7.12592 2.29733 6.72525V6.72525C3.30733 4.66059 5.53933 3.33325 8 3.33325C10.4607 3.33325 12.6927 4.66059 13.7027 6.72525V6.72525C13.8987 7.12592 14 7.56059 14 7.99992C14 8.43925 13.8987 8.87392 13.7027 9.27458V9.27458C12.6927 11.3393 10.4607 12.6666 8 12.6666C5.53933 12.6666 3.30733 11.3393 2.29733 9.27458V9.27458C2.10133 8.87392 2 8.43925 2 7.99992Z'
29-
stroke='black'
30-
strokeLinecap='round'
31-
strokeLinejoin='round'
26+
fill-rule="evenodd"
27+
clip-rule="evenodd"
28+
d="M2 7.99992C2 7.56059 2.10133 7.12592 2.29733 6.72525V6.72525C3.30733 4.66059 5.53933 3.33325 8 3.33325C10.4607 3.33325 12.6927 4.66059 13.7027 6.72525V6.72525C13.8987 7.12592 14 7.56059 14 7.99992C14 8.43925 13.8987 8.87392 13.7027 9.27458V9.27458C12.6927 11.3393 10.4607 12.6666 8 12.6666C5.53933 12.6666 3.30733 11.3393 2.29733 9.27458V9.27458C2.10133 8.87392 2 8.43925 2 7.99992Z"
29+
stroke="black"
30+
strokeLinecap="round"
31+
strokeLinejoin="round"
3232
/>
3333
</svg>
3434
);
3535
}
3636

37-
function ShowPasswordIcon({ size = 16, color = 'none', className = '' }) {
37+
function ShowPasswordIcon({ size = 16, color = "none", className = "" }) {
3838
return (
3939
<svg
4040
width={size}
4141
height={size}
42-
viewBox='0 0 16 16'
42+
viewBox="0 0 16 16"
4343
fill={color}
4444
className={className}
45-
xmlns='http://www.w3.org/2000/svg'
45+
xmlns="http://www.w3.org/2000/svg"
4646
>
4747
<path
48-
d='M9.70514 9.03858C9.27877 9.75749 8.45061 10.1358 7.62805 9.98746C6.80549 9.83911 6.16168 9.1953 6.01333 8.37274C5.86497 7.55018 6.2433 6.72202 6.96221 6.29565'
49-
stroke='black'
50-
strokeLinecap='round'
51-
strokeLinejoin='round'
48+
d="M9.70514 9.03858C9.27877 9.75749 8.45061 10.1358 7.62805 9.98746C6.80549 9.83911 6.16168 9.1953 6.01333 8.37274C5.86497 7.55018 6.2433 6.72202 6.96221 6.29565"
49+
stroke="black"
50+
strokeLinecap="round"
51+
strokeLinejoin="round"
5252
/>
5353
<path
54-
d='M11.9973 11.3309C10.8474 12.203 9.44277 12.6731 7.99956 12.6687C5.60816 12.7113 3.39859 11.397 2.29452 9.2753C1.89792 8.47142 1.89792 7.52878 2.29452 6.7249C2.84668 5.62531 3.72688 4.72447 4.81338 4.14697'
55-
stroke='black'
56-
strokeLinecap='round'
57-
strokeLinejoin='round'
54+
d="M11.9973 11.3309C10.8474 12.203 9.44277 12.6731 7.99956 12.6687C5.60816 12.7113 3.39859 11.397 2.29452 9.2753C1.89792 8.47142 1.89792 7.52878 2.29452 6.7249C2.84668 5.62531 3.72688 4.72447 4.81338 4.14697"
55+
stroke="black"
56+
strokeLinecap="round"
57+
strokeLinejoin="round"
5858
/>
5959
<path
60-
d='M13.6185 9.42294C13.6453 9.37225 13.6801 9.32678 13.7054 9.27513C14.102 8.47125 14.102 7.52861 13.7054 6.72473C12.6013 4.60302 10.3917 3.28874 8.00031 3.33133C7.85038 3.33133 7.70465 3.35134 7.55664 3.36109'
61-
stroke='black'
62-
strokeLinecap='round'
63-
strokeLinejoin='round'
60+
d="M13.6185 9.42294C13.6453 9.37225 13.6801 9.32678 13.7054 9.27513C14.102 8.47125 14.102 7.52861 13.7054 6.72473C12.6013 4.60302 10.3917 3.28874 8.00031 3.33133C7.85038 3.33133 7.70465 3.35134 7.55664 3.36109"
61+
stroke="black"
62+
strokeLinecap="round"
63+
strokeLinejoin="round"
6464
/>
6565
<path
66-
d='M14.0021 13.3356L2.66406 1.99756'
67-
stroke='black'
68-
strokeLinecap='round'
69-
strokeLinejoin='round'
66+
d="M14.0021 13.3356L2.66406 1.99756"
67+
stroke="black"
68+
strokeLinecap="round"
69+
strokeLinejoin="round"
7070
/>
7171
</svg>
7272
);
@@ -89,53 +89,57 @@ export default function App() {
8989
>();
9090

9191
const options = [
92-
{ name: 'Solana', id: 'sol' },
93-
{ name: 'Polygon', id: 'polygon' },
94-
{ name: 'Near', id: 'near' },
95-
{ name: 'Ethereum', id: 'eth' },
96-
{ name: 'Sui', id: 'sui' },
97-
{ name: 'Aptos', id: 'aptos' },
98-
{ name: 'Avalanche', id: 'avalanche' },
99-
{ name: 'Bitcoin', id: 'btc' },
100-
{ name: 'Cardano', id: 'ada' }
92+
{ name: "Solana", id: "sol" },
93+
{ name: "Polygon", id: "polygon" },
94+
{ name: "Near", id: "near" },
95+
{ name: "Ethereum", id: "eth" },
96+
{ name: "Sui", id: "sui" },
97+
{ name: "Aptos", id: "aptos" },
98+
{ name: "Avalanche", id: "avalanche" },
99+
{ name: "Bitcoin", id: "btc" },
100+
{ name: "Cardano", id: "ada" },
101101
];
102102

103103
const { control, setValue } = useForm<DragDropForm>();
104104
const onDrop = useCallback(
105105
(files: File[]) => {
106-
setValue('files', files, { shouldValidate: true });
106+
setValue("files", files, { shouldValidate: true });
107107
},
108108
[setValue]
109109
);
110110
const { getRootProps, getInputProps, isDragActive } = useUpload(onDrop);
111111

112112
return (
113-
<div className='w-[400px] mx-auto p-4'>
113+
<div className="w-[400px] mx-auto p-4">
114114
<Form>
115-
<Form.Label name='Email'>
116-
<Form.Input placeholder='e.g. [email protected]' />
115+
<Form.Label name="Email">
116+
<Form.Input placeholder="e.g. [email protected]" />
117117
</Form.Label>
118118

119119
<Form.Label
120-
name='Password'
121-
asideComponent={<div className='text-xs'>Forgot Password?</div>}
122-
className='mt-5'
120+
name="Password"
121+
asideComponent={<div className="text-xs">Forgot Password?</div>}
122+
className="mt-5"
123123
>
124124
<Form.Password
125-
placeholder='Enter your password'
125+
placeholder="Enter your password"
126126
showPasswordIcon={<ShowPasswordIcon />}
127127
hidePasswordIcon={<HidePasswordIcon />}
128128
/>
129129
</Form.Label>
130130

131+
<Form.Label name="Description" className="mt-5">
132+
<Form.TextArea placeholder="Enter a description" />
133+
</Form.Label>
134+
131135
<Form.Select
132-
className='mt-5'
136+
className="mt-5"
133137
onChange={(v) => {
134138
setSingleValue(v);
135139
}}
136140
value={singleValue}
137141
>
138-
<Form.Select.Button icon={<Icon.Sol />} placeholder='e.g. Solana'>
142+
<Form.Select.Button icon={<Icon.Sol />} placeholder="e.g. Solana">
139143
{singleValue?.name}
140144
</Form.Select.Button>
141145
<Form.Select.Options>
@@ -148,14 +152,14 @@ export default function App() {
148152
</Form.Select>
149153

150154
<Form.Select
151-
className='mt-5'
155+
className="mt-5"
152156
multiple
153157
onChange={(v) => {
154158
setMultiValue(v);
155159
}}
156160
value={multiValue}
157161
>
158-
<Form.Select.Button icon={<Icon.Sol />} placeholder='e.g. Solana'>
162+
<Form.Select.Button icon={<Icon.Sol />} placeholder="e.g. Solana">
159163
{multiValue && multiValue?.length > 0
160164
? multiValue[0].name
161165
: undefined}
@@ -169,9 +173,9 @@ export default function App() {
169173
</Form.Select.Options>
170174
</Form.Select>
171175

172-
<Form.Label name='Drop Image' className='mt-5'>
176+
<Form.Label name="Drop Image" className="mt-5">
173177
<Controller
174-
name='files'
178+
name="files"
175179
control={control}
176180
render={({ field: { value, onChange } }) => (
177181
<Form.DragDrop
@@ -183,15 +187,15 @@ export default function App() {
183187
>
184188
<div
185189
className={clsx(
186-
'flex items-center justify-center border border-dashed border-gray-200 cursor-pointer rounded-md',
190+
"flex items-center justify-center border border-dashed border-gray-200 cursor-pointer rounded-md",
187191
{
188-
'bg-gray-100': isDragActive,
189-
'p-6 text-center text-gray-500': !value
192+
"bg-gray-100": isDragActive,
193+
"p-6 text-center text-gray-500": !value,
190194
}
191195
)}
192196
>
193197
{value ? (
194-
<div className='bg-white rounded-lg p-3 overflow-hidden'>
198+
<div className="bg-white rounded-lg p-3 overflow-hidden">
195199
{value.map((file, index) => (
196200
<Form.DragDrop.Preview key={index} value={file} />
197201
))}
@@ -208,45 +212,45 @@ export default function App() {
208212
/>
209213
</Form.Label>
210214
<Form.Label
211-
name='Subscribe newsletter'
215+
name="Subscribe newsletter"
212216
placement={Placement.Right}
213-
className='mt-5 text-xs'
217+
className="mt-5 text-xs"
214218
>
215-
<Form.Checkbox id='subscribe' />
219+
<Form.Checkbox id="subscribe" />
216220
</Form.Label>
217221

218-
<Form.RadioGroup className='mt-5'>
219-
<Form.Label name='Apple' placement={Placement.Right}>
220-
<Form.RadioGroup.Radio value='apple' name='fruits' />
222+
<Form.RadioGroup className="mt-5">
223+
<Form.Label name="Apple" placement={Placement.Right}>
224+
<Form.RadioGroup.Radio value="apple" name="fruits" />
221225
</Form.Label>
222-
<Form.Label name='Mango' placement={Placement.Right}>
223-
<Form.RadioGroup.Radio value='Mango' name='fruits' />
226+
<Form.Label name="Mango" placement={Placement.Right}>
227+
<Form.RadioGroup.Radio value="Mango" name="fruits" />
224228
</Form.Label>
225229
</Form.RadioGroup>
226230

227-
<Form.RadioGroup className='mt-5'>
231+
<Form.RadioGroup className="mt-5">
228232
<Form.Label
229-
name='Red'
230-
htmlFor='red'
231-
peerClassName='peer-checked:text-red-500'
233+
name="Red"
234+
htmlFor="red"
235+
peerClassName="peer-checked:text-red-500"
232236
>
233237
<Form.RadioGroup.Radio
234-
id='red'
235-
value='red'
236-
name='color'
237-
className='peer hidden'
238+
id="red"
239+
value="red"
240+
name="color"
241+
className="peer hidden"
238242
/>
239243
</Form.Label>
240244
<Form.Label
241-
name='Green'
242-
htmlFor='green'
243-
peerClassName='peer-checked:text-green-500'
245+
name="Green"
246+
htmlFor="green"
247+
peerClassName="peer-checked:text-green-500"
244248
>
245249
<Form.RadioGroup.Radio
246-
id='green'
247-
value='green'
248-
name='color'
249-
className='peer hidden'
250+
id="green"
251+
value="green"
252+
name="color"
253+
className="peer hidden"
250254
/>
251255
</Form.Label>
252256
</Form.RadioGroup>

packages/@holaplexui-react/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@holaplex/ui-library-react",
33
"author": "Holaplex Inc.",
4-
"version": "0.18.0",
4+
"version": "0.19.0",
55
"description": "Holaplex react ui library components",
66
"private": false,
77
"files": [

packages/@holaplexui-react/src/components/Form.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
InputHTMLAttributes,
99
useState,
1010
Fragment,
11+
TextareaHTMLAttributes,
1112
} from 'react';
1213
import { Listbox, RadioGroup } from '@headlessui/react';
1314
import { FieldError } from 'react-hook-form';
@@ -88,18 +89,19 @@ interface FormInputProps
8889
className?: string;
8990
icon?: JSX.Element;
9091
error?: FieldError;
92+
type?: string;
9193
}
9294

9395
const FormInput = forwardRef(function FormInput(
94-
{ className, icon, error, ...props }: FormInputProps,
96+
{ className, icon, error, type, ...props }: FormInputProps,
9597
ref
9698
) {
9799
return (
98100
<div className={clsx('relative', { 'focus-within:form-input-error': error }, className)}>
99101
<input
100102
{...props}
101103
ref={ref as LegacyRef<HTMLInputElement> | undefined}
102-
type={props.type ?? 'text'}
104+
type={type ?? 'text'}
103105
className={clsx(
104106
'w-full',
105107
{
@@ -123,6 +125,29 @@ const FormInput = forwardRef(function FormInput(
123125
});
124126
Form.Input = FormInput;
125127

128+
interface FormTextAreaProps
129+
extends DetailedHTMLProps<TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement> {
130+
className?: string;
131+
error?: FieldError;
132+
}
133+
134+
const FormTextArea = forwardRef(function FormTextArea(
135+
{ className, error, ...props }: FormTextAreaProps,
136+
ref
137+
) {
138+
return (
139+
<div className={clsx('relative', { 'focus-within:form-textarea-error': error }, className)}>
140+
<textarea
141+
{...props}
142+
ref={ref as LegacyRef<HTMLTextAreaElement> | undefined}
143+
className={clsx('w-full', 'form-textarea')}
144+
/>
145+
</div>
146+
);
147+
});
148+
149+
Form.TextArea = FormTextArea;
150+
126151
interface FormPasswordProps
127152
extends DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {
128153
className?: string;

packages/@holaplexui-react/src/components/Popover.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function PopoverBox({
3636
});
3737

3838
return (
39-
<Popover className="relative">
39+
<Popover className="relative inline-block">
4040
{({ open }) => (
4141
<>
4242
<Popover.Button as="div" ref={setReferenceElement}>

0 commit comments

Comments
 (0)