diff --git a/packages/react/src/__tests__/__snapshots__/storyshots.test.js.snap b/packages/react/src/__tests__/__snapshots__/storyshots.test.js.snap index 9d35ccff73f..5dbc86a662d 100644 --- a/packages/react/src/__tests__/__snapshots__/storyshots.test.js.snap +++ b/packages/react/src/__tests__/__snapshots__/storyshots.test.js.snap @@ -36373,12 +36373,16 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` }, "props": Object { "ContentGroupPictograms": Object { - "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", - "heading": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.", + "heading": "Lorem ipsum dolor sit amet", "items": Array [ Object { - "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.", - "cta": null, + "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.", + "cta": Object { + "copy": "Lorem ipsum dolor sit amet ", + "href": "https://www.example.com", + "type": "local", + }, "heading": "Aliquam condimentum interdum", "pictogram": Object { "aria-label": "Pictogram", @@ -36389,8 +36393,12 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` }, }, Object { - "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.", - "cta": null, + "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.", + "cta": Object { + "copy": "Lorem ipsum dolor sit amet ", + "href": "https://www.example.com", + "type": "local", + }, "heading": "Aliquam condimentum interdum", "pictogram": Object { "aria-label": "Pictogram", @@ -36401,8 +36409,12 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` }, }, Object { - "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.", - "cta": null, + "copy": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.", + "cta": Object { + "copy": "Lorem ipsum dolor sit amet ", + "href": "https://www.example.com", + "type": "local", + }, "heading": "Aliquam condimentum interdum", "pictogram": Object { "aria-label": "Pictogram", @@ -36424,10 +36436,7 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` "heading": "Aliquam condimentum interdum", "pictogram": Object { "aria-label": "Pictogram", - "src": Object { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - }, + "src": undefined, }, }, ], @@ -36452,13 +36461,17 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` >
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Lorem ipsum dolor sit amet
Lorem ipsum dolor sit amet, consectetur adipiscing elit.

", + "__html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.

", } } /> @@ -36527,8 +36548,14 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` > - - +
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.

", + "__html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.

", } } data-autoid="dds--content-item__copy" /> + + +
@@ -36623,8 +36748,14 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` - - +
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.

", + "__html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.

", } } data-autoid="dds--content-item__copy" /> + + +
@@ -36719,8 +36948,14 @@ exports[`Storyshots Components|Content group pictograms Default 1`] = ` - - +
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.

", + "__html": "

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.

