fix variable input icon alignment

This commit is contained in:
k00b 2025-07-22 18:26:29 -05:00
parent 276bb94eb9
commit f63d40196d
2 changed files with 70 additions and 57 deletions

View File

@ -269,7 +269,7 @@ export default function AdvPostForm ({ children, item, sub, storageKeyPrefix })
emptyItem={EMPTY_FORWARD} emptyItem={EMPTY_FORWARD}
hint={<span className='text-muted'>Forward sats to up to 5 other stackers. Any remaining sats go to you.</span>} hint={<span className='text-muted'>Forward sats to up to 5 other stackers. Any remaining sats go to you.</span>}
> >
{({ index, placeholder }) => { {({ index, AppendColumn }) => {
return ( return (
<div key={index} className='d-flex flex-row'> <div key={index} className='d-flex flex-row'>
<InputUserSuggest <InputUserSuggest
@ -286,6 +286,7 @@ export default function AdvPostForm ({ children, item, sub, storageKeyPrefix })
max={100} max={100}
append={<InputGroup.Text className='text-monospace'>%</InputGroup.Text>} append={<InputGroup.Text className='text-monospace'>%</InputGroup.Text>}
groupClassName={`${styles.percent} mb-0`} groupClassName={`${styles.percent} mb-0`}
AppendColumn={AppendColumn}
/> />
</div> </div>
) )

View File

@ -609,7 +609,7 @@ function FormGroup ({ className, label, children }) {
function InputInner ({ function InputInner ({
prepend, append, hint, warn, showValid, onChange, onBlur, overrideValue, appendValue, prepend, append, hint, warn, showValid, onChange, onBlur, overrideValue, appendValue,
innerRef, noForm, clear, onKeyDown, inputGroupClassName, debounce: debounceTime, maxLength, hideError, innerRef, noForm, clear, onKeyDown, inputGroupClassName, debounce: debounceTime, maxLength, hideError,
...props AppendColumn, ...props
}) { }) {
const [field, meta, helpers] = noForm ? [{}, {}, {}] : useField(props) const [field, meta, helpers] = noForm ? [{}, {}, {}] : useField(props)
const formik = noForm ? null : useFormikContext() const formik = noForm ? null : useFormikContext()
@ -687,38 +687,43 @@ function InputInner ({
return ( return (
<> <>
<InputGroup hasValidation className={inputGroupClassName}> <Row>
{prepend} <Col>
<BootstrapForm.Control <InputGroup hasValidation className={inputGroupClassName}>
ref={innerRef} {prepend}
{...field} <BootstrapForm.Control
{...props} ref={innerRef}
onKeyDown={onKeyDownInner} {...field}
onChange={onChangeInner} {...props}
onBlur={onBlurInner} onKeyDown={onKeyDownInner}
isInvalid={!hideError && invalid} // if hideError is true, handle error showing separately onChange={onChangeInner}
isValid={showValid && meta.initialValue !== meta.value && meta.touched && !meta.error} onBlur={onBlurInner}
/> isInvalid={!hideError && invalid} // if hideError is true, handle error showing separately
{(isClient && clear && field.value && !props.readOnly) && isValid={showValid && meta.initialValue !== meta.value && meta.touched && !meta.error}
<Button />
variant={null} {(isClient && clear && field.value && !props.readOnly) &&
onClick={(e) => { <Button
helpers.setValue('') variant={null}
if (storageKey) { onClick={(e) => {
window.localStorage.removeItem(storageKey) helpers.setValue('')
} if (storageKey) {
if (onChange) { window.localStorage.removeItem(storageKey)
onChange(formik, { target: { value: '' } }) }
} if (onChange) {
}} onChange(formik, { target: { value: '' } })
className={`${styles.clearButton} ${styles.appendButton} ${invalid ? styles.isInvalid : ''}`} }
><CloseIcon className='fill-grey' height={20} width={20} /> }}
</Button>} className={`${styles.clearButton} ${styles.appendButton} ${invalid ? styles.isInvalid : ''}`}
{append} ><CloseIcon className='fill-grey' height={20} width={20} />
<BootstrapForm.Control.Feedback type='invalid'> </Button>}
{meta.touched && meta.error} {append}
</BootstrapForm.Control.Feedback> <BootstrapForm.Control.Feedback type='invalid'>
</InputGroup> {meta.touched && meta.error}
</BootstrapForm.Control.Feedback>
</InputGroup>
</Col>
{AppendColumn && <AppendColumn className={meta.touched && meta.error ? 'invisible' : ''} />}
</Row>
{hint && ( {hint && (
<BootstrapForm.Text> <BootstrapForm.Text>
{hint} {hint}
@ -952,31 +957,38 @@ export function VariableInput ({ label, groupClassName, name, hint, max, min, re
<FieldArray name={name} hasValidation> <FieldArray name={name} hasValidation>
{({ form, ...fieldArrayHelpers }) => { {({ form, ...fieldArrayHelpers }) => {
const options = form.values[name] const options = form.values[name]
return ( return (
<> <>
{options?.map((_, i) => ( {options?.map((_, i) => {
<div key={i}> const AppendColumn = ({ className }) => (
<Row className='mb-2'> <Col className={`d-flex ps-0 ${className}`} xs='auto'>
<Col> {options.length - 1 === i && options.length !== max
{children // onMouseDown is used to prevent the blur event on text inputs from overriding the click event
? children({ index: i, readOnly: i < readOnlyLen, placeholder: i >= min ? 'optional' : undefined }) ? <AddIcon className='fill-grey align-self-center justify-self-center pointer' onMouseDown={() => fieldArrayHelpers.push(emptyItem)} />
: <InputInner name={`${name}[${i}]`} {...props} readOnly={i < readOnlyLen} placeholder={i >= min ? 'optional' : undefined} />} // filler div for col alignment across rows
</Col> : <div style={{ width: '24px', height: '24px' }} />}
<Col className='d-flex ps-0' xs='auto'> </Col>
{options.length - 1 === i && options.length !== max )
? <AddIcon className='fill-grey align-self-center justify-self-center pointer' onClick={() => fieldArrayHelpers.push(emptyItem)} /> return (
// filler div for col alignment across rows <div key={i}>
: <div style={{ width: '24px', height: '24px' }} />} <Row className='mb-2'>
</Col> <Col>
{options.length - 1 === i && {children
<> ? children({ index: i, readOnly: i < readOnlyLen, placeholder: i >= min ? 'optional' : undefined, AppendColumn })
{hint && <BootstrapForm.Text>{hint}</BootstrapForm.Text>} : <InputInner name={`${name}[${i}]`} {...props} readOnly={i < readOnlyLen} placeholder={i >= min ? 'optional' : undefined} AppendColumn={AppendColumn} />}
{form.touched[name] && typeof form.errors[name] === 'string' && </Col>
<div className='invalid-feedback d-block'>{form.errors[name]}</div>}
</>} {options.length - 1 === i &&
</Row> <>
</div> {hint && <BootstrapForm.Text>{hint}</BootstrapForm.Text>}
))} {form.touched[name] && typeof form.errors[name] === 'string' &&
<div className='invalid-feedback d-block'>{form.errors[name]}</div>}
</>}
</Row>
</div>
)
})}
</> </>
) )
}} }}