stacker.news/components/accordian-item.js
Ben Allen 57fbab31b3
Force post options open when dirty or on errors (#1129)
* wip submit will open options

* fix: options show on error discussions

* lint

* feat: all types check for dirty or errors

* lint

* fix ordering

* dirty and error useEffects

* use formik context

* update dirty checks on forms

* revert dirty logic

* simplify handle error functions

* lint

* add myself to contributors and update awards

* use Formik context in adv-post-form

* move all logic into accordian item

* move logic up to adv-post-form

* lint

* errors open options every time

* refine dirty form accordians

---------

Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com>
Co-authored-by: keyan <keyan.kousha+huumn@gmail.com>
2024-05-12 16:17:41 -05:00

54 lines
1.8 KiB
JavaScript

import Accordion from 'react-bootstrap/Accordion'
import AccordionContext from 'react-bootstrap/AccordionContext'
import { useAccordionButton } from 'react-bootstrap/AccordionButton'
import ArrowRight from '@/svgs/arrow-right-s-fill.svg'
import ArrowDown from '@/svgs/arrow-down-s-fill.svg'
import { useContext, useEffect } from 'react'
function ContextAwareToggle ({ children, headerColor = 'var(--theme-grey)', eventKey, show }) {
const { activeEventKey } = useContext(AccordionContext)
const decoratedOnClick = useAccordionButton(eventKey)
useEffect(() => {
// if we want to show the accordian and it's not open, open it
if (show && activeEventKey !== eventKey) {
decoratedOnClick()
}
}, [show])
const isCurrentEventKey = activeEventKey === eventKey
return (
<div style={{ cursor: 'pointer', display: 'flex', alignItems: 'center' }} onClick={decoratedOnClick}>
{isCurrentEventKey
? <ArrowDown style={{ fill: headerColor }} height={20} width={20} />
: <ArrowRight style={{ fill: headerColor }} height={20} width={20} />}
{children}
</div>
)
}
export default function AccordianItem ({ header, body, headerColor = 'var(--theme-grey)', show }) {
return (
<Accordion defaultActiveKey={show ? '0' : undefined}>
<ContextAwareToggle show={show} eventKey='0'><div style={{ color: headerColor }}>{header}</div></ContextAwareToggle>
<Accordion.Collapse eventKey='0' className='mt-2'>
<div>{body}</div>
</Accordion.Collapse>
</Accordion>
)
}
export function AccordianCard ({ header, children, show }) {
return (
<Accordion defaultActiveKey={show ? '0' : undefined}>
<Accordion.Item eventKey='0'>
<Accordion.Header>{header}</Accordion.Header>
<Accordion.Body>
{children}
</Accordion.Body>
</Accordion.Item>
</Accordion>
)
}