Skip to content

Commit

Permalink
Merge pull request #20 from holaplex/espi/popover-fix-textarea
Browse files Browse the repository at this point in the history
Popover Fix and Form Textarea
  • Loading branch information
kespinola authored May 18, 2023
2 parents 4175fa0 + 5051b63 commit 52aa0dd
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 93 deletions.
182 changes: 93 additions & 89 deletions packages/@holaplexui-playground/pages/form.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,72 @@
import { Form, Icon, Placement } from '@holaplex/ui-library-react';
import clsx from 'clsx';
import { watch } from 'fs';
import { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { Controller, useForm } from 'react-hook-form';
import useUpload from '../hooks/useUpload';
import { Form, Icon, Placement } from "@holaplex/ui-library-react";
import clsx from "clsx";
import { watch } from "fs";
import { useCallback, useState } from "react";
import { useDropzone } from "react-dropzone";
import { Controller, useForm } from "react-hook-form";
import useUpload from "../hooks/useUpload";

function HidePasswordIcon({ size = 16, color = 'none', className = '' }) {
function HidePasswordIcon({ size = 16, color = "none", className = "" }) {
return (
<svg
width={size}
height={size}
viewBox='0 0 16 16'
viewBox="0 0 16 16"
fill={color}
className={className}
xmlns='http://www.w3.org/2000/svg'
xmlns="http://www.w3.org/2000/svg"
>
<path
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'
stroke='black'
strokeLinecap='round'
strokeLinejoin='round'
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"
stroke="black"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
fill-rule='evenodd'
clip-rule='evenodd'
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'
stroke='black'
strokeLinecap='round'
strokeLinejoin='round'
fill-rule="evenodd"
clip-rule="evenodd"
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"
stroke="black"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}

function ShowPasswordIcon({ size = 16, color = 'none', className = '' }) {
function ShowPasswordIcon({ size = 16, color = "none", className = "" }) {
return (
<svg
width={size}
height={size}
viewBox='0 0 16 16'
viewBox="0 0 16 16"
fill={color}
className={className}
xmlns='http://www.w3.org/2000/svg'
xmlns="http://www.w3.org/2000/svg"
>
<path
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'
stroke='black'
strokeLinecap='round'
strokeLinejoin='round'
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"
stroke="black"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
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'
stroke='black'
strokeLinecap='round'
strokeLinejoin='round'
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"
stroke="black"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
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'
stroke='black'
strokeLinecap='round'
strokeLinejoin='round'
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"
stroke="black"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d='M14.0021 13.3356L2.66406 1.99756'
stroke='black'
strokeLinecap='round'
strokeLinejoin='round'
d="M14.0021 13.3356L2.66406 1.99756"
stroke="black"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
Expand All @@ -89,53 +89,57 @@ export default function App() {
>();

const options = [
{ name: 'Solana', id: 'sol' },
{ name: 'Polygon', id: 'polygon' },
{ name: 'Near', id: 'near' },
{ name: 'Ethereum', id: 'eth' },
{ name: 'Sui', id: 'sui' },
{ name: 'Aptos', id: 'aptos' },
{ name: 'Avalanche', id: 'avalanche' },
{ name: 'Bitcoin', id: 'btc' },
{ name: 'Cardano', id: 'ada' }
{ name: "Solana", id: "sol" },
{ name: "Polygon", id: "polygon" },
{ name: "Near", id: "near" },
{ name: "Ethereum", id: "eth" },
{ name: "Sui", id: "sui" },
{ name: "Aptos", id: "aptos" },
{ name: "Avalanche", id: "avalanche" },
{ name: "Bitcoin", id: "btc" },
{ name: "Cardano", id: "ada" },
];

const { control, setValue } = useForm<DragDropForm>();
const onDrop = useCallback(
(files: File[]) => {
setValue('files', files, { shouldValidate: true });
setValue("files", files, { shouldValidate: true });
},
[setValue]
);
const { getRootProps, getInputProps, isDragActive } = useUpload(onDrop);

return (
<div className='w-[400px] mx-auto p-4'>
<div className="w-[400px] mx-auto p-4">
<Form>
<Form.Label name='Email'>
<Form.Input placeholder='e.g. [email protected]' />
<Form.Label name="Email">
<Form.Input placeholder="e.g. [email protected]" />
</Form.Label>

<Form.Label
name='Password'
asideComponent={<div className='text-xs'>Forgot Password?</div>}
className='mt-5'
name="Password"
asideComponent={<div className="text-xs">Forgot Password?</div>}
className="mt-5"
>
<Form.Password
placeholder='Enter your password'
placeholder="Enter your password"
showPasswordIcon={<ShowPasswordIcon />}
hidePasswordIcon={<HidePasswordIcon />}
/>
</Form.Label>

<Form.Label name="Description" className="mt-5">
<Form.TextArea placeholder="Enter a description" />
</Form.Label>

<Form.Select
className='mt-5'
className="mt-5"
onChange={(v) => {
setSingleValue(v);
}}
value={singleValue}
>
<Form.Select.Button icon={<Icon.Sol />} placeholder='e.g. Solana'>
<Form.Select.Button icon={<Icon.Sol />} placeholder="e.g. Solana">
{singleValue?.name}
</Form.Select.Button>
<Form.Select.Options>
Expand All @@ -148,14 +152,14 @@ export default function App() {
</Form.Select>

<Form.Select
className='mt-5'
className="mt-5"
multiple
onChange={(v) => {
setMultiValue(v);
}}
value={multiValue}
>
<Form.Select.Button icon={<Icon.Sol />} placeholder='e.g. Solana'>
<Form.Select.Button icon={<Icon.Sol />} placeholder="e.g. Solana">
{multiValue && multiValue?.length > 0
? multiValue[0].name
: undefined}
Expand All @@ -169,9 +173,9 @@ export default function App() {
</Form.Select.Options>
</Form.Select>

<Form.Label name='Drop Image' className='mt-5'>
<Form.Label name="Drop Image" className="mt-5">
<Controller
name='files'
name="files"
control={control}
render={({ field: { value, onChange } }) => (
<Form.DragDrop
Expand All @@ -183,15 +187,15 @@ export default function App() {
>
<div
className={clsx(
'flex items-center justify-center border border-dashed border-gray-200 cursor-pointer rounded-md',
"flex items-center justify-center border border-dashed border-gray-200 cursor-pointer rounded-md",
{
'bg-gray-100': isDragActive,
'p-6 text-center text-gray-500': !value
"bg-gray-100": isDragActive,
"p-6 text-center text-gray-500": !value,
}
)}
>
{value ? (
<div className='bg-white rounded-lg p-3 overflow-hidden'>
<div className="bg-white rounded-lg p-3 overflow-hidden">
{value.map((file, index) => (
<Form.DragDrop.Preview key={index} value={file} />
))}
Expand All @@ -208,45 +212,45 @@ export default function App() {
/>
</Form.Label>
<Form.Label
name='Subscribe newsletter'
name="Subscribe newsletter"
placement={Placement.Right}
className='mt-5 text-xs'
className="mt-5 text-xs"
>
<Form.Checkbox id='subscribe' />
<Form.Checkbox id="subscribe" />
</Form.Label>

<Form.RadioGroup className='mt-5'>
<Form.Label name='Apple' placement={Placement.Right}>
<Form.RadioGroup.Radio value='apple' name='fruits' />
<Form.RadioGroup className="mt-5">
<Form.Label name="Apple" placement={Placement.Right}>
<Form.RadioGroup.Radio value="apple" name="fruits" />
</Form.Label>
<Form.Label name='Mango' placement={Placement.Right}>
<Form.RadioGroup.Radio value='Mango' name='fruits' />
<Form.Label name="Mango" placement={Placement.Right}>
<Form.RadioGroup.Radio value="Mango" name="fruits" />
</Form.Label>
</Form.RadioGroup>

<Form.RadioGroup className='mt-5'>
<Form.RadioGroup className="mt-5">
<Form.Label
name='Red'
htmlFor='red'
peerClassName='peer-checked:text-red-500'
name="Red"
htmlFor="red"
peerClassName="peer-checked:text-red-500"
>
<Form.RadioGroup.Radio
id='red'
value='red'
name='color'
className='peer hidden'
id="red"
value="red"
name="color"
className="peer hidden"
/>
</Form.Label>
<Form.Label
name='Green'
htmlFor='green'
peerClassName='peer-checked:text-green-500'
name="Green"
htmlFor="green"
peerClassName="peer-checked:text-green-500"
>
<Form.RadioGroup.Radio
id='green'
value='green'
name='color'
className='peer hidden'
id="green"
value="green"
name="color"
className="peer hidden"
/>
</Form.Label>
</Form.RadioGroup>
Expand Down
2 changes: 1 addition & 1 deletion packages/@holaplexui-react/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@holaplex/ui-library-react",
"author": "Holaplex Inc.",
"version": "0.18.0",
"version": "0.19.0",
"description": "Holaplex react ui library components",
"private": false,
"files": [
Expand Down
29 changes: 27 additions & 2 deletions packages/@holaplexui-react/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
InputHTMLAttributes,
useState,
Fragment,
TextareaHTMLAttributes,
} from 'react';
import { Listbox, RadioGroup } from '@headlessui/react';
import { FieldError } from 'react-hook-form';
Expand Down Expand Up @@ -88,18 +89,19 @@ interface FormInputProps
className?: string;
icon?: JSX.Element;
error?: FieldError;
type?: string;
}

const FormInput = forwardRef(function FormInput(
{ className, icon, error, ...props }: FormInputProps,
{ className, icon, error, type, ...props }: FormInputProps,
ref
) {
return (
<div className={clsx('relative', { 'focus-within:form-input-error': error }, className)}>
<input
{...props}
ref={ref as LegacyRef<HTMLInputElement> | undefined}
type={props.type ?? 'text'}
type={type ?? 'text'}
className={clsx(
'w-full',
{
Expand All @@ -123,6 +125,29 @@ const FormInput = forwardRef(function FormInput(
});
Form.Input = FormInput;

interface FormTextAreaProps
extends DetailedHTMLProps<TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement> {
className?: string;
error?: FieldError;
}

const FormTextArea = forwardRef(function FormTextArea(
{ className, error, ...props }: FormTextAreaProps,
ref
) {
return (
<div className={clsx('relative', { 'focus-within:form-textarea-error': error }, className)}>
<textarea
{...props}
ref={ref as LegacyRef<HTMLTextAreaElement> | undefined}
className={clsx('w-full', 'form-textarea')}
/>
</div>
);
});

Form.TextArea = FormTextArea;

interface FormPasswordProps
extends DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {
className?: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/@holaplexui-react/src/components/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function PopoverBox({
});

return (
<Popover className="relative">
<Popover className="relative inline-block">
{({ open }) => (
<>
<Popover.Button as="div" ref={setReferenceElement}>
Expand Down

0 comments on commit 52aa0dd

Please sign in to comment.