form enhancements

This commit is contained in:
keyan 2023-05-11 14:34:42 -05:00
parent 5bb6b5f2e7
commit 6d8780373a
5 changed files with 17 additions and 47 deletions

View File

@ -3,7 +3,7 @@ import InputGroup from 'react-bootstrap/InputGroup'
import BootstrapForm from 'react-bootstrap/Form' import BootstrapForm from 'react-bootstrap/Form'
import Alert from 'react-bootstrap/Alert' import Alert from 'react-bootstrap/Alert'
import { Formik, Form as FormikForm, useFormikContext, useField, FieldArray } from 'formik' import { Formik, Form as FormikForm, useFormikContext, useField, FieldArray } from 'formik'
import React, { useEffect, useRef, useState } from 'react' import React, { createContext, useContext, useEffect, useState } from 'react'
import copy from 'clipboard-copy' import copy from 'clipboard-copy'
import Thumb from '../svgs/thumb-up-fill.svg' import Thumb from '../svgs/thumb-up-fill.svg'
import { Col, Dropdown as BootstrapDropdown, Nav } from 'react-bootstrap' import { Col, Dropdown as BootstrapDropdown, Nav } from 'react-bootstrap'
@ -132,10 +132,11 @@ function FormGroup ({ className, label, children }) {
function InputInner ({ function InputInner ({
prepend, append, hint, showValid, onChange, overrideValue, prepend, append, hint, showValid, onChange, overrideValue,
innerRef, storageKeyPrefix, noForm, clear, onKeyDown, ...props innerRef, noForm, clear, onKeyDown, ...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()
const storageKeyPrefix = useContext(StorageKeyPrefixContext)
const storageKey = storageKeyPrefix ? storageKeyPrefix + '-' + props.name : undefined const storageKey = storageKeyPrefix ? storageKeyPrefix + '-' + props.name : undefined
@ -155,7 +156,7 @@ function InputInner ({
} }
}, [overrideValue]) }, [overrideValue])
const invalid = meta.touched && meta.error const invalid = (!formik || formik.submitCount > 0) && meta.touched && meta.error
return ( return (
<> <>
@ -363,6 +364,8 @@ export function Checkbox ({ children, label, groupClassName, hiddenLabel, extra,
) )
} }
const StorageKeyPrefixContext = createContext()
export function Form ({ export function Form ({
initial, schema, onSubmit, children, initialError, validateImmediately, storageKeyPrefix, ...props initial, schema, onSubmit, children, initialError, validateImmediately, storageKeyPrefix, ...props
}) { }) {
@ -389,46 +392,10 @@ export function Form ({
> >
<FormikForm {...props} noValidate> <FormikForm {...props} noValidate>
{error && <Alert variant='danger' onClose={() => setError(undefined)} dismissible>{error}</Alert>} {error && <Alert variant='danger' onClose={() => setError(undefined)} dismissible>{error}</Alert>}
{storageKeyPrefix <StorageKeyPrefixContext.Provider value={storageKeyPrefix}>
? React.Children.map(children, (child) => {
// if child has a type that's a string, it's a dom element and can't get a prop
if (child) {
let childProps = {}
if (typeof child.type !== 'string') {
childProps = { storageKeyPrefix }
}
return React.cloneElement(child, childProps)
}
})
: children}
</FormikForm>
</Formik>
)
}
export function SyncForm ({
initial, schema, children, action, ...props
}) {
const ref = useRef(null)
return (
<Formik
initialValues={initial}
validationSchema={schema}
validateOnBlur={false}
onSubmit={() => ref.current.submit()}
>
{props => (
<form
ref={ref}
onSubmit={props.handleSubmit}
onReset={props.handleReset}
action={action}
method='POST'
noValidate
>
{children} {children}
</form> </StorageKeyPrefixContext.Provider>
)} </FormikForm>
</Formik> </Formik>
) )
} }

View File

@ -112,6 +112,7 @@ function TopLevelItem ({ item, noReply, ...props }) {
return ( return (
<ItemComponent <ItemComponent
item={item} item={item}
full
right={ right={
<> <>
<Share item={item} /> <Share item={item} />

View File

@ -15,7 +15,7 @@ import DontLikeThisDropdownItem from './dont-link-this'
import BookmarkDropdownItem from './bookmark' import BookmarkDropdownItem from './bookmark'
import { CopyLinkDropdownItem } from './share' import { CopyLinkDropdownItem } from './share'
export default function ItemInfo ({ item, commentsText, className, embellishUser, extraInfo, onEdit, editText }) { export default function ItemInfo ({ item, full, commentsText, className, embellishUser, extraInfo, onEdit, editText }) {
const editThreshold = new Date(item.createdAt).getTime() + 10 * 60000 const editThreshold = new Date(item.createdAt).getTime() + 10 * 60000
const me = useMe() const me = useMe()
const router = useRouter() const router = useRouter()
@ -23,8 +23,9 @@ export default function ItemInfo ({ item, commentsText, className, embellishUser
useState(item.mine && (Date.now() < editThreshold)) useState(item.mine && (Date.now() < editThreshold))
const [hasNewComments, setHasNewComments] = useState(false) const [hasNewComments, setHasNewComments] = useState(false)
useEffect(() => { useEffect(() => {
// if we are showing toc, then this is a full item if (!full) {
setHasNewComments(newComments(item)) setHasNewComments(newComments(item))
}
}, [item]) }, [item])
return ( return (

View File

@ -18,7 +18,7 @@ export function SearchTitle ({ title }) {
}) })
} }
export default function Item ({ item, rank, belowTitle, right, children }) { export default function Item ({ item, rank, belowTitle, right, full, children }) {
const titleRef = useRef() const titleRef = useRef()
return ( return (
@ -58,7 +58,7 @@ export default function Item ({ item, rank, belowTitle, right, children }) {
</a> </a>
</>} </>}
</div> </div>
<ItemInfo item={item} /> <ItemInfo full={full} item={item} />
{belowTitle} {belowTitle}
</div> </div>
{right} {right}

View File

@ -179,6 +179,7 @@ export function WithdrawlForm () {
name='invoice' name='invoice'
required required
autoFocus autoFocus
clear
/> />
<Input <Input
label='max fee' label='max fee'