diff --git a/lib/bundle.css b/lib/bundle.css index 85e60c4e..d6134df3 100644 --- a/lib/bundle.css +++ b/lib/bundle.css @@ -127,6 +127,7 @@ a { grid-column-start: 1; } .ssb-accordion .accordion-body { + overflow-x: auto; font-family: "Open Sans", sans-serif !important; font-stretch: normal; font-weight: normal; @@ -2291,15 +2292,12 @@ a { padding: 1.25rem 1rem; } @media (max-width: 992px) { - .ssb-table-wrapper .ssb-table caption { - padding-top: 47px; + .ssb-table-wrapper .ssb-table caption:has(.visible) { + padding-top: 3rem; } .ssb-table-wrapper .ssb-table caption .caption-wrapper .scroll-icon-wrapper { margin-top: -100px; } - .ssb-table-wrapper .ssb-table caption .caption-wrapper.single-line .scroll-icon-wrapper { - margin-top: -70px; - } } .ssb-table-wrapper .ssb-table caption .icon-container { padding: 0 1rem; @@ -2423,20 +2421,19 @@ a { .ssb-table-wrapper .ssb-table .align-center { text-align: center; } - -.scroll-icon-active svg, -.scroll-icon:active svg { +.ssb-table-wrapper .scroll-icon-active svg, +.ssb-table-wrapper .scroll-icon:active svg { fill: var(--ssb-dark-5); transition: fill 0.18s; } -.scroll-icon-active svg line, -.scroll-icon-active svg polyline, -.scroll-icon:active svg line, -.scroll-icon:active svg polyline { +.ssb-table-wrapper .scroll-icon-active svg line, +.ssb-table-wrapper .scroll-icon-active svg polyline, +.ssb-table-wrapper .scroll-icon:active svg line, +.ssb-table-wrapper .scroll-icon:active svg polyline { stroke: var(--ssb-white); } -.scroll-icon-active svg circle, -.scroll-icon:active svg circle { +.ssb-table-wrapper .scroll-icon-active svg circle, +.ssb-table-wrapper .scroll-icon:active svg circle { stroke: var(--ssb-dark-5); transition: stroke 0.16s; } diff --git a/package-lock.json b/package-lock.json index a0f01468..92f56bb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@statisticsnorway/ssb-component-library", - "version": "2.2.14", + "version": "2.2.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@statisticsnorway/ssb-component-library", - "version": "2.2.14", + "version": "2.2.15", "license": "Apache-2.0", "dependencies": { "prismjs": "~1.29.0", diff --git a/package.json b/package.json index 66c26fd6..9c76e1b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@statisticsnorway/ssb-component-library", - "version": "2.2.14", + "version": "2.2.15", "description": "Component library for SSB (Statistics Norway)", "main": "lib/bundle.js", "scripts": { diff --git a/src/components/Accordion/_accordion.scss b/src/components/Accordion/_accordion.scss index 4fc2f57f..afb143b2 100644 --- a/src/components/Accordion/_accordion.scss +++ b/src/components/Accordion/_accordion.scss @@ -76,6 +76,8 @@ } .accordion-body { + overflow-x: auto; + @include open-sans; color: $ssb-dark-6; font-size: 16px; diff --git a/src/components/Table/README.md b/src/components/Table/README.md index 6b6b9475..ada30f1d 100644 --- a/src/components/Table/README.md +++ b/src/components/Table/README.md @@ -81,12 +81,14 @@ Available props: ##### Table -| Name | Type | Description | -| ------------ | ------------- | ---------------------------------------------------------------- | -| className | string | Optional styling classes | -| caption | string | Optional caption text | -| dataNoteRefs | string | Optional caption text for data-noterefs attribute | -| children | Required node | Table content (TableHead, TableBody, and TableFooter components) | +| Name | Type | Description | +| ------------------ | ------------- | ---------------------------------------------------------------- | +| id | string | Optional id | +| className | string | Optional styling classes | +| caption | string | Optional caption text | +| dataNoteRefs | string | Optional caption text for data-noterefs attribute | +| children | Required node | Table content (TableHead, TableBody, and TableFooter components) | +| checkIsOverflowing | boolean | Optional boolean that fires checkOverflow function in useEffect | ##### TableHead, TableBody, TableFooter, and TableRow diff --git a/src/components/Table/__snapshots__/table.test.tsx.snap b/src/components/Table/__snapshots__/table.test.tsx.snap index da123112..84e027a1 100644 --- a/src/components/Table/__snapshots__/table.test.tsx.snap +++ b/src/components/Table/__snapshots__/table.test.tsx.snap @@ -10,7 +10,7 @@ exports[`Render Table component Matches the snapshot 1`] = ` >
Table caption
+
diff --git a/src/components/Table/_table.scss b/src/components/Table/_table.scss index 37bf3931..1d694ef7 100644 --- a/src/components/Table/_table.scss +++ b/src/components/Table/_table.scss @@ -10,7 +10,7 @@ width: 100%; border-collapse: collapse; border: 1px solid variables.$ssb-dark-5; - + caption, th, td { @@ -68,15 +68,13 @@ padding: 1.25rem 1rem; @media (max-width: $desktop-screen) { - padding-top: 47px; + &:has(.visible){ + padding-top: 3rem; + } .caption-wrapper .scroll-icon-wrapper { margin-top: -100px; } - - .caption-wrapper.single-line .scroll-icon-wrapper { - margin-top: -70px; - } } .icon-container { @@ -247,22 +245,22 @@ text-align: center; } } -} - -.scroll-icon-active, -.scroll-icon:active { - svg { - fill: var(--ssb-dark-5); - transition: fill 0.18s; - } - - svg line, - svg polyline { - stroke: var(--ssb-white); - } - svg circle { - stroke: var(--ssb-dark-5); - transition: stroke 0.16s; + .scroll-icon-active, + .scroll-icon:active { + svg { + fill: var(--ssb-dark-5); + transition: fill 0.18s; + } + + svg line, + svg polyline { + stroke: var(--ssb-white); + } + + svg circle { + stroke: var(--ssb-dark-5); + transition: stroke 0.16s; + } } } diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index baeeb92e..9e594864 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -7,8 +7,10 @@ export interface TableElementProps { } export interface TableProps extends TableElementProps { + id?: string caption?: string dataNoteRefs?: string + checkIsOverflowing?: boolean } export interface TableCellProps { @@ -24,87 +26,70 @@ export interface TableCellProps { children?: ReactNode | string | number } -const Table = forwardRef(({ className, caption, dataNoteRefs, children }, ref) => { - const tableWrapperRef = useRef(null) - const iconWrapperRef = useRef(null) - const captionRef = useRef(null) - const [isOverflowing, setIsOverflowing] = useState(false) - const [isActive, setIsActive] = useState<{ left: boolean; right: boolean }>({ left: false, right: false }) - - type Direction = 'left' | 'right' +const Table = forwardRef( + ({ id, className, caption, dataNoteRefs, children, checkIsOverflowing }, ref) => { + const tableWrapperRef = useRef(null) + const iconWrapperRef = useRef(null) + const captionRef = useRef(null) + const [isOverflowing, setIsOverflowing] = useState(false) + const [isActive, setIsActive] = useState<{ left: boolean; right: boolean }>({ left: false, right: false }) - const handleScroll = (direction: Direction) => { - if (tableWrapperRef.current) { - const scrollAmount = direction === 'left' ? -380 : 380 - tableWrapperRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' }) - } - } + type Direction = 'left' | 'right' - const handleMouseClick = (direction: Direction) => { - handleScroll(direction) - if (document.activeElement instanceof HTMLElement) { - document.activeElement.blur() // Force blur to remove hover styles + const handleScroll = (direction: Direction) => { + if (tableWrapperRef.current) { + const scrollAmount = direction === 'left' ? -380 : 380 + tableWrapperRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' }) + } } - } - const handleKeyPress = (event: React.KeyboardEvent, direction: Direction) => { - if (event.key === 'Enter' || event.key === ' ') { - event.preventDefault() - setIsActive((prev) => ({ ...prev, [direction]: true })) + const handleMouseClick = (direction: Direction) => { handleScroll(direction) - setTimeout(() => { - setIsActive((prev) => ({ ...prev, [direction]: false })) - }, 150) + if (document.activeElement instanceof HTMLElement) { + document.activeElement.blur() // Force blur to remove hover styles + } } - } - useEffect(() => { - const checkOverflow = () => { - if (tableWrapperRef.current) { - const hasOverflow = tableWrapperRef.current.scrollWidth > tableWrapperRef.current.clientWidth - setIsOverflowing(hasOverflow) + const handleKeyPress = (event: React.KeyboardEvent, direction: Direction) => { + if (event.key === 'Enter' || event.key === ' ') { + event.preventDefault() + setIsActive((prev) => ({ ...prev, [direction]: true })) + handleScroll(direction) + setTimeout(() => { + setIsActive((prev) => ({ ...prev, [direction]: false })) + }, 150) } } - const checkCaptionHeight = () => { - if (captionRef.current) { - const computedStyle = window.getComputedStyle(captionRef.current) - const lineHeight = parseFloat(computedStyle.lineHeight) - const paddingTop = parseFloat(computedStyle.paddingTop) - const paddingBottom = parseFloat(computedStyle.paddingBottom) - const captionHeight = captionRef.current.clientHeight - paddingTop - paddingBottom - const lines = Math.round(captionHeight / lineHeight) - const parentElement = captionRef.current.parentElement as HTMLElement | null - if (parentElement) { - if (lines > 1) { - parentElement.classList.remove('single-line') - } else { - parentElement.classList.add('single-line') + useEffect(() => { + const checkOverflow = () => { + if (tableWrapperRef.current) { + const hasOverflow = tableWrapperRef.current.scrollWidth > tableWrapperRef.current.clientWidth + setIsOverflowing(hasOverflow) + + if (iconWrapperRef.current) { + iconWrapperRef.current.style.visibility = hasOverflow ? 'visible' : 'hidden' } } } - } + checkOverflow() + window.addEventListener('resize', checkOverflow) - checkOverflow() - checkCaptionHeight() - window.addEventListener('resize', checkOverflow) + return () => { + window.removeEventListener('resize', checkOverflow) + } + }, [checkIsOverflowing]) - return () => { - window.removeEventListener('resize', checkOverflow) - } - }, []) - - return ( -
- - {caption && ( - + )} + {children} +
-
-
- {caption} -
- {isOverflowing && ( -
+ return ( +
+ + {caption && ( + - )} - {children} -
+
+
+ {caption} +
+
(({ className, caption, da
- )} -
-
-
- ) -}) +
+
+
+ ) + } +) export default Table