Skip to content

Commit

Permalink
feat!: PageCounterのテキスト表示順序を可変できるようにする
Browse files Browse the repository at this point in the history
  • Loading branch information
AtsushiM committed May 23, 2024
1 parent 9639371 commit 232a63b
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,27 @@ const Template: StoryFn<ComponentProps<typeof PageCounter>> = (props) => <PageCo
export const All = () => (
<Stack>
<Template start={1} end={50} />
<Template start={1} end={50} total={5000} />
<Template
start={1}
end={50}
total={5000}
decorators={{ rangeSeparatorVisuallyHiddenText: () => '件から' }}
visibleOrder={{
range: 1,
total: 2,
}}
decorators={{
before: () => '(before)',
beforeRange: () => '(beforeRange)',
rangeSeparator: (org) => `(rangeSeparator: "${org}")`,
rangeSeparatorVisuallyHiddenText: (org) => `(rangeSeparatorVisuallyHiddenText: "${org}")`,
unit: (org) => `(unit: "${org}")`,
afterRange: () => '(afterRange)',
betweenTotalAndRange: () => '(betweenTotalAndRange)',
beforeTotal: () => '(beforeTotal)',
afterTotal: (org) => `(afterTotal: "${org}")`,
after: () => '(after)',
}}
/>
</Stack>
)
102 changes: 81 additions & 21 deletions packages/smarthr-ui/src/components/PageCounter/PageCounter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,33 @@ type Props = {
end: number
total?: number
decorators?: DecoratorsType<
'unitForTotal' | 'unit' | 'rangeSeparator' | 'rangeSeparatorVisuallyHiddenText'
| 'before'
| 'after'
| 'betweenTotalAndRange'
| 'beforeTotal'
| 'afterTotal'
| 'unit'
| 'beforeRange'
| 'afterRange'
| 'rangeSeparator'
| 'rangeSeparatorVisuallyHiddenText'
>
visibleOrder?: {
total: number
range: number
}
}
type ElementProps = Omit<ComponentPropsWithoutRef<'div'>, keyof Props>

const executeDecorator = (defaultText: string, decorator: DecoratorType | undefined) =>
decorator?.(defaultText) || defaultText

const UNIT_TOTAL_TEXT = '件中'
const VISIBLE_ORDER: Props['visibleOrder'] = {
total: 0,
range: 1,
}
const NULL_TEXT = ''
const AFTER_TOTAL_TEXT = '件中'
const UNIT_TEXT = '件'
const RANGE_SEPARATOR = '–'
const RANGE_SEPARATOR_VISUALLY_HIDDEN_TEXT = 'から'
Expand All @@ -30,15 +48,41 @@ export const PageCounter: React.FC<Props & ElementProps> = ({
start,
end,
total = 0,
visibleOrder = VISIBLE_ORDER,
decorators,
className,
...props
}) => {
const unitTotalText = useMemo(
() => executeDecorator(UNIT_TOTAL_TEXT, decorators?.unitForTotal),
[decorators?.unitForTotal],
const beforeText = useMemo(
() => executeDecorator(NULL_TEXT, decorators?.before),
[decorators?.before],
)
const afterText = useMemo(
() => executeDecorator(NULL_TEXT, decorators?.after),
[decorators?.after],
)
const betweenTotalAndRangeText = useMemo(
() => executeDecorator(NULL_TEXT, decorators?.betweenTotalAndRange),
[decorators?.betweenTotalAndRange],
)
const beforeTotalText = useMemo(
() => executeDecorator(NULL_TEXT, decorators?.beforeTotal),
[decorators?.beforeTotal],
)
const afterTotalText = useMemo(
() => executeDecorator(AFTER_TOTAL_TEXT, decorators?.afterTotal),
[decorators?.afterTotal],
)
const unitText = useMemo(() => executeDecorator(UNIT_TEXT, decorators?.unit), [decorators?.unit])
const beforeRangeText = useMemo(
() => executeDecorator(NULL_TEXT, decorators?.beforeRange),
[decorators?.beforeRange],
)
const afterRangeText = useMemo(
() => executeDecorator(NULL_TEXT, decorators?.afterRange),
[decorators?.afterRange],
)

const rangeSeparatorDecorators = useMemo(
() => ({
text: () => executeDecorator(RANGE_SEPARATOR, decorators?.rangeSeparator),
Expand All @@ -52,26 +96,42 @@ export const PageCounter: React.FC<Props & ElementProps> = ({
)
const style = useMemo(() => pageCounter({ className }), [className])

return (
<Cluster {...props} inline align="baseline" className={style}>
{total > 0 && (
<Cluster as="span" gap={0.25} inline align="baseline">
<Text weight="bold" as="b">
{total.toLocaleString()}
</Text>
{unitTotalText}
</Cluster>
)}
const totalElement =
total > 0 ? (
<Cluster as="span" gap={0.25} inline align="baseline">
{beforeTotalText}
<Text weight="bold" as="b">
{start.toLocaleString()}
</Text>
<RangeSeparator decorators={rangeSeparatorDecorators} />
<Text weight="bold" as="b">
{end.toLocaleString()}
{total.toLocaleString()}
</Text>
{unitText}
{afterTotalText}
</Cluster>
) : null
const rangeElemnt = (
<Cluster as="span" gap={0.25} inline align="baseline">
{beforeRangeText}
<Text weight="bold" as="b">
{start.toLocaleString()}
</Text>
<RangeSeparator decorators={rangeSeparatorDecorators} />
<Text weight="bold" as="b">
{end.toLocaleString()}
</Text>
{unitText}
{afterRangeText}
</Cluster>
)
const elements =
visibleOrder.total <= visibleOrder.range
? [totalElement, rangeElemnt]
: [rangeElemnt, totalElement]

return (
<Cluster {...props} inline align="baseline" className={style}>
{beforeText}
{elements[0]}
{betweenTotalAndRangeText}
{elements[1]}
{afterText}
</Cluster>
)
}

0 comments on commit 232a63b

Please sign in to comment.