From d35b91fa47529faa13a27ec4d934d3d0f63092ed Mon Sep 17 00:00:00 2001 From: Qs-F Date: Thu, 25 Jul 2024 20:11:31 +0900 Subject: [PATCH 1/6] docs(Table): add story for fixed columns --- .../src/components/Table/Table.stories.tsx | 87 +++++++++++++++++++ .../smarthr-ui/src/components/Table/Td.tsx | 6 +- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/packages/smarthr-ui/src/components/Table/Table.stories.tsx b/packages/smarthr-ui/src/components/Table/Table.stories.tsx index 66a49522e2..d1d29edbb4 100644 --- a/packages/smarthr-ui/src/components/Table/Table.stories.tsx +++ b/packages/smarthr-ui/src/components/Table/Table.stories.tsx @@ -622,6 +622,93 @@ export const WithReel: StoryFn = () => ( ) WithReel.storyName = 'with TableReel' +export const FixedColumns = () => ( + +) + const Ul = styled.ul` list-style: none; padding: 0; diff --git a/packages/smarthr-ui/src/components/Table/Td.tsx b/packages/smarthr-ui/src/components/Table/Td.tsx index df30d74a34..e314963cfb 100644 --- a/packages/smarthr-ui/src/components/Table/Td.tsx +++ b/packages/smarthr-ui/src/components/Table/Td.tsx @@ -54,7 +54,11 @@ const td = tv({ fixed: { true: [ 'fixedElement', - '[&.fixed]:shr-sticky [&.fixed]:shr-right-0 [&.fixed]:shr-bg-white [&.fixed]:after:shr-opacity-100', + 'shr-sticky shr-bg-white [&.fixed]:after:shr-opacity-100', + '[&:first-child]:shr-left-0', + '[&.fixed:first-child]:after:shr-left-full [&.fixed:first-child]:after:shr-bg-gradient-to-r', + '[&:last-child]:shr-right-0', + 'after:shr-right-full after:shr-bg-gradient-to-l', ], }, }, From 1051ecaaaf58d6e89c4918d0fa15634dae582bae Mon Sep 17 00:00:00 2001 From: Qs-F Date: Tue, 30 Jul 2024 11:58:40 +0900 Subject: [PATCH 2/6] fix: make dom iterable --- packages/smarthr-ui/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/smarthr-ui/tsconfig.json b/packages/smarthr-ui/tsconfig.json index 2337811344..21f9dd22a0 100644 --- a/packages/smarthr-ui/tsconfig.json +++ b/packages/smarthr-ui/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./lib", - "lib": ["es2020", "dom"], + "lib": ["es2020", "dom", "DOM.Iterable"], "target": "es2020", "module": "commonjs", "moduleResolution": "node", From 8c94a7f93ec7700bbdc2d414224d0e858668344c Mon Sep 17 00:00:00 2001 From: Qs-F Date: Tue, 30 Jul 2024 11:59:15 +0900 Subject: [PATCH 3/6] docs: update storybook --- .../src/components/Table/Table.stories.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/smarthr-ui/src/components/Table/Table.stories.tsx b/packages/smarthr-ui/src/components/Table/Table.stories.tsx index d1d29edbb4..0db7ceb243 100644 --- a/packages/smarthr-ui/src/components/Table/Table.stories.tsx +++ b/packages/smarthr-ui/src/components/Table/Table.stories.tsx @@ -630,8 +630,7 @@ export const FixedColumns = () => ( fixed - cell - cell + fixed cell cell cell @@ -651,10 +650,12 @@ export const FixedColumns = () => ( cell cell fixed + fixed + fixed fixed cell cell @@ -674,11 +675,11 @@ export const FixedColumns = () => ( cell cell cell - cell - cell + fixed fixed + fixed fixed cell cell @@ -698,8 +699,7 @@ export const FixedColumns = () => ( cell cell cell - cell - cell + fixed fixed From 919c8bbd30d25b5b8d7fbb6ecdc619a2b1f1f88f Mon Sep 17 00:00:00 2001 From: Qs-F Date: Tue, 30 Jul 2024 12:02:08 +0900 Subject: [PATCH 4/6] fix: collected into fixedCellStyle reel shadow related code --- .../smarthr-ui/src/components/Table/Td.tsx | 17 ++++----------- .../smarthr-ui/src/components/Table/Th.tsx | 14 ++++--------- .../src/components/Table/fixedCellStyle.ts | 21 +++++++++++++++++++ .../src/components/Table/useReelShadow.ts | 19 ----------------- 4 files changed, 29 insertions(+), 42 deletions(-) create mode 100644 packages/smarthr-ui/src/components/Table/fixedCellStyle.ts delete mode 100644 packages/smarthr-ui/src/components/Table/useReelShadow.ts diff --git a/packages/smarthr-ui/src/components/Table/Td.tsx b/packages/smarthr-ui/src/components/Table/Td.tsx index e314963cfb..2873d20db6 100644 --- a/packages/smarthr-ui/src/components/Table/Td.tsx +++ b/packages/smarthr-ui/src/components/Table/Td.tsx @@ -1,7 +1,7 @@ import React, { ComponentPropsWithoutRef, FC, PropsWithChildren, useMemo } from 'react' import { type VariantProps, tv } from 'tailwind-variants' -import { reelShadowStyle } from './useReelShadow' +import { fixedCellStyle } from './fixedCellStyle' import type { CellContentWidth } from './type' @@ -10,6 +10,7 @@ export type Props = PropsWithChildren< contentWidth?: | CellContentWidth | { base?: CellContentWidth; min?: CellContentWidth; max?: CellContentWidth } + fixed?: boolean } > type ElementProps = Omit, keyof Props> @@ -24,8 +25,8 @@ export const Td: FC = ({ ...props }) => { const styleProps = useMemo(() => { - const tdStyles = td({ align, nullable, fixed, className }) - const reelShadowStyles = fixed ? reelShadowStyle({ direction: 'right' }) : '' + const tdStyles = td({ align, nullable, className }) + const reelShadowStyles = fixed ? fixedCellStyle() : '' return { className: `${tdStyles} ${reelShadowStyles}`.trim(), style: { @@ -51,16 +52,6 @@ const td = tv({ nullable: { true: "empty:after:shr-content-['-----']", }, - fixed: { - true: [ - 'fixedElement', - 'shr-sticky shr-bg-white [&.fixed]:after:shr-opacity-100', - '[&:first-child]:shr-left-0', - '[&.fixed:first-child]:after:shr-left-full [&.fixed:first-child]:after:shr-bg-gradient-to-r', - '[&:last-child]:shr-right-0', - 'after:shr-right-full after:shr-bg-gradient-to-l', - ], - }, }, }) diff --git a/packages/smarthr-ui/src/components/Table/Th.tsx b/packages/smarthr-ui/src/components/Table/Th.tsx index 5f768cd022..aa1551ddfe 100644 --- a/packages/smarthr-ui/src/components/Table/Th.tsx +++ b/packages/smarthr-ui/src/components/Table/Th.tsx @@ -13,7 +13,7 @@ import { UnstyledButton } from '../Button' import { FaSortDownIcon, FaSortUpIcon } from '../Icon' import { VisuallyHiddenText } from '../VisuallyHiddenText' -import { reelShadowStyle } from './useReelShadow' +import { fixedCellStyle } from './fixedCellStyle' import type { CellContentWidth } from './type' @@ -29,6 +29,7 @@ export type Props = PropsWithChildren< sortDirectionIconAlt: (text: string, { sort }: { sort: sortTypes }) => ReactNode } contentWidth?: CellContentWidth + fixed?: boolean } & VariantProps > type ElementProps = Omit, keyof Props | 'onClick'> @@ -55,13 +56,6 @@ const thWrapper = tv({ left: '', right: 'shr-text-right', }, - fixed: { - true: [ - /* これ以降の記述はTableReel内で'fixed'を利用した際に追従させるために必要 */ - 'fixedElement', - '[&.fixed]:shr-sticky [&.fixed]:shr-right-0 [&.fixed]:after:shr-opacity-100', - ], - }, }, }) @@ -87,8 +81,8 @@ export const Th: FC = ({ ...props }) => { const styleProps = useMemo(() => { - const thWrapperStyle = thWrapper({ className, align, fixed }) - const reelShadowStyles = fixed ? reelShadowStyle({ showShadow: false, direction: 'right' }) : '' + const thWrapperStyle = thWrapper({ className, align }) + const reelShadowStyles = fixed ? fixedCellStyle() : '' return { className: `${thWrapperStyle} ${reelShadowStyles}`.trim(), style: { diff --git a/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts b/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts new file mode 100644 index 0000000000..7e00d791cf --- /dev/null +++ b/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts @@ -0,0 +1,21 @@ +import { tv } from 'tailwind-variants' + +export const fixedCellStyle = tv({ + base: [ + 'smarthr-ui-TableCell-fixed', + 'shr-sticky shr-bg-white [&.smarthr-ui-TableCell-fixed]:after:shr-opacity-100', + + 'after:shr-absolute after:shr-top-0 after:shr-z-0 after:shr-h-full after:shr-w-0.75 after:shr-from-[rgba(0,0,0,0.2)] after:shr-to-transparent after:shr-transition-all after:shr-duration-200 after:shr-content-[""] after:shr-visible', + /* 影の領域が広すぎるとクリッカブルエリアを侵食するので無効化 */ + 'after:shr-pointer-events-none', + + '[&.smarthr-ui-TableCell-fixed]:shr-left-[var(--prev-width)]', + '[&:has(+:not(.smarthr-ui-TableCell-fixed))]:after:shr-left-full [&:has(+:not(.smarthr-ui-TableCell-fixed))]:after:shr-bg-gradient-to-r', + + '[&.smarthr-ui-TableCell-fixed]:shr-right-[var(--next-width)]', + '[:not(.smarthr-ui-TableCell-fixed)+&.smarthr-ui-TableCell-fixed]:after:shr-right-full [:not(.smarthr-ui-TableCell-fixed)+&.smarthr-ui-TableCell-fixed]:after:shr-bg-gradient-to-l', + + '[.smarthr-ui-TableReel-scroll-reached-start_&:has(+:not(.smarthr-ui-TableCell-fixed))]:after:shr-opacity-0', + '[.smarthr-ui-TableReel-scroll-reached-end_:not(.smarthr-ui-TableCell-fixed)+&.smarthr-ui-TableCell-fixed]:after:shr-opacity-0', + ], +}) diff --git a/packages/smarthr-ui/src/components/Table/useReelShadow.ts b/packages/smarthr-ui/src/components/Table/useReelShadow.ts deleted file mode 100644 index 1b13a2f5d2..0000000000 --- a/packages/smarthr-ui/src/components/Table/useReelShadow.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { tv } from 'tailwind-variants' - -export const reelShadowStyle = tv({ - base: [ - 'after:shr-absolute after:shr-top-0 after:shr-z-0 after:shr-h-full after:shr-w-0.75 after:shr-from-[rgba(0,0,0,0.2)] after:shr-to-transparent after:shr-transition-opacity after:shr-duration-200 after:shr-content-[""]', - /* 影の領域が広すぎるとクリッカブルエリアを侵食するので無効化 */ - 'after:shr-pointer-events-none', - ], - variants: { - showShadow: { - true: 'after:shr-opacity-100', - false: 'after:shr-opacity-0', - }, - direction: { - left: 'after:shr-left-0 after:shr-bg-gradient-to-r', - right: 'after:shr-right-full after:shr-bg-gradient-to-l', - }, - }, -}) From cd40f980fe67662bbc4a4e24af08a5f31f758aa1 Mon Sep 17 00:00:00 2001 From: Qs-F Date: Tue, 30 Jul 2024 12:19:06 +0900 Subject: [PATCH 5/6] fix: fix to support multiple leading and trailing columns fixed --- .../src/components/Table/TableReel.tsx | 12 +++--- .../src/components/Table/useReelCells.ts | 37 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/packages/smarthr-ui/src/components/Table/TableReel.tsx b/packages/smarthr-ui/src/components/Table/TableReel.tsx index ecf635e3ee..914777a530 100644 --- a/packages/smarthr-ui/src/components/Table/TableReel.tsx +++ b/packages/smarthr-ui/src/components/Table/TableReel.tsx @@ -2,27 +2,29 @@ import React, { ComponentPropsWithRef, PropsWithChildren, useMemo } from 'react' import { tv } from 'tailwind-variants' import { useReelCells } from './useReelCells' -import { reelShadowStyle } from './useReelShadow' type ElementProps = Omit, keyof PropsWithChildren> const tableReel = tv({ slots: { wrapper: ['smarthr-ui-TableReel', 'shr-relative'], - inner: ['smarthr-ui-TableReel-inner', 'shr-relative shr-overflow-auto'], + inner: [ + 'smarthr-ui-TableReel-inner smarthr-ui-TableReel-scroll-reached-start', + 'shr-relative shr-overflow-auto', + ], }, }) export const TableReel: React.FC = ({ className, ...props }) => { - const { showShadow, tableWrapperRef } = useReelCells() + const { tableWrapperRef } = useReelCells() const { wrapperStyle, innerStyle } = useMemo(() => { const { wrapper, inner } = tableReel() return { - wrapperStyle: reelShadowStyle({ showShadow, className: wrapper({ className }) }), + wrapperStyle: wrapper({ className }), innerStyle: inner(), } - }, [className, showShadow]) + }, [className]) return (
diff --git a/packages/smarthr-ui/src/components/Table/useReelCells.ts b/packages/smarthr-ui/src/components/Table/useReelCells.ts index 0b444ab3fa..67f43b30bf 100644 --- a/packages/smarthr-ui/src/components/Table/useReelCells.ts +++ b/packages/smarthr-ui/src/components/Table/useReelCells.ts @@ -8,23 +8,28 @@ export const useReelCells = () => { const currentRef = tableWrapperRef.current const handleScroll = () => { - if (currentRef) { - const stickyCells = currentRef.querySelectorAll('.fixedElement') || [] - const scrollLeft = currentRef.scrollLeft - const maxScrollLeft = currentRef.scrollWidth - currentRef.clientWidth || 0 - - stickyCells.forEach((cell) => { - const shouldFix = maxScrollLeft > 0 && scrollLeft < maxScrollLeft - - if (shouldFix) { - cell.classList.add('fixed') - setShowShadow(scrollLeft > 0) - } else { - cell.classList.remove('fixed') - setShowShadow(maxScrollLeft === 0 && scrollLeft === 0 ? false : true) - } - }) + if (!currentRef) { + return } + const stickyCells = + (currentRef.querySelectorAll( + '.smarthr-ui-TableCell-fixed', + ) as unknown as HTMLCollectionOf) || [] + for (const stickyCell of stickyCells) { + const prevWidth = stickyCell.previousElementSibling?.clientWidth ?? 0 + const nextWidth = stickyCell.nextElementSibling?.clientWidth ?? 0 + stickyCell.style.setProperty('--prev-width', `${prevWidth}px`) + stickyCell.style.setProperty('--next-width', `${nextWidth}px`) + } + + const scrollLeft = currentRef.scrollLeft + const maxScrollLeft = currentRef.scrollWidth - currentRef.clientWidth || 0 + + const scrollReachedStart = scrollLeft <= 0 + const scrollReachedEnd = maxScrollLeft > 0 && scrollLeft >= maxScrollLeft + + currentRef.classList.toggle('smarthr-ui-TableReel-scroll-reached-start', scrollReachedStart) + currentRef.classList.toggle('smarthr-ui-TableReel-scroll-reached-end', scrollReachedEnd) } handleScroll() From f8d7c30c00b35dc21eebcaea6d50eac2e6edc02c Mon Sep 17 00:00:00 2001 From: Qs-F Date: Mon, 5 Aug 2024 12:35:22 +0900 Subject: [PATCH 6/6] fix: Fix only two columns fixed bug (WIP) --- .../src/components/Table/Table.stories.tsx | 15 +++++++++++++-- .../smarthr-ui/src/components/Table/TableReel.tsx | 2 +- .../src/components/Table/fixedCellStyle.ts | 2 +- .../src/components/Table/useReelCells.ts | 6 +++--- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/packages/smarthr-ui/src/components/Table/Table.stories.tsx b/packages/smarthr-ui/src/components/Table/Table.stories.tsx index 0db7ceb243..b2f28558e3 100644 --- a/packages/smarthr-ui/src/components/Table/Table.stories.tsx +++ b/packages/smarthr-ui/src/components/Table/Table.stories.tsx @@ -681,6 +681,7 @@ export const FixedColumns = () => ( fixed fixed + cell cell cell cell @@ -698,9 +699,10 @@ export const FixedColumns = () => ( cell cell cell - cell - fixed fixed + + + @@ -709,6 +711,15 @@ export const FixedColumns = () => ( ) +const FFButton = () => { + const [state, setState] = React.useState(false) + return ( + + ) +} + const Ul = styled.ul` list-style: none; padding: 0; diff --git a/packages/smarthr-ui/src/components/Table/TableReel.tsx b/packages/smarthr-ui/src/components/Table/TableReel.tsx index 914777a530..f72350f984 100644 --- a/packages/smarthr-ui/src/components/Table/TableReel.tsx +++ b/packages/smarthr-ui/src/components/Table/TableReel.tsx @@ -9,7 +9,7 @@ const tableReel = tv({ slots: { wrapper: ['smarthr-ui-TableReel', 'shr-relative'], inner: [ - 'smarthr-ui-TableReel-inner smarthr-ui-TableReel-scroll-reached-start', + 'smarthr-ui-TableReel-inner smarthr-ui-TableReel-scroll-reached-start smarthr-ui-TableReel-scroll-reached-end', 'shr-relative shr-overflow-auto', ], }, diff --git a/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts b/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts index 7e00d791cf..c8ec6c089c 100644 --- a/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts +++ b/packages/smarthr-ui/src/components/Table/fixedCellStyle.ts @@ -3,7 +3,7 @@ import { tv } from 'tailwind-variants' export const fixedCellStyle = tv({ base: [ 'smarthr-ui-TableCell-fixed', - 'shr-sticky shr-bg-white [&.smarthr-ui-TableCell-fixed]:after:shr-opacity-100', + 'shr-sticky shr-bg-white', 'after:shr-absolute after:shr-top-0 after:shr-z-0 after:shr-h-full after:shr-w-0.75 after:shr-from-[rgba(0,0,0,0.2)] after:shr-to-transparent after:shr-transition-all after:shr-duration-200 after:shr-content-[""] after:shr-visible', /* 影の領域が広すぎるとクリッカブルエリアを侵食するので無効化 */ diff --git a/packages/smarthr-ui/src/components/Table/useReelCells.ts b/packages/smarthr-ui/src/components/Table/useReelCells.ts index 67f43b30bf..5764bd020a 100644 --- a/packages/smarthr-ui/src/components/Table/useReelCells.ts +++ b/packages/smarthr-ui/src/components/Table/useReelCells.ts @@ -16,8 +16,8 @@ export const useReelCells = () => { '.smarthr-ui-TableCell-fixed', ) as unknown as HTMLCollectionOf) || [] for (const stickyCell of stickyCells) { - const prevWidth = stickyCell.previousElementSibling?.clientWidth ?? 0 - const nextWidth = stickyCell.nextElementSibling?.clientWidth ?? 0 + const prevWidth = stickyCell.previousElementSibling?.getBoundingClientRect().width ?? 0 + const nextWidth = stickyCell.nextElementSibling?.getBoundingClientRect().width ?? 0 stickyCell.style.setProperty('--prev-width', `${prevWidth}px`) stickyCell.style.setProperty('--next-width', `${nextWidth}px`) } @@ -26,7 +26,7 @@ export const useReelCells = () => { const maxScrollLeft = currentRef.scrollWidth - currentRef.clientWidth || 0 const scrollReachedStart = scrollLeft <= 0 - const scrollReachedEnd = maxScrollLeft > 0 && scrollLeft >= maxScrollLeft + const scrollReachedEnd = maxScrollLeft <= 0 || scrollLeft >= maxScrollLeft currentRef.classList.toggle('smarthr-ui-TableReel-scroll-reached-start', scrollReachedStart) currentRef.classList.toggle('smarthr-ui-TableReel-scroll-reached-end', scrollReachedEnd)