Move inputs and profile components

This commit is contained in:
Robert Long
2022-01-05 17:27:01 -08:00
parent 2b1a523973
commit 3cb59aebf5
16 changed files with 19 additions and 19 deletions

65
src/input/Input.jsx Normal file
View File

@@ -0,0 +1,65 @@
import React, { forwardRef } from "react";
import classNames from "classnames";
import styles from "./Input.module.css";
import { ReactComponent as CheckIcon } from "../icons/Check.svg";
export function FieldRow({ children, rightAlign, className, ...rest }) {
return (
<div
className={classNames(
styles.fieldRow,
{ [styles.rightAlign]: rightAlign },
className
)}
>
{children}
</div>
);
}
export function Field({ children, className, ...rest }) {
return <div className={classNames(styles.field, className)}>{children}</div>;
}
export const InputField = forwardRef(
(
{ id, label, className, type, checked, prefix, suffix, disabled, ...rest },
ref
) => {
return (
<Field
className={classNames(
type === "checkbox" ? styles.checkboxField : styles.inputField,
{
[styles.prefix]: !!prefix,
[styles.disabled]: disabled,
},
className
)}
>
{prefix && <span>{prefix}</span>}
<input
id={id}
{...rest}
ref={ref}
type={type}
checked={checked}
disabled={disabled}
/>
<label htmlFor={id}>
{type === "checkbox" && (
<div className={styles.checkbox}>
<CheckIcon />
</div>
)}
{label}
</label>
{suffix && <span>{suffix}</span>}
</Field>
);
}
);
export function ErrorMessage({ children }) {
return <p className={styles.errorMessage}>{children}</p>;
}

169
src/input/Input.module.css Normal file
View File

@@ -0,0 +1,169 @@
.fieldRow {
display: flex;
margin-bottom: 32px;
align-items: center;
}
.field {
display: flex;
flex: 1;
min-width: 0;
position: relative;
}
.fieldRow.rightAlign {
justify-content: flex-end;
}
.fieldRow > * {
margin-right: 24px;
}
.fieldRow > :last-child {
margin-right: 0;
}
.inputField {
border-radius: 4px;
transition: border-color 0.25s;
border: 1px solid var(--inputBorderColor);
}
.inputField input {
font-weight: 400;
font-size: 15px;
border: none;
border-radius: 4px;
padding: 12px 9px 10px 9px;
color: var(--textColor1);
background-color: var(--bgColor1);
flex: 1;
min-width: 0;
}
.inputField.disabled input,
.inputField.disabled span {
color: var(--textColor2);
}
.inputField span {
padding: 11px 9px;
}
.inputField span:first-child {
padding-right: 0;
}
.inputField input::placeholder {
transition: color 0.25s ease-in 0s;
color: transparent;
}
.inputField input:placeholder-shown:focus::placeholder {
transition: color 0.25s ease-in 0.1s;
color: var(--textColor2);
}
.inputField label {
transition: font-size 0.25s ease-out 0.1s, color 0.25s ease-out 0.1s,
top 0.25s ease-out 0.1s, background-color 0.25s ease-out 0.1s;
color: var(--textColor3);
background-color: transparent;
font-size: 15px;
position: absolute;
left: 0;
top: 0;
margin: 9px 8px;
padding: 2px;
pointer-events: none;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: calc(100% - 20px);
}
.inputField:focus-within {
border-color: var(--inputBorderColorFocused);
}
.inputField input:focus {
outline: 0;
}
.inputField input:focus + label,
.inputField input:not(:placeholder-shown) + label,
.inputField.prefix input + label {
background-color: var(--bgColor2);
transition: font-size 0.25s ease-out 0s, color 0.25s ease-out 0s,
top 0.25s ease-out 0s, background-color 0.25s ease-out 0s;
font-size: 10px;
top: -13px;
padding: 0 2px;
pointer-events: auto;
}
.inputField input:focus + label {
color: var(--inputBorderColorFocused);
}
.checkboxField {
display: flex;
align-items: flex-start;
}
.checkboxField label {
display: flex;
align-items: center;
flex-grow: 1;
font-size: 13px;
}
.checkboxField input {
outline: 0;
appearance: none;
-webkit-appearance: none;
margin: 0;
padding: 0;
}
.checkbox {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
flex-shrink: 0;
height: 16px;
width: 16px;
border: 1.5px solid rgba(185, 190, 198, 0.5);
box-sizing: border-box;
border-radius: 4px;
margin-right: 10px;
}
.checkbox svg {
display: none;
}
.checkbox svg * {
stroke: #fff;
}
.checkboxField input[type="checkbox"]:checked + label > .checkbox {
background: var(--primaryColor);
border-color: var(--primaryColor);
}
.checkboxField input[type="checkbox"]:checked + label > .checkbox svg {
display: flex;
}
.checkboxField:focus-within .checkbox {
border: 1.5px solid var(--inputBorderColorFocused) !important;
}
.errorMessage {
margin: 0;
font-size: 13px;
color: #ff5b55;
font-weight: 600;
}

57
src/input/SelectInput.jsx Normal file
View File

@@ -0,0 +1,57 @@
import React, { useRef } from "react";
import { HiddenSelect, useSelect } from "@react-aria/select";
import { useButton } from "@react-aria/button";
import { useSelectState } from "@react-stately/select";
import { Popover } from "../popover/Popover";
import { ListBox } from "../ListBox";
import styles from "./SelectInput.module.css";
import classNames from "classnames";
import { ReactComponent as ArrowDownIcon } from "../icons/ArrowDown.svg";
export function SelectInput(props) {
const state = useSelectState(props);
const ref = useRef();
const { labelProps, triggerProps, valueProps, menuProps } = useSelect(
props,
state,
ref
);
const { buttonProps } = useButton(triggerProps, ref);
return (
<div className={classNames(styles.selectInput, props.className)}>
<h4 {...labelProps} className={styles.label}>
{props.label}
</h4>
<HiddenSelect
state={state}
triggerRef={ref}
label={props.label}
name={props.name}
/>
<button {...buttonProps} ref={ref} className={styles.selectTrigger}>
<span {...valueProps} className={styles.selectedItem}>
{state.selectedItem
? state.selectedItem.rendered
: "Select an option"}
</span>
<ArrowDownIcon />
</button>
{state.isOpen && (
<Popover
isOpen={state.isOpen}
onClose={state.close}
className={styles.popover}
>
<ListBox
{...menuProps}
state={state}
optionClassName={styles.option}
/>
</Popover>
)}
</div>
);
}

View File

@@ -0,0 +1,42 @@
.selectInput {
position: relative;
display: inline-block;
margin-bottom: 28px;
max-width: 444px;
}
.label {
font-weight: 600;
font-size: 18px;
margin-top: 0;
margin-bottom: 12px;
}
.selectTrigger {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 12px;
background-color: var(--bgColor1);
border-radius: 8px;
border: 1px solid var(--inputBorderColor);
font-size: 15px;
color: var(--textColor1);
height: 40px;
max-width: 100%;
width: 100%;
}
.selectedItem {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 20px;
}
.popover {
position: absolute;
margin-top: 5px;
width: 100%;
z-index: 1;
}