|
| 1 | +import React, { ElementType, useContext } from 'react' |
| 2 | +import styled from 'styled-components' |
| 3 | +import { PC, PP, PR } from '../../types/PolymorphicElementProps' |
| 4 | +import { ItemizeContext } from './ItemizeContext' |
| 5 | + |
| 6 | +const marginMap = { |
| 7 | + none: '0', |
| 8 | + normal: '1em', |
| 9 | + wide: '2em', |
| 10 | +} |
| 11 | + |
| 12 | +interface ItemizeContainerProps { |
| 13 | + marker: string |
| 14 | + margin: 'none' | 'normal' | 'wide' |
| 15 | +} |
| 16 | + |
| 17 | +const ItemizeContainer = styled.ul<ItemizeContainerProps>` |
| 18 | + padding-inline-start: 4ch; |
| 19 | + margin-block-start: ${({ margin }) => marginMap[margin]}; |
| 20 | + margin-block-end: ${({ margin }) => marginMap[margin]}; |
| 21 | + margin-inline-start: 0; |
| 22 | + margin-inline-end: 0; |
| 23 | + list-style-type: '${({ marker }) => marker} '; |
| 24 | + & > li::marker { |
| 25 | + color: ${({ theme }) => theme.color.text.secondary.main}; |
| 26 | + } |
| 27 | +` |
| 28 | + |
| 29 | +export interface ItemizeProps { |
| 30 | + marker?: string |
| 31 | + margin?: 'none' | 'normal' | 'wide' |
| 32 | +} |
| 33 | + |
| 34 | +export const Itemize: PC<'ul', ItemizeProps> = React.forwardRef( |
| 35 | + <T extends ElementType>(props: PP<T, ItemizeProps>, ref?: PR<T>) => { |
| 36 | + const itemizeContext = useContext(ItemizeContext) |
| 37 | + const { |
| 38 | + margin = itemizeContext.level === 0 ? 'normal' : 'none', |
| 39 | + marker = itemizeContext.level === 0 ? '✓' : '–', |
| 40 | + as = 'ul', |
| 41 | + ...rest |
| 42 | + } = props |
| 43 | + |
| 44 | + return ( |
| 45 | + <ItemizeContext.Provider |
| 46 | + value={{ marker, usesCounter: false, level: itemizeContext.level + 1 }} |
| 47 | + > |
| 48 | + <ItemizeContainer |
| 49 | + margin={margin} |
| 50 | + marker={marker} |
| 51 | + ref={ref} |
| 52 | + as={as} |
| 53 | + {...rest} |
| 54 | + /> |
| 55 | + </ItemizeContext.Provider> |
| 56 | + ) |
| 57 | + } |
| 58 | +) |
0 commit comments