", } } data-autoid="dds--content-item__copy" /> + + +
@@ -39785,7 +40118,9 @@ exports[`Storyshots Components|Dotcom shell Default (footer language only) 1`] = } } > - + - + - + - +
@@ -71528,7 +71869,9 @@ exports[`Storyshots Components|Dotcom shell With micro footer (language only) 1` } } > - + - + - + - + - + { switch (sel) { - case 'Desktop': - return Desktop; + case 'TouchScreen': + return TouchScreen; case 'Pattern': return Pattern; case 'Touch': @@ -46,7 +46,7 @@ const toggleCTA = item => { return { type: 'local', href: 'https://www.example.com', - copy: 'Lorem ipsum dolor', + copy: 'Lorem ipsum dolor sit amet ', }; } else { return null; @@ -76,18 +76,18 @@ export default { ), copy: text( `Item ${i + 1} Copy (items.copy)`, - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et ultricies est. Mauris iaculis eget dolor nec hendrerit. Phasellus at elit sollicitudin, sodales nulla quis, consequat libero.', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.', groupId ), cta: toggleCTA( - boolean(`Item ${i + 1} CTA (items.cta)`, false, groupId) + boolean(`Item ${i + 1} CTA (items.cta)`, true, groupId) ), pictogram: { src: selectPictogram( select( `Item ${i + 1} Pictogram (pictogram)`, pictograms, - pictograms.Desktop, + pictograms.TouchScreen, groupId ) ), @@ -98,12 +98,12 @@ export default { return { heading: text( 'Pattern title (heading)', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Lorem ipsum dolor sit amet', groupId ), copy: text( 'Copy (copy)', - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum non porttitor libero, in venenatis magna.', groupId ), items, diff --git a/packages/react/src/components/DotcomShell/__stories__/DotcomShell.stories.js b/packages/react/src/components/DotcomShell/__stories__/DotcomShell.stories.js index 094ed9106fe..dd353cd4cea 100644 --- a/packages/react/src/components/DotcomShell/__stories__/DotcomShell.stories.js +++ b/packages/react/src/components/DotcomShell/__stories__/DotcomShell.stories.js @@ -57,7 +57,7 @@ export const Default = ({ parameters }) => {
- +
diff --git a/packages/react/src/components/DotcomShell/__stories__/data/content.js b/packages/react/src/components/DotcomShell/__stories__/data/content.js index d5905861b28..9b3d6a6d077 100644 --- a/packages/react/src/components/DotcomShell/__stories__/data/content.js +++ b/packages/react/src/components/DotcomShell/__stories__/data/content.js @@ -35,6 +35,7 @@ import logoMicrosoft from '../../../../../../storybook-images/assets/logos/logo- import logoRabobank from '../../../../../../storybook-images/assets/logos/logo-rabobank.png'; import logoUsBank from '../../../../../../storybook-images/assets/logos/logo-usbank.png'; +import PropTypes from 'prop-types'; import React from 'react'; /** @@ -42,9 +43,12 @@ import React from 'react'; * * @returns {*} JSX for Learn template */ -const Content = () => ( +const Content = ({ withL1 }) => ( <> - + ( ); +Content.propTypes = { + /** + * `true` if content is rendered with an L1 on the page + */ + withL1: PropTypes.bool, +}; + export default Content; diff --git a/packages/react/src/components/Masthead/Masthead.js b/packages/react/src/components/Masthead/Masthead.js index 1411b02ceda..f79a8282b99 100644 --- a/packages/react/src/components/Masthead/Masthead.js +++ b/packages/react/src/components/Masthead/Masthead.js @@ -148,28 +148,30 @@ const Masthead = ({ [`${prefix}--masthead__header--search-active`]: isSearchActive, }); + const [scrollOffset, setScrollOffset] = useState(window.scrollY); + useEffect(() => { /** * Sets sticky masthead. If both L0 and L1 are present, L1 will be sticky. * */ - const hideTopnavThreshold = 0.25; const handleScroll = root.addEventListener('scroll', () => { /** - * L0 will hide/show only in the top 25% of the viewport. + * L0 will hide on scroll down, show on scroll up * */ if (mastheadL1Ref.current != null) { - setIsMastheadSticky( - root.pageYOffset > root.innerHeight * hideTopnavThreshold - ); + const prevOffset = scrollOffset; + const currOffset = window.scrollY; + setIsMastheadSticky(currOffset > prevOffset); + setScrollOffset(currOffset); } }); return () => { root.removeEventListener('scroll', () => handleScroll); }; - }, []); + }, [scrollOffset]); if (navigation) { switch (typeof navigation) { diff --git a/packages/react/src/components/TableOfContents/TOCDesktop.js b/packages/react/src/components/TableOfContents/TOCDesktop.js index a96431e2d97..4c5d084bd13 100644 --- a/packages/react/src/components/TableOfContents/TOCDesktop.js +++ b/packages/react/src/components/TableOfContents/TOCDesktop.js @@ -58,7 +58,10 @@ const TOCDesktop = ({ menuItems, selectedId }) => { const handleOnClick = (e, id) => { e.preventDefault(); const selector = `a[name="${id}"]`; - smoothScroll(null, selector); + const masthead = e.target.ownerDocument.querySelector( + `.${prefix}--masthead` + ); + smoothScroll(null, selector, masthead?.offsetHeight); triggerFocus(selector); }; diff --git a/packages/react/src/components/TableOfContents/TableOfContents.js b/packages/react/src/components/TableOfContents/TableOfContents.js index a3228c40e0c..f9817f9831b 100644 --- a/packages/react/src/components/TableOfContents/TableOfContents.js +++ b/packages/react/src/components/TableOfContents/TableOfContents.js @@ -121,7 +121,7 @@ const TableOfContents = ({ .filter((elem, index, arr) => elem.height === null ? arr[index - 1].position < arr[index - 1].height - : elem.position - 50 > -elem.height + : elem.position - 50 - stickyOffset > -elem.height ); // Sets last section as active at the end of page in case there is not enough height for it to dynamically activate diff --git a/packages/react/tests/e2e-storybook/cypress/integration/LinkList/LinkList.e2e.js b/packages/react/tests/e2e-storybook/cypress/integration/LinkList/LinkList.e2e.js index 6763d928411..c31a75d0220 100644 --- a/packages/react/tests/e2e-storybook/cypress/integration/LinkList/LinkList.e2e.js +++ b/packages/react/tests/e2e-storybook/cypress/integration/LinkList/LinkList.e2e.js @@ -4,7 +4,7 @@ * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ -import getCssPropertyForRule from '../../../../utils/get-css-property-for-rule'; +import getCssPropertyForRule from '../../utils/get-css-property-for-rule'; /** * Sets the correct path diff --git a/packages/react/tests/utils/get-css-property-for-rule.js b/packages/react/tests/e2e-storybook/cypress/utils/get-css-property-for-rule.js similarity index 100% rename from packages/react/tests/utils/get-css-property-for-rule.js rename to packages/react/tests/e2e-storybook/cypress/utils/get-css-property-for-rule.js diff --git a/packages/styles/scss/components/content-block-mixed/_content-block-mixed.scss b/packages/styles/scss/components/content-block-mixed/_content-block-mixed.scss index 74cca735a2d..ec1020add6d 100644 --- a/packages/styles/scss/components/content-block-mixed/_content-block-mixed.scss +++ b/packages/styles/scss/components/content-block-mixed/_content-block-mixed.scss @@ -8,6 +8,14 @@ @mixin content-block-mixed { :host(dds-content-block-mixed), .#{$prefix}--content-block-mixed { + .#{$prefix}--content-group-pictograms { + margin-left: -$carbon--spacing-05; + .#{$prefix}--pictogram-item__row { + width: calc(100% + 16px); + max-width: calc(100% + 16px); + } + } + .#{$prefix}--layout-1-3 { @include carbon--breakpoint-down('md') { .#{$prefix}--link-list__list.#{$prefix}--link-list__list--card { diff --git a/packages/styles/scss/components/content-group-pictograms/_content-group-pictograms.scss b/packages/styles/scss/components/content-group-pictograms/_content-group-pictograms.scss index 46f0f503078..60e13208aee 100644 --- a/packages/styles/scss/components/content-group-pictograms/_content-group-pictograms.scss +++ b/packages/styles/scss/components/content-group-pictograms/_content-group-pictograms.scss @@ -10,12 +10,24 @@ ::slotted(#{$dds-prefix}-content-group-copy), .#{$prefix}--content-group-pictograms .#{$prefix}--content-group__copy { margin-bottom: $spacing-05; + margin-left: $spacing-05; + margin-right: $spacing-05; @include carbon--breakpoint('md') { margin-bottom: $spacing-07; } } + div.#{$prefix}--content-group-pictograms { + padding-left: 0; + padding-right: 0; + + .#{$prefix}--content-group__title { + padding-left: $spacing-05; + padding-right: $spacing-05; + } + } + .#{$prefix}--content-group-pictograms__item:last-child { .#{$prefix}--content-item { margin-bottom: 0; diff --git a/packages/styles/scss/components/masthead/_masthead.scss b/packages/styles/scss/components/masthead/_masthead.scss index a8df785574e..412d6a5969b 100755 --- a/packages/styles/scss/components/masthead/_masthead.scss +++ b/packages/styles/scss/components/masthead/_masthead.scss @@ -213,25 +213,26 @@ $search-transition-timing: 95ms; } .#{$prefix}--masthead--sticky.#{$prefix}--masthead--sticky__l1 { + top: -98px; + @include carbon--breakpoint-up(800px) { top: -48px; } } - .#{$prefix}--masthead--sticky__l1 + .#{$prefix}--dotcom-shell { - @include carbon--breakpoint-up(800px) { - .#{$prefix}--tableofcontents__sidebar { - top: 98px; - } - } + .#{$prefix}--masthead--sticky__l1 + + .#{$prefix}--dotcom-shell + .#{$prefix}--tableofcontents__sidebar { + top: 98px; } .#{$prefix}--masthead--sticky__l1.#{$prefix}--masthead--sticky - + .#{$prefix}--dotcom-shell { + + .#{$prefix}--dotcom-shell .#{$prefix}--tableofcontents__sidebar { - @include carbon--breakpoint-up(800px) { - top: 48px; - } + top: 0; + + @include carbon--breakpoint-up(800px) { + top: 48px; } } diff --git a/packages/styles/scss/components/pictogram-item/_pictogram-item.scss b/packages/styles/scss/components/pictogram-item/_pictogram-item.scss index 471daf66051..bee050ceaa4 100644 --- a/packages/styles/scss/components/pictogram-item/_pictogram-item.scss +++ b/packages/styles/scss/components/pictogram-item/_pictogram-item.scss @@ -16,10 +16,11 @@ .#{$prefix}--pictogram-item__row { @include carbon--make-row; + margin-left: 0; + margin-right: 0; + max-width: 100%; - @include carbon--breakpoint('md') { - max-width: 75%; - } + @include carbon--breakpoint('lg') { max-width: 100%; } @@ -43,6 +44,10 @@ @include carbon--breakpoint('md') { @include carbon--make-col(6, 8); } + + @include carbon--breakpoint('max') { + padding-right: $carbon--spacing-11; + } } .#{$prefix}--pictogram-item__pictogram, @@ -53,9 +58,6 @@ width: 80px; } } - :host(#{$dds-prefix}-pictogram-item) { - padding-left: $carbon--spacing-05; - } } @include exports('pictogram-item') { diff --git a/packages/web-components/src/components/dotcom-shell/dotcom-shell-composite.ts b/packages/web-components/src/components/dotcom-shell/dotcom-shell-composite.ts index 71ff0c1f651..96b4491ee43 100644 --- a/packages/web-components/src/components/dotcom-shell/dotcom-shell-composite.ts +++ b/packages/web-components/src/components/dotcom-shell/dotcom-shell-composite.ts @@ -26,6 +26,7 @@ import { FOOTER_SIZE } from '../footer/footer'; import '../footer/footer-composite'; import './dotcom-shell'; import styles from './dotcom-shell-composite.scss'; +import DDSTableOfContents from '../table-of-contents/table-of-contents'; const { prefix } = settings; const { stablePrefix: ddsPrefix } = ddsSettings; @@ -85,6 +86,11 @@ class DDSDotcomShellComposite extends LitElement { */ private _masthead?: HTMLElement; + /** + * The tableOfContents element. + */ + private _tableOfContents?: DDSTableOfContents; + /** * The tableOfContents inner navBar or sideBar depending on layout. */ @@ -178,10 +184,20 @@ class DDSDotcomShellComposite extends LitElement { this._masthead!.style.top = `${mastheadTop}px`; } } else if (l1Element) { - this._masthead!.style.top = `-${Math.min( - this._masthead!.offsetHeight - l1Element.offsetHeight, - Math.abs(mastheadTop) - )}px`; + const toc = this._tableOfContents; + const stickyOffset = Number(toc?.getAttribute('stickyOffset')); + if (window.scrollY < this._lastScrollPosition) { + // scrolling up + this._masthead!.style.top = '0'; + toc!.stickyOffset = stickyOffset + l1Element.offsetHeight; + } else { + // scrolling down + this._masthead!.style.top = `-${Math.min( + this._masthead!.offsetHeight - l1Element.offsetHeight, + Math.abs(mastheadTop) + )}px`; + toc!.stickyOffset = Math.max(stickyOffset - l1Element.offsetHeight, stickyOffset); + } } else if (this._tableOfContentsLayout === 'horizontal') { this._tableOfContentsInnerBar!.style.top = `${Math.max(Math.min(tocPosition, this._masthead!.offsetHeight), 0)}px`; this._masthead!.style.top = `${mastheadTop}px`; @@ -579,7 +595,8 @@ class DDSDotcomShellComposite extends LitElement { super.update(changedProperties); if (!this._tableOfContentsInnerBar) { - const toc = document.querySelector(`${ddsPrefix}-table-of-contents`); + this._tableOfContents = document.querySelector(`${ddsPrefix}-table-of-contents`) as DDSTableOfContents; + const toc = this._tableOfContents; if (toc?.getAttribute('toc-layout') === 'horizontal') { this._tableOfContentsInnerBar = toc?.shadowRoot?.querySelector(`.${prefix}--tableofcontents__navbar`) as HTMLElement; this._tableOfContentsLayout = 'horizontal'; diff --git a/packages/web-components/src/components/table-of-contents/table-of-contents.ts b/packages/web-components/src/components/table-of-contents/table-of-contents.ts index 4b22ede196e..8945a272858 100644 --- a/packages/web-components/src/components/table-of-contents/table-of-contents.ts +++ b/packages/web-components/src/components/table-of-contents/table-of-contents.ts @@ -275,7 +275,9 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen position: elem.getBoundingClientRect().y, })) .filter((elem, index, arr) => - elem.height === null ? arr[index - 1].position < arr[index - 1].height! : elem.position - 50 > -elem.height + elem.height === null + ? arr[index - 1].position < arr[index - 1].height! + : elem.position - 50 - this.stickyOffset > -elem.height ); // Sets last section as active at the end of page in case there is not enough height for it to dynamically activate @@ -659,7 +661,7 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen : ``}