mirror of
https://github.com/wavetermdev/docusaurus-og.git
synced 2026-08-05 13:46:35 -07:00
feat: implement the AccordionItem component
This commit is contained in:
@@ -1,18 +1,22 @@
|
||||
import { useColorMode } from '@docusaurus/theme-common'
|
||||
import { clsx } from 'clsx'
|
||||
import React, { CSSProperties } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
import styles from './style.module.scss'
|
||||
|
||||
import AddSvg from '../../static/icons/add.svg'
|
||||
import ArrowLCircleSvg from '../../static/icons/arrow-left-circle.svg'
|
||||
import ArrowL from '../../static/icons/arrow-left.svg'
|
||||
import ArrowRCircleSvg from '../../static/icons/arrow-right-circle.svg'
|
||||
import ArrowR from '../../static/icons/arrow-right.svg'
|
||||
import Avatar from '../../static/icons/avatar.svg'
|
||||
import CloseSvg from '../../static/icons/close.svg'
|
||||
import CopySvg from '../../static/icons/copy.svg'
|
||||
import DiscordWhiteSvg from '../../static/icons/discord-white.svg'
|
||||
import DiscordSvg from '../../static/icons/discord.svg'
|
||||
import DiscourseSvg from '../../static/icons/discourse.svg'
|
||||
import DotSvg from '../../static/icons/dot.svg'
|
||||
import DownloadSvg from '../../static/icons/download.svg'
|
||||
import DropdownSvg from '../../static/icons/dropdown.svg'
|
||||
import EditSvg from '../../static/icons/edit.svg'
|
||||
import ExternalLinkSvg from '../../static/icons/external-link.svg'
|
||||
@@ -23,15 +27,13 @@ import GithubWhiteSvg from '../../static/icons/github-white.svg'
|
||||
import GScholarSvg from '../../static/icons/gscholar.svg'
|
||||
import HistorySvg from '../../static/icons/history.svg'
|
||||
import LinkedinSvg from '../../static/icons/linkedin.svg'
|
||||
import RemoveSvg from '../../static/icons/remove.svg'
|
||||
import SearchSvg from '../../static/icons/search.svg'
|
||||
import StatusSvg from '../../static/icons/status.svg'
|
||||
import TelegramWhiteSvg from '../../static/icons/telegram-white.svg'
|
||||
import TelegramSvg from '../../static/icons/telegram.svg'
|
||||
import TwitterSvg from '../../static/icons/twitter.svg'
|
||||
import DiscordWhiteSvg from '../../static/icons/discord-white.svg'
|
||||
import TelegramWhiteSvg from '../../static/icons/telegram-white.svg'
|
||||
import XWhiteSvg from '../../static/icons/x-white.svg'
|
||||
import Avatar from '../../static/icons/avatar.svg'
|
||||
import DownloadSvg from '../../static/icons/download.svg'
|
||||
|
||||
type TIconProps = {
|
||||
size?: 's' | 'm' | 'l'
|
||||
@@ -40,7 +42,8 @@ type TIconProps = {
|
||||
|
||||
type TProps = {
|
||||
children?: JSX.Element
|
||||
fill?: string
|
||||
fill?: boolean
|
||||
stroke?: boolean
|
||||
} & TIconProps
|
||||
|
||||
export const Icon = (props: TProps): JSX.Element => {
|
||||
@@ -53,6 +56,8 @@ export const Icon = (props: TProps): JSX.Element => {
|
||||
styles.icon,
|
||||
colorMode === 'dark' ? styles.dark : styles.light,
|
||||
styles[size],
|
||||
props.stroke && styles.stroke,
|
||||
props.fill && styles.fill,
|
||||
props.className && props.className,
|
||||
)}
|
||||
>
|
||||
@@ -234,3 +239,15 @@ export const IconDownload = (props: TIconProps): JSX.Element => (
|
||||
<DownloadSvg />
|
||||
</Icon>
|
||||
)
|
||||
|
||||
export const IconAdd = (props: TIconProps): JSX.Element => (
|
||||
<Icon {...props} stroke>
|
||||
<AddSvg />
|
||||
</Icon>
|
||||
)
|
||||
|
||||
export const IconRemove = (props: TIconProps): JSX.Element => (
|
||||
<Icon {...props} stroke>
|
||||
<RemoveSvg />
|
||||
</Icon>
|
||||
)
|
||||
|
||||
@@ -17,13 +17,31 @@
|
||||
}
|
||||
|
||||
&.dark {
|
||||
.fill {
|
||||
fill: var(--ifm-color-black);
|
||||
&.fill {
|
||||
&,
|
||||
* {
|
||||
fill: var(--ifm-color-white);
|
||||
}
|
||||
}
|
||||
.stroke {
|
||||
stroke: var(--ifm-color-white);
|
||||
&.stroke {
|
||||
svg,
|
||||
svg * {
|
||||
stroke: var(--ifm-color-white);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.light {
|
||||
&.fill {
|
||||
&,
|
||||
* {
|
||||
fill: var(--ifm-color-black);
|
||||
}
|
||||
}
|
||||
&.stroke {
|
||||
svg,
|
||||
svg * {
|
||||
stroke: var(--ifm-color-black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
@use '../../../css/utils';
|
||||
@use '../../../css/lsd';
|
||||
|
||||
.mdx-accordion-item {
|
||||
border-bottom: 1px solid rgb(var(--lsd-border-primary));
|
||||
|
||||
> input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mdx-accordion-item__header {
|
||||
min-height: 88px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 0;
|
||||
gap: 0 16px;
|
||||
|
||||
&,
|
||||
* {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.mdx-accordion-item__content-wrapper {
|
||||
overflow: hidden;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.mdx-accordion-item__content {
|
||||
height: 0;
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
|
||||
.mdx-accordion-item--open {
|
||||
.mdx-accordion-item__content {
|
||||
height: auto;
|
||||
padding-bottom: 1.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
@include utils.responsive('lg', 'down') {
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
import clsx from 'clsx'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import './AccordionItem.scss'
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
import { IconAdd, IconRemove } from '../../Icon'
|
||||
import uniqueId from 'lodash/uniqueId'
|
||||
|
||||
export type AccordionItemProps = Omit<
|
||||
React.HTMLProps<HTMLDivElement>,
|
||||
'title'
|
||||
> & {
|
||||
open?: boolean
|
||||
title: React.ReactNode
|
||||
onToggle?: (open: boolean) => void
|
||||
}
|
||||
|
||||
export const AccordionItem: React.FC<AccordionItemProps> = ({
|
||||
open: openProp,
|
||||
onToggle,
|
||||
title,
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const id = uniqueId('accordion-item-')
|
||||
const [open, setOpen] = useState(openProp ?? false)
|
||||
|
||||
if (typeof openProp !== 'undefined' && openProp !== open) {
|
||||
setOpen(openProp)
|
||||
}
|
||||
|
||||
const handleToggle = () => {
|
||||
if (typeof openProp !== 'undefined') {
|
||||
onToggle && onToggle(!open)
|
||||
} else {
|
||||
setOpen((val) => !val)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
className,
|
||||
'mdx-accordion-item',
|
||||
open && 'mdx-accordion-item--open',
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<input type="checkbox" id={id} checked={open} />
|
||||
<div
|
||||
role="button"
|
||||
className="mdx-accordion-item__header"
|
||||
onClick={() => handleToggle()}
|
||||
>
|
||||
<Typography
|
||||
className="mdx-accordion-item__title"
|
||||
variant="h5"
|
||||
component="label"
|
||||
htmlFor={id}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
<div className="mdx-accordion-item__icon">
|
||||
{open ? <IconRemove /> : <IconAdd />}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mdx-accordion-item__content-wrapper">
|
||||
<div className="mdx-accordion-item__content">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './AccordionItem'
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './AccordionItem'
|
||||
export * from './AppCard'
|
||||
export * from './AssetCard'
|
||||
export * from './Box'
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<line x1="9" y1="17.5" x2="9" y2="0.5" stroke="white"/>
|
||||
<line x1="0.5" y1="9" x2="17.5" y2="9" stroke="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 215 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<line x1="0.5" y1="9" x2="17.5" y2="9" stroke="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 159 B |
Reference in New Issue
Block a user