Skip to content

Instantly share code, notes, and snippets.

@ademilter
Last active March 23, 2022 15:42
Show Gist options
  • Save ademilter/4eca6cae3b72cffb2d4eff7dec460f4a to your computer and use it in GitHub Desktop.
Save ademilter/4eca6cae3b72cffb2d4eff7dec460f4a to your computer and use it in GitHub Desktop.
manageable component
<SectionBlockContainer>
<SectionBlock>
<SectionBlockIcon>
<Drafts />
</SectionBlockIcon>
<SectionBlockTitle>Marketing Emails</SectionBlockTitle>
<SectionBlockSummary>
Receive occasional news from Upstash teams, and promotional
offers.
</SectionBlockSummary>
<SectionBlockActions>
<Switch
loading={isLoadingMarketing}
checked={isMarketingStatus}
onChange={() => {}}
/>
</SectionBlockActions>
</SectionBlock>
<SectionBlockDivider />
<SectionBlock>
<SectionBlockIcon>
<NotificationsActive />
</SectionBlockIcon>
<SectionBlockTitle>Transactional Emails</SectionBlockTitle>
<SectionBlockSummary>
Receive emails for usage limit exceeds and team invitations.
</SectionBlockSummary>
<SectionBlockActions>
<Switch
loading={isLoadingInAppMail}
checked={isInAppMailStatus}
onChange={() => {}}
/>
</SectionBlockActions>
</SectionBlock>
<SectionBlockDivider />
</SectionBlockContainer>
import React from 'react'
import cx from 'classnames'
// Block
type SectionBlockProps = React.PropsWithChildren<{
icon?: React.ReactNode
}>
export function SectionBlock({ children, icon }: SectionBlockProps) {
const childs: React.ReactNode[] = React.Children.map(
children,
(child: React.ReactElement) => {
return React.cloneElement(child, {
...child.props,
})
}
)
const SectionBlockIcon = childs.find(
(child: any) => child.type.displayName === 'SectionBlockIcon'
)
const SectionBlockTitle = childs.find(
(child: any) => child.type.displayName === 'SectionBlockTitle'
)
const SectionBlockSummary = childs.find(
(child: any) => child.type.displayName === 'SectionBlockSummary'
)
const SectionBlockActions = childs.find(
(child: any) => child.type.displayName === 'SectionBlockActions'
)
return (
<div className="flex items-center py-6">
{SectionBlockIcon && (
<div className="w-10 mr-4 mt-0.5 flex self-start justify-center">
{SectionBlockIcon}
</div>
)}
<div className="flex-grow">
{SectionBlockTitle}
{SectionBlockSummary}
</div>
{SectionBlockActions && (
<div className="ml-10">{SectionBlockActions}</div>
)}
</div>
)
}
// Icon
type SectionBlockIconProps = React.PropsWithChildren<{
className?: string
}>
export function SectionBlockIcon({
children,
className,
...props
}: SectionBlockIconProps) {
return (
<div className={cx('text-xl', className)} {...props}>
{children}
</div>
)
}
SectionBlockIcon.displayName = 'SectionBlockIcon'
// Title
type SectionBlockTitleProps = React.PropsWithChildren<{
className?: string
}>
export function SectionBlockTitle({
children,
className,
...props
}: SectionBlockTitleProps) {
return (
<h3 className={cx('', className)} {...props}>
{children}
</h3>
)
}
SectionBlockTitle.displayName = 'SectionBlockTitle'
// Summary
type SectionBlockSummaryProps = React.PropsWithChildren<{
className?: string
}>
export function SectionBlockSummary({
children,
className,
...props
}: SectionBlockSummaryProps) {
return (
<div className={cx('text-gray-500', className)} {...props}>
{children}
</div>
)
}
SectionBlockSummary.displayName = 'SectionBlockSummary'
// Actions
type SectionBlockActionsProps = React.PropsWithChildren<{}>
export function SectionBlockActions({ children }: SectionBlockActionsProps) {
return <div>{children}</div>
}
SectionBlockActions.displayName = 'SectionBlockActions'
// Divider
type SectionBlockDividerProps = {
className?: string
}
export function SectionBlockDivider({
className,
...props
}: SectionBlockDividerProps) {
return (
<div
className={cx(
'border-0 border-b border-solid border-gray-200',
className
)}
{...props}
/>
)
}
// Container
type SectionBlockContainerProps = React.PropsWithChildren<{}>
export function SectionBlockContainer({
children,
}: SectionBlockContainerProps) {
return <div className="">{children}</div>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment