diff --git a/package.json b/package.json index 9fe4475c7f..2cd25a13ec 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "no-githooks": "git config --unset core.hooksPath" }, "dependencies": { - "@ably/ui": "15.7.0", + "@ably/ui": "15.8.1", "@codesandbox/sandpack-react": "^2.9.0", "@mdx-js/react": "^2.3.0", "@react-hook/media-query": "^1.1.1", diff --git a/src/components/Article/index.tsx b/src/components/Article/index.tsx index c6033c1b1f..1aa0df84bb 100644 --- a/src/components/Article/index.tsx +++ b/src/components/Article/index.tsx @@ -2,7 +2,7 @@ import React, { FunctionComponent as FC } from 'react'; import { ArticleFooter } from './ArticleFooter'; const Article: FC<{ children: React.ReactNode }> = ({ children }) => ( - <article className="flex-1 overflow-x-hidden"> + <article className="flex-1 overflow-x-hidden relative z-10"> {children} <ArticleFooter /> </article> diff --git a/src/components/Layout/Breadcrumbs.test.tsx b/src/components/Layout/Breadcrumbs.test.tsx index 9395f1830b..6219fb7bf6 100644 --- a/src/components/Layout/Breadcrumbs.test.tsx +++ b/src/components/Layout/Breadcrumbs.test.tsx @@ -58,4 +58,29 @@ describe('Breadcrumbs', () => { expect(screen.getByText('Current Page')).toHaveClass('text-gui-unavailable'); expect(screen.getByText('Current Page')).toHaveClass('pointer-events-none'); }); + + it('removes duplicate links from breadcrumb nodes', () => { + mockUseLayoutContext.mockReturnValue({ + activePage: { + tree: [ + { page: { name: 'Section 1', link: '/section-1' } }, + { page: { name: 'Duplicate Section', link: '/section-1' } }, + { page: { name: 'Current Page', link: '/section-1/page-1' } }, + ], + }, + }); + + render(<Breadcrumbs />); + + // Should only show one instance of the duplicate link + const section1Links = screen.getAllByText('Section 1'); + expect(section1Links).toHaveLength(1); + + // Should not render the duplicate with different text + expect(screen.queryByText('Duplicate Section')).not.toBeInTheDocument(); + + // Should still render other breadcrumb elements + expect(screen.getByText('Home')).toBeInTheDocument(); + expect(screen.getByText('Current Page')).toBeInTheDocument(); + }); }); diff --git a/src/components/Layout/Breadcrumbs.tsx b/src/components/Layout/Breadcrumbs.tsx index 0a6c146dc9..4d09220b1f 100644 --- a/src/components/Layout/Breadcrumbs.tsx +++ b/src/components/Layout/Breadcrumbs.tsx @@ -3,15 +3,22 @@ import { useLayoutContext } from 'src/contexts/layout-context'; import Link from '../Link'; import Icon from '@ably/ui/core/Icon'; import cn from '@ably/ui/core/utils/cn'; -import { hierarchicalKey } from './utils/nav'; +import { hierarchicalKey, PageTreeNode } from './utils/nav'; const Breadcrumbs: React.FC = () => { const { activePage } = useLayoutContext(); - const breadcrumbNodes = useMemo( - () => activePage?.tree.filter((node) => node.page.link !== '#') ?? [], - [activePage.tree], - ); + const breadcrumbNodes = useMemo(() => { + const filteredNodes = activePage?.tree.filter((node) => node.page.link !== '#') ?? []; + const uniqueNodes = filteredNodes.reduce((acc: PageTreeNode[], current) => { + const isDuplicate = acc.some((item) => item.page.link === current.page.link); + if (!isDuplicate) { + acc.push(current); + } + return acc; + }, []); + return uniqueNodes; + }, [activePage?.tree]); if (breadcrumbNodes.length === 0) { return null; diff --git a/src/components/Layout/Header.test.tsx b/src/components/Layout/Header.test.tsx index 6b1b4e2b9f..b309f91966 100644 --- a/src/components/Layout/Header.test.tsx +++ b/src/components/Layout/Header.test.tsx @@ -29,6 +29,14 @@ jest.mock('./LeftSidebar', () => ({ default: jest.fn(() => <div>LeftSidebar</div>), })); +jest.mock('@reach/router', () => ({ + useLocation: jest.fn(), +})); + +jest.mock('./LanguageSelector', () => ({ + LanguageSelector: jest.fn(() => <div>LanguageSelector</div>), +})); + describe('Header', () => { beforeEach(() => { document.body.innerHTML = ''; @@ -92,7 +100,11 @@ describe('Header', () => { value={{ sessionState: { signedIn: true, - account: { links: { dashboard: { href: '/dashboard', text: 'Dashboard' } } }, + account: { + id: 'test-id', + name: 'Test Account', + links: { dashboard: { href: '/dashboard', text: 'Dashboard' } }, + }, }, apps: [], }} diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index bcad48507c..19cd7c2cec 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -1,4 +1,5 @@ -import React, { useState, useEffect, useContext } from 'react'; +import React, { useContext } from 'react'; +import { useLocation } from '@reach/router'; import Icon from '@ably/ui/core/Icon'; import AblyHeader from '@ably/ui/core/Header'; import { SearchBar } from '../SearchBar'; @@ -10,7 +11,7 @@ type HeaderProps = { }; const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { - const [showMenu, setShowMenu] = useState(false); + const location = useLocation(); const userContext = useContext(UserContext); const sessionState = { ...userContext.sessionState, @@ -33,30 +34,6 @@ const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { // } // }; - useEffect(() => { - const handleResize = () => { - if (window.innerWidth >= 1040) { - setShowMenu(false); - } - }; - - window.addEventListener('resize', handleResize); - return () => window.removeEventListener('resize', handleResize); - }, []); - - useEffect(() => { - if (showMenu) { - document.body.classList.add('overflow-hidden'); - } else { - document.body.classList.remove('overflow-hidden'); - } - - // Cleanup on unmount - return () => { - document.body.classList.remove('overflow-hidden'); - }; - }, [showMenu]); - return ( <AblyHeader // TODO: reenable when examples are ready to be released @@ -86,7 +63,7 @@ const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { mobileNav={<LeftSidebar inHeader key="nav-mobile-documentation-tab" />} searchButton={ <button - className="cursor-pointer focus-base rounded" + className="cursor-pointer focus-base rounded px-0 pt-4 text-neutral-1300 dark:text-neutral-000" aria-label="Toggle search" onClick={() => { const searchContainer = document.querySelector('#inkeep-search > div'); @@ -125,6 +102,7 @@ const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { ]} sessionState={sessionState} logoHref="/docs" + location={location} /> ); }; diff --git a/src/components/Layout/LanguageSelector.tsx b/src/components/Layout/LanguageSelector.tsx index 637d538b10..866ba8fe72 100644 --- a/src/components/Layout/LanguageSelector.tsx +++ b/src/components/Layout/LanguageSelector.tsx @@ -1,22 +1,17 @@ -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef, useState, MouseEvent, TouchEvent } from 'react'; import { useLocation } from '@reach/router'; import Select from 'react-select'; import Badge from '@ably/ui/core/Badge'; import Icon from '@ably/ui/core/Icon'; import { IconName } from '@ably/ui/core/Icon/types'; import cn from '@ably/ui/core/utils/cn'; +import { componentMaxHeight, HEADER_BOTTOM_MARGIN, HEADER_HEIGHT } from '@ably/ui/core/utils/heights'; import { languageData, languageInfo } from 'src/data/languages'; import { LanguageKey } from 'src/data/languages/types'; import { useOnClickOutside } from 'src/hooks'; import { useLayoutContext } from 'src/contexts/layout-context'; import { navigate } from '../Link'; -import { - componentMaxHeight, - HEADER_HEIGHT, - HEADER_BOTTOM_MARGIN, - LANGUAGE_SELECTOR_HEIGHT, - INKEEP_ASK_BUTTON_HEIGHT, -} from './utils/heights'; +import { LANGUAGE_SELECTOR_HEIGHT, INKEEP_ASK_BUTTON_HEIGHT } from './utils/heights'; type LanguageSelectorOptionData = { label: LanguageKey; @@ -38,6 +33,16 @@ const LanguageSelectorOption = ({ isOption, setMenuOpen, langParam, ...props }: const lang = languageInfo[props.data.label]; const location = useLocation(); + const handleClick = (e: MouseEvent<HTMLDivElement> | TouchEvent<HTMLDivElement>) => { + e.preventDefault(); + + if (isOption) { + navigate(`${location.pathname}?lang=${props.data.label}`); + } + + setMenuOpen(!props.selectProps.menuIsOpen); + }; + return ( <div className={cn( @@ -46,13 +51,8 @@ const LanguageSelectorOption = ({ isOption, setMenuOpen, langParam, ...props }: 'p-8 hover:bg-neutral-100 dark:hover:bg-neutral-1200 cursor-pointer': isOption, }, )} - onClick={() => { - if (isOption) { - navigate(`${location.pathname}?lang=${props.data.label}`); - } - - setMenuOpen(!props.selectProps.menuIsOpen); - }} + onClick={handleClick} + onTouchEnd={handleClick} role="menuitem" > <div className={cn('flex items-center gap-8', { 'flex-1': isOption })}> @@ -111,8 +111,16 @@ export const LanguageSelector = () => { setSelectedOption(defaultOption); }, [langParam, options]); + const handleClick = (e: MouseEvent<HTMLButtonElement> | TouchEvent<HTMLButtonElement>) => { + e.preventDefault(); + setMenuOpen(!menuOpen); + }; + return ( - <div ref={selectRef} className="absolute top-0 right-0 md:relative w-full text-right md:text-left mb-24 focus-base"> + <div + ref={selectRef} + className="md:relative w-full text-right md:text-left mb-24 focus-base -mt-4 md:mt-0 -mr-4 md:mr-0" + > <Select options={options} value={selectedOption} @@ -134,10 +142,12 @@ export const LanguageSelector = () => { ), SingleValue: (props) => <LanguageSelectorOption {...props} setMenuOpen={setMenuOpen} langParam={langParam} />, IndicatorSeparator: null, - DropdownIndicator: (props) => ( + DropdownIndicator: () => ( <button - className="flex items-center pl-8 text-red-orange" - onClick={() => setMenuOpen(!props.selectProps.menuIsOpen)} + role="button" + className="flex items-center pl-8 text-red-orange cursor-pointer" + onClick={handleClick} + onTouchEnd={handleClick} aria-label="Toggle language dropdown" > <Icon @@ -161,7 +171,9 @@ export const LanguageSelector = () => { }} role="menu" > - <p className="ui-text-overline2 py-16 px-8 text-neutral-700 dark:text-neutral-600">Code Language</p> + <p className="ui-text-overline2 text-left py-16 px-8 text-neutral-700 dark:text-neutral-600"> + Code Language + </p> {children} </div> ), diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index a03bd2bfa5..7d63075dc6 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -24,7 +24,7 @@ const Layout: React.FC<LayoutProps> = ({ children, pageContext }) => { return ( <GlobalLoading template={template}> <Header searchBar={searchBar} /> - <div className="flex pt-64 gap-80 justify-center ui-standard-container mx-auto"> + <div className="flex pt-64 md:gap-48 lg:gap-64 xl:gap-80 justify-center ui-standard-container mx-auto"> {sidebar ? <LeftSidebar /> : null} <Container as="main" className="flex-1"> {sidebar ? <Breadcrumbs /> : null} diff --git a/src/components/Layout/LeftSidebar.tsx b/src/components/Layout/LeftSidebar.tsx index bb267a37de..901ce7b94f 100644 --- a/src/components/Layout/LeftSidebar.tsx +++ b/src/components/Layout/LeftSidebar.tsx @@ -1,5 +1,5 @@ import { useMemo, useState, useEffect, useRef } from 'react'; -import { useLocation } from '@reach/router'; +import { navigate, useLocation } from '@reach/router'; import cn from '@ably/ui/core/utils/cn'; import Accordion from '@ably/ui/core/Accordion'; import Icon from '@ably/ui/core/Icon'; @@ -130,6 +130,26 @@ const constructProductNavData = ( return { name: product.name, icon: activePageTree[0]?.page.name === product.name ? product.icon.open : product.icon.closed, + onClick: () => { + // When a product is clicked, find and scroll to any open accordion element + if (typeof document !== 'undefined') { + // Use setTimeout to ensure the DOM has updated after the click and animation has completed + setTimeout(() => { + const targetAccordion = window.innerWidth >= 1040 ? 'left-nav' : 'mobile-nav'; + const menuContainer = document.getElementById(targetAccordion); + const openAccordion: HTMLElement | null = menuContainer + ? menuContainer.querySelector('[data-state="open"] > button') + : null; + + if (openAccordion) { + menuContainer?.scrollTo({ + top: openAccordion.offsetTop, + behavior: 'smooth', + }); + } + }, 200); + } + }, content: ( <div key={product.name} className="flex flex-col gap-20 px-16 pt-12"> {product.showJumpLink ? ( @@ -163,6 +183,18 @@ const constructProductNavData = ( }; }); + // Add a Home entry at the start of navData if inHeader is true + if (inHeader) { + navData.unshift({ + name: 'Home', + content: null, + onClick: () => { + navigate('/docs'); + }, + interactive: false, + }); + } + return navData; }; @@ -192,29 +224,18 @@ const LeftSidebar = ({ inHeader = false }: LeftSidebarProps) => { ); return ( - <> - {inHeader ? ( - <a - href="/docs" - aria-label="Home" - className="flex w-full items-center focus-base text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1100 active:text-neutral-1000 transition-colors h-40 ui-text-menu1 font-bold px-16 mt-16" - > - Home - </a> - ) : null} - <Accordion - ref={sidebarRef} - className={cn( - !inHeader && [sidebarAlignmentClasses, 'hidden md:block md:-mx-16'], - 'overflow-y-auto', - hasScrollbar ? 'md:pr-8' : 'md:pr-16', - )} - style={sidebarAlignmentStyles} - id="left-nav" - data={productNavData} - {...commonAccordionOptions(null, activePage.tree[0]?.index, true, inHeader)} - /> - </> + <Accordion + ref={sidebarRef} + className={cn( + !inHeader && [sidebarAlignmentClasses, 'hidden md:block md:-mx-16'], + 'overflow-y-auto', + hasScrollbar ? 'md:pr-8' : 'md:pr-16', + )} + style={sidebarAlignmentStyles} + id={inHeader ? 'mobile-nav' : 'left-nav'} + data={productNavData} + {...commonAccordionOptions(null, activePage.tree[0]?.index, true, inHeader)} + /> ); }; diff --git a/src/components/Layout/RightSidebar.tsx b/src/components/Layout/RightSidebar.tsx index a8a0f6c527..60119b6f43 100644 --- a/src/components/Layout/RightSidebar.tsx +++ b/src/components/Layout/RightSidebar.tsx @@ -3,12 +3,13 @@ import { useLocation, WindowLocation } from '@reach/router'; import cn from '@ably/ui/core/utils/cn'; import Icon from '@ably/ui/core/Icon'; import { IconName } from '@ably/ui/core/Icon/types'; +import { componentMaxHeight, HEADER_HEIGHT, HEADER_BOTTOM_MARGIN } from '@ably/ui/core/utils/heights'; import { LanguageSelector } from './LanguageSelector'; import { useLayoutContext } from 'src/contexts/layout-context'; import { languageInfo } from 'src/data/languages'; import { PageTreeNode, sidebarAlignmentClasses, sidebarAlignmentStyles } from './utils/nav'; -import { componentMaxHeight, HEADER_HEIGHT, HEADER_BOTTOM_MARGIN, INKEEP_ASK_BUTTON_HEIGHT } from './utils/heights'; +import { INKEEP_ASK_BUTTON_HEIGHT } from './utils/heights'; type SidebarHeader = { id: string; diff --git a/src/components/Layout/utils/heights.ts b/src/components/Layout/utils/heights.ts index 788218ed2b..c0119bd371 100644 --- a/src/components/Layout/utils/heights.ts +++ b/src/components/Layout/utils/heights.ts @@ -3,18 +3,6 @@ these values to prevent magic numbers popping up with no obvious reasoning. When making alterations to Layout components, consider these values and update where necessary. */ -export const HEADER_HEIGHT = 64; -export const HEADER_BOTTOM_MARGIN = 24; + export const LANGUAGE_SELECTOR_HEIGHT = 38; export const INKEEP_ASK_BUTTON_HEIGHT = 96; - -/** - * Calculates the maximum height for a component by subtracting the total of given heights from 100vh. - * - * @param {...number} heights - An array of heights in pixels. - * @returns {string} The CSS calc expression for the maximum height. - */ -export const componentMaxHeight = (...heights: number[]): string => { - const totalHeight = heights.reduce((sum, height) => sum + height, 0) + 'px'; - return `calc(100vh - ${totalHeight})`; -}; diff --git a/src/components/Layout/utils/nav.ts b/src/components/Layout/utils/nav.ts index 630d7720df..0cf19c92cf 100644 --- a/src/components/Layout/utils/nav.ts +++ b/src/components/Layout/utils/nav.ts @@ -1,8 +1,8 @@ import cn from '@ably/ui/core/utils/cn'; import { AccordionProps } from '@ably/ui/core/Accordion'; +import { HEADER_HEIGHT, componentMaxHeight } from '@ably/ui/core/utils/heights'; import { ProductData, ProductKey } from 'src/data/types'; import { NavProductContent, NavProductPage, NavProductPages } from 'src/data/nav/types'; -import { componentMaxHeight, HEADER_HEIGHT } from './heights'; import { LanguageKey } from 'src/data/languages/types'; export type PageTreeNode = { index: number; page: NavProductPage }; @@ -131,7 +131,7 @@ export const commonAccordionOptions = ( { 'my-12': topLevel && inHeader, 'h-40 ui-text-menu1 !font-bold md:ui-text-menu4 px-16': topLevel, - 'h-[1rem] ui-text-menu2 !font-semibold md:ui-text-menu4': !topLevel, + 'min-h-[1.625em] md:min-h-[1.375em] ui-text-menu2 !font-semibold md:ui-text-menu4': !topLevel, }, ), selectedHeaderCSS: '!text-neutral-1300 mb-8', diff --git a/src/components/Markdown/CodeBlock.tsx b/src/components/Markdown/CodeBlock.tsx index 90e90aeb38..941a40f92c 100644 --- a/src/components/Markdown/CodeBlock.tsx +++ b/src/components/Markdown/CodeBlock.tsx @@ -29,7 +29,7 @@ export const CodeBlock: FC<{ children: React.ReactNode; language: string }> = ({ }; return ( - <pre className="bg-cool-black text-white p-0 rounded-lg relative"> + <pre className="bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full"> <div className="overflow-auto relative p-16 pr-32"> <code className="ui-text-code" diff --git a/src/components/Redoc/Loader.tsx b/src/components/Redoc/Loader.tsx index 1474035829..3c1ca638a4 100644 --- a/src/components/Redoc/Loader.tsx +++ b/src/components/Redoc/Loader.tsx @@ -4,7 +4,7 @@ import { GoTopButton } from './GoTopButton'; import { overrideMenuItemNavigation } from './utils'; export const Loader = ({ specUrl }: { specUrl: string }) => { - const redocDependencyScript = '//cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js'; + const redocDependencyScript = '//cdn.redoc.ly/redoc/v2.4.0/bundles/redoc.standalone.js'; const options = { hideDownloadButton: true, scrollYOffset: 64, diff --git a/src/components/blocks/list/Dl/index.tsx b/src/components/blocks/list/Dl/index.tsx index 0dabe53d21..e72470bab4 100644 --- a/src/components/blocks/list/Dl/index.tsx +++ b/src/components/blocks/list/Dl/index.tsx @@ -6,7 +6,7 @@ import cn from '@ably/ui/core/utils/cn'; const Dl = ({ data, attribs }: HtmlComponentProps<'dl'>) => { return ( - <dl {...attribs} className={cn(attribs?.className, listDl, 'ui-text-p2')}> + <dl {...attribs} className={cn(attribs?.className, listDl, 'ui-text-p2 max-w-[calc(100vw-48px)] sm:max-w-full')}> <Html data={data} BlockWrapper={DlWrapper} /> </dl> ); diff --git a/src/components/blocks/software/Pre.tsx b/src/components/blocks/software/Pre.tsx index 16d547248f..b3e04a5324 100644 --- a/src/components/blocks/software/Pre.tsx +++ b/src/components/blocks/software/Pre.tsx @@ -64,12 +64,14 @@ const Pre = ({ languages = getLanguagesSDKInterface(languages, selectedSDKInterfaceTab); } + const codeClassName = 'bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full'; + const hasCode = languages?.some((lang) => getTrimmedLanguage(lang) === pageLanguage) || pageLanguage === DEFAULT_LANGUAGE; const shouldDisplayTip = !hasCode && languages?.length !== undefined; const withModifiedClassname = { ...attribs, - className: `bg-cool-black text-white p-0 rounded-lg relative`, + className: codeClassName, }; const dataTreatedAsCode = data && !isString(data) && every((element) => element.type === HtmlDataTypes.text, data); @@ -79,7 +81,7 @@ const Pre = ({ const stringToRender = reduce((acc, curr) => acc.concat((curr.data as string) ?? ''), '', data); return ( - <pre {...attribs} className="bg-cool-black text-white p-0 rounded-lg relative overflow-hidden"> + <pre {...attribs} className={codeClassName}> <div className="overflow-auto relative p-16"> <MultilineCodeContent dataContainsKey={false} diff --git a/src/components/blocks/software/__snapshots__/Pre.test.tsx.snap b/src/components/blocks/software/__snapshots__/Pre.test.tsx.snap index 799f4277f4..c39734a60a 100644 --- a/src/components/blocks/software/__snapshots__/Pre.test.tsx.snap +++ b/src/components/blocks/software/__snapshots__/Pre.test.tsx.snap @@ -5,7 +5,7 @@ exports[`<Pre /> should render code block when no languages are passed 1`] = ` class="my-32" > <pre - class="bg-cool-black text-white p-0 rounded-lg relative" + class="bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full" > useVars = false; </pre> @@ -17,7 +17,7 @@ exports[`<Pre /> should successfully render Code elements with language 1`] = ` class="my-32" > <pre - class="bg-cool-black text-white p-0 rounded-lg relative" + class="bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full" > <div class="border-b border-charcoal-grey w-full" @@ -118,7 +118,7 @@ exports[`<Pre /> should successfully render code elements with only Realtime la class="my-32" > <pre - class="bg-cool-black text-white p-0 rounded-lg relative" + class="bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full" > <div class="bg-dark-grey border-charcoal-grey text-white border-b-4 rounded-t-lg flex justify-end" @@ -248,7 +248,7 @@ exports[`<Pre /> should successfully render code elements with only Rest langua class="my-32" > <pre - class="bg-cool-black text-white p-0 rounded-lg relative" + class="bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full" > <div class="bg-dark-grey border-charcoal-grey text-white border-b-4 rounded-t-lg flex justify-end" @@ -378,7 +378,7 @@ exports[`<Pre /> should successfully render code elements with both Rest and Rea class="my-32" > <pre - class="bg-cool-black text-white p-0 rounded-lg relative" + class="bg-cool-black text-white p-0 rounded-lg relative max-w-[calc(100vw-48px)] sm:max-w-full" > <div class="bg-dark-grey border-charcoal-grey text-white border-b-4 rounded-t-lg flex justify-end" diff --git a/src/components/blocks/table/Table.tsx b/src/components/blocks/table/Table.tsx index 8bc510f1ba..9160f20867 100644 --- a/src/components/blocks/table/Table.tsx +++ b/src/components/blocks/table/Table.tsx @@ -12,7 +12,7 @@ const Table = ({ data, attribs }: HtmlComponentProps<'table'>) => { } return ( - <div className={tableContainer}> + <div className={cn(tableContainer, 'max-w-[calc(100vw-48px)] sm:max-w-full')}> <table className={cn('border-0 border-collapse mb-4 border-spacing-0 ui-text-p2 text-left', table)} {...attribs}> <Html data={data.filter((item) => item.type === HtmlDataTypes.tag)} /> </table> diff --git a/src/components/blocks/wrappers/__snapshots__/ConditionalChildrenLanguageDisplay.test.js.snap b/src/components/blocks/wrappers/__snapshots__/ConditionalChildrenLanguageDisplay.test.js.snap index cfc7627a74..159ca3d19c 100644 --- a/src/components/blocks/wrappers/__snapshots__/ConditionalChildrenLanguageDisplay.test.js.snap +++ b/src/components/blocks/wrappers/__snapshots__/ConditionalChildrenLanguageDisplay.test.js.snap @@ -2,7 +2,7 @@ exports[`Integration: ConditionalChildrenLanguageDisplay only displays one <dt><dd> pair of children from alternatives for parsed definition lists ConditionalChildrenLanguageDisplay displays the expected results from HTML data 1`] = ` <dl - className="listDl ui-text-p2" + className="listDl ui-text-p2 max-w-[calc(100vw-48px)] sm:max-w-full" > diff --git a/yarn.lock b/yarn.lock index a76e7337b0..3daf60b441 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,10 +7,10 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@ably/ui@15.7.0": - version "15.7.0" - resolved "https://registry.yarnpkg.com/@ably/ui/-/ui-15.7.0.tgz#b95626272fc8ba43162878b8a6016a7f86264ce8" - integrity sha512-1FBs+S9NUa0/6U5kZaAo+BIi8VZDoN8yG3dUeUzZ9m48bvigDgUP+AQtGOSiItD5aP6TiSHWnatERk/J/jN0Tw== +"@ably/ui@15.8.1": + version "15.8.1" + resolved "https://registry.yarnpkg.com/@ably/ui/-/ui-15.8.1.tgz#be59ffe07c0ce826c1061adbcb8ff2a75dcfd78c" + integrity sha512-o2wpZEHpXDeLH1i+YaEeBf2PxqnG3EzBmmqB4Lx80NjbpTXFY19wI25bZ53fUuFroU04Yj1UQ/T94Qmbld6wkg== dependencies: "@radix-ui/react-accordion" "^1.2.1" "@radix-ui/react-navigation-menu" "^1.2.4"