Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOP-5258: make collapsibles interactive offline #1330

Merged
merged 6 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions src/components/Collapsible/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import { cx } from '@leafygreen-ui/emotion';
import { Body } from '@leafygreen-ui/typography';
import { HeadingContextProvider } from '../../context/heading-context';
import { findAllNestedAttribute } from '../../utils/find-all-nested-attribute';
import { OFFLINE_CLASSNAME } from '../../utils/head-scripts/offline-ui/collapsible';
import { isBrowser } from '../../utils/is-browser';
import { isOfflineDocsBuild } from '../../utils/is-offline-docs-build';
import { reportAnalytics } from '../../utils/report-analytics';
import ComponentFactory from '../ComponentFactory';
import Heading from '../Heading';
Expand All @@ -25,7 +27,10 @@ const Collapsible = ({ nodeData: { children, options }, sectionDepth, ...rest })
return findAllNestedAttribute(children, 'id');
}, [children]);

const [open, setOpen] = useState(expanded ?? true);
const [open, setOpen] = useState(() => {
if (isOfflineDocsBuild || expanded) return true;
return expanded ?? true;
seungpark marked this conversation as resolved.
Show resolved Hide resolved
});
const headingNodeData = {
id,
children: [{ type: 'text', value: heading }],
Expand Down Expand Up @@ -67,7 +72,10 @@ const Collapsible = ({ nodeData: { children, options }, sectionDepth, ...rest })

return (
<HeadingContextProvider ignoreNextHeading={true} heading={heading}>
<Box className={cx('collapsible', collapsibleStyle)}>
<Box
aria-expanded={open}
className={cx('collapsible', collapsibleStyle, isOfflineDocsBuild ? OFFLINE_CLASSNAME : '')}
>
<Box className={cx(headerContainerStyle)}>
<Box>
{/* Adding 1 to reflect logic in parser, but want to show up as H2 for SEO reasons */}
Expand All @@ -76,11 +84,16 @@ const Collapsible = ({ nodeData: { children, options }, sectionDepth, ...rest })
</Heading>
<Body baseFontSize={13}>{subHeading}</Body>
</Box>
<IconButton className={iconStyle} aria-labelledby={'Expand the collapsed content'} onClick={onIconClick}>
<IconButton
className={iconStyle}
aria-labelledby={'Expand the collapsed content'}
aria-expanded={open}
onClick={onIconClick}
>
<Icon glyph={open ? 'ChevronDown' : 'ChevronRight'} />
</IconButton>
</Box>
<Box className={cx(innerContentStyle(open))}>
<Box className={cx(innerContentStyle)}>
{children.map((c, i) => (
<ComponentFactory nodeData={c} key={i} sectionDepth={sectionDepth} {...rest}></ComponentFactory>
))}
Expand Down
12 changes: 9 additions & 3 deletions src/components/Collapsible/styles.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { css } from '@leafygreen-ui/emotion';
import { palette } from '@leafygreen-ui/palette';
import { theme } from '../../theme/docsTheme';
import { OFFLINE_CLASSNAME } from '../../utils/head-scripts/offline-ui/collapsible';

export const collapsibleStyle = css`
border-bottom: 1px solid ${palette.gray.light2};
Expand Down Expand Up @@ -29,13 +30,18 @@ export const headerStyle = css`
export const iconStyle = css`
align-self: center;
flex-shrink: 0;

.${OFFLINE_CLASSNAME}[aria-expanded=false] & {
transform: rotate(-90deg);
}
`;

export const innerContentStyle = (open) => css`
export const innerContentStyle = css`
overflow: hidden;
height: 0;
color: --font-color-primary;

${open && `height: auto;`}
${open && `visibility: visible;`}
[aria-expanded='true'] & {
height: auto;
}
`;
2 changes: 1 addition & 1 deletion src/components/ComponentFactoryLazy.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ComponentMap = {
};

export const LAZY_COMPONENTS = Object.keys(ComponentMap).reduce((res, key) => {
if (isOfflineDocsBuild && key === 'instruqt') {
if (isOfflineDocsBuild && ['video', 'instruqt'].includes(key)) {
res[key] = (props) => (!props.nodeData?.options?.drawer ? <OfflineNotAvailable assetKey={key} /> : null);
} else {
const LazyComponent = ComponentMap[key];
Expand Down
24 changes: 24 additions & 0 deletions src/utils/head-scripts/offline-ui/collapsible.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function bindCollapsibleUI() {
const onContentLoaded = () => {
try {
const collapsibleComponents = document.querySelectorAll('.offline-collapsible');
for (const collapsible of collapsibleComponents) {
// bind event to button
const button = collapsible.querySelector('button');
button?.addEventListener('click', () => {
const newVal = button.getAttribute('aria-expanded') === 'false';
button.setAttribute('aria-expanded', newVal);
collapsible.setAttribute('aria-expanded', newVal);
});
}
} catch (e) {
console.error(e);
}
};

document.addEventListener('DOMContentLoaded', onContentLoaded, false);
}

export default bindCollapsibleUI;

export const OFFLINE_CLASSNAME = `offline-collapsible`;
5 changes: 3 additions & 2 deletions src/utils/head-scripts/offline-ui/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import bindTabUI from './tabs';
import bindCollapsibleUI from './collapsible';
import updateSidenavHeight from './sidenav';
import bindTabsSelectorsUI from './tabs-selectors';
const OFFLINE_UI_CLASSNAME = 'snooty-offline-ui';
Expand All @@ -12,6 +13,6 @@ const getScript = ({ key, fn }) => (
/>
);

export const OFFLINE_HEAD_SCRIPTS = [bindTabUI, updateSidenavHeight, bindTabsSelectorsUI].map((fn, idx) =>
getScript({ key: `offline-docs-ui-${idx}`, fn })
export const OFFLINE_HEAD_SCRIPTS = [bindTabUI, updateSidenavHeight, bindTabsSelectorsUI, bindCollapsibleUI].map(
(fn, idx) => getScript({ key: `offline-docs-ui-${idx}`, fn })
);
13 changes: 13 additions & 0 deletions tests/unit/__snapshots__/Collapsible.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ exports[`collapsible component renders all the content in the options and childr
background-color: rgba(61,79,88,0.1);
}

.offline-collapsible[aria-expanded=false] .emotion-8 {
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
}

.emotion-9 {
position: absolute;
top: 0;
Expand All @@ -186,6 +193,10 @@ exports[`collapsible component renders all the content in the options and childr
color: --font-color-primary;
}

[aria-expanded='true'] .emotion-10 {
height: auto;
}

.emotion-11 {
margin: unset;
font-family: 'Euclid Circular A','Helvetica Neue',Helvetica,Arial,sans-serif;
Expand Down Expand Up @@ -509,6 +520,7 @@ exports[`collapsible component renders all the content in the options and childr
}

<div
aria-expanded="false"
class="collapsible emotion-0"
>
<div
Expand Down Expand Up @@ -557,6 +569,7 @@ exports[`collapsible component renders all the content in the options and childr
</div>
<button
aria-disabled="false"
aria-expanded="false"
aria-labelledby="Expand the collapsed content"
class="emotion-8"
tabindex="0"
Expand Down
Loading