Update Input and InputTableField

* Added error and label to input, in a fieldset
* Updated prop labels in InputTableField
This commit is contained in:
Justin Edmund 2023-06-30 22:22:54 -07:00
parent 198f5c79cd
commit a3a205fb5d
3 changed files with 129 additions and 70 deletions

View file

@ -2,83 +2,126 @@
width: 100%;
}
.input {
-webkit-font-smoothing: antialiased;
background-color: var(--input-bg);
border: 2px solid transparent;
border-radius: $input-corner;
box-sizing: border-box;
display: block;
width: 100%;
.fieldset {
display: flex;
flex-direction: column;
gap: $unit-half;
&:not(.wrapper) {
padding: $unit * 1.5 $unit-2x;
&:last-child .error {
margin-bottom: 0;
}
&.accessory {
$offset: 2px;
.error {
color: $error;
font-size: $font-small;
padding: calc($unit / 2) ($unit * 2);
min-width: 100%;
margin-bottom: $unit;
width: 0;
}
align-items: center;
background: var(--input-bg);
.input {
-webkit-font-smoothing: antialiased;
background-color: var(--input-bg);
border: 2px solid transparent;
border-radius: $input-corner;
border: $offset solid transparent;
box-sizing: border-box;
position: relative;
color: var(--text-primary);
display: block;
font-family: system-ui, -apple-system, 'Helvetica Neue', Helvetica, Arial,
sans-serif;
font-size: $font-regular;
width: 100%;
.counter {
color: var(--text-tertiary);
display: block;
font-weight: $bold;
line-height: 48px;
position: absolute;
right: $unit-2x;
top: 0;
&:not(.wrapper) {
padding: $unit * 1.5 $unit-2x;
}
input {
background: transparent;
&.accessory {
$offset: 2px;
align-items: center;
background: var(--input-bg);
border-radius: $input-corner;
border: none;
border: $offset solid transparent;
box-sizing: border-box;
padding: ($unit * 1.75) $unit-2x;
width: 100%;
position: relative;
.counter {
color: var(--text-tertiary);
display: block;
font-weight: $bold;
line-height: 48px;
position: absolute;
right: $unit-2x;
top: 0;
}
input {
background: transparent;
border-radius: $input-corner;
border: none;
box-sizing: border-box;
color: var(--text-primary);
padding: ($unit * 1.75) $unit-2x;
width: 100%;
}
}
&[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
}
&:focus {
border: 2px solid $blue;
outline: none;
}
&.bound {
background-color: var(--input-bound-bg);
&:hover {
background-color: var(--input-bound-bg-hover);
}
}
&.duration {
background: transparent;
border: none;
padding: 0;
width: initial;
height: 100%;
padding: calc($unit-2x - 2px) 0;
&:hover {
background: transparent;
}
&:focus,
&:focus-visible {
border: none;
}
}
&.number {
text-align: right;
width: $unit-8x;
}
&.alignRight {
text-align: right;
}
&.hidden {
display: none;
}
}
&[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
}
&:focus {
border: 2px solid $blue;
outline: none;
}
&.bound {
background-color: var(--input-bound-bg);
&:hover {
background-color: var(--input-bound-bg-hover);
}
}
&.number {
min-width: $unit-8x;
}
&.AlignRight {
text-align: right;
}
&.Hidden {
.counter {
display: none;
}
}
.counter {
display: none;
}
.input::placeholder,
.input > input::placeholder {
color: var(--text-secondary);

View file

@ -1,10 +1,11 @@
import React, { useEffect, useState } from 'react'
import classNames from 'classnames'
import styles from './index.module.scss'
interface Props extends React.ComponentProps<'input'> {
bound?: boolean
error?: string
label?: string
hide1Password?: boolean
showCounter?: boolean
}
@ -16,16 +17,17 @@ const defaultProps = {
}
const Input = React.forwardRef<HTMLInputElement, Props>(function input(
{ value, bound, showCounter, ...props }: Props,
{ value: initialValue, bound, label, error, showCounter, ...props }: Props,
forwardedRef
) {
// States
const [value, setValue] = useState(initialValue)
const [currentCount, setCurrentCount] = useState(() =>
props.maxLength ? props.maxLength - (`${value}` || '').length : 0
)
// Classes
const wrapperClasses = classNames(
const inputWrapperClasses = classNames(
{
[styles.wrapper]: true,
[styles.accessory]: showCounter,
@ -53,12 +55,13 @@ const Input = React.forwardRef<HTMLInputElement, Props>(function input(
// Event handlers
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setValue(event.target.value)
if (props.onChange) props.onChange(event)
}
// Rendering
return (
<div className={wrapperClasses}>
const input = (
<div className={inputWrapperClasses}>
<input
{...inputProps}
data-1p-ignore={props.hide1Password}
@ -67,7 +70,7 @@ const Input = React.forwardRef<HTMLInputElement, Props>(function input(
type={props.type}
name={props.name}
placeholder={props.placeholder}
value={value || ''}
value={value}
onBlur={props.onBlur}
onChange={handleChange}
maxLength={props.maxLength}
@ -77,6 +80,16 @@ const Input = React.forwardRef<HTMLInputElement, Props>(function input(
<span className={styles.counter}>{currentCount}</span>
</div>
)
const fieldset = (
<fieldset className={styles.fieldset}>
{label && <legend className={styles.legend}>{label}</legend>}
{input}
{error && <span className={styles.error}>{error}</span>}
</fieldset>
)
return fieldset
})
Input.defaultProps = defaultProps

View file

@ -44,18 +44,21 @@ const InputTableField = ({
<TableField
{...props}
name={props.name || ''}
className={classNames({ InputField: true }, props.className)}
imageAlt={imageAlt}
imageClass={imageClass}
imageSrc={imageSrc}
className={styles.nameField}
image={{
alt: imageAlt,
className: imageClass,
src: imageSrc ? imageSrc : [],
}}
label={label}
>
<Input
className="Bound"
className={props.className}
placeholder={props.placeholder}
value={inputValue ? `${inputValue}` : ''}
step={1}
tabIndex={props.tabIndex}
bound={true}
type={props.type}
onChange={onInputChange}
/>