15b6cd93dSBartosz Kaszubowskiimport { css } from '@emotion/react'; 2f4b1168bSBartosz Kaszubowskiimport { LinkBase } from '@expo/styleguide'; 3586106d6SBartłomiej Klocekimport * as React from 'react'; 4586106d6SBartłomiej Klocek 5586106d6SBartłomiej Klocekimport { AdditionalProps } from '~/common/headingManager'; 652aab7caSKeith Kurakimport PermalinkIcon from '~/components/icons/Permalink'; 71f61a071SBartosz Kaszubowskiimport withHeadingManager, { 81f61a071SBartosz Kaszubowski HeadingManagerProps, 91f61a071SBartosz Kaszubowski} from '~/components/page-higher-order/withHeadingManager'; 10586106d6SBartłomiej Klocek 111f61a071SBartosz Kaszubowskitype BaseProps = React.PropsWithChildren<{ 12586106d6SBartłomiej Klocek component: any; 13586106d6SBartłomiej Klocek className?: string; 143c9a6b96SBartosz Kaszubowski style?: React.CSSProperties; 151f61a071SBartosz Kaszubowski}>; 16586106d6SBartłomiej Klocek 171f61a071SBartosz Kaszubowskitype EnhancedProps = React.PropsWithChildren<{ 18cb5b8d03SBartosz Kaszubowski // Sidebar heading level override 19586106d6SBartłomiej Klocek nestingLevel?: number; 20586106d6SBartłomiej Klocek additionalProps?: AdditionalProps; 21586106d6SBartłomiej Klocek id?: string; 221f61a071SBartosz Kaszubowski}>; 23586106d6SBartłomiej Klocek 24929e0953SCedric van Puttenconst STYLES_PERMALINK_TARGET = css` 25929e0953SCedric van Putten display: block; 26929e0953SCedric van Putten position: absolute; 27b5ea8c8fSBartosz Kaszubowski top: -46px; 28929e0953SCedric van Putten visibility: hidden; 29929e0953SCedric van Putten`; 30929e0953SCedric van Putten 31929e0953SCedric van Puttenconst STYLES_PERMALINK_LINK = css` 32b5ea8c8fSBartosz Kaszubowski position: relative; 33929e0953SCedric van Putten color: inherit; 34cb5b8d03SBartosz Kaszubowski text-decoration: none !important; 35929e0953SCedric van Putten 36929e0953SCedric van Putten /* Disable link when used in collapsible, to allow expand on click */ 37929e0953SCedric van Putten details & { 38929e0953SCedric van Putten pointer-events: none; 39929e0953SCedric van Putten } 40929e0953SCedric van Putten`; 41929e0953SCedric van Putten 42929e0953SCedric van Puttenconst STYLED_PERMALINK_CONTENT = css` 439e30a8beSCedric van Putten display: inline; 44929e0953SCedric van Putten`; 45929e0953SCedric van Putten 46929e0953SCedric van Puttenconst STYLES_PERMALINK_ICON = css` 47929e0953SCedric van Putten cursor: pointer; 48f4b1168bSBartosz Kaszubowski vertical-align: middle; 49929e0953SCedric van Putten display: inline-block; 50929e0953SCedric van Putten width: 1.2em; 51f4b1168bSBartosz Kaszubowski height: 1em; 52929e0953SCedric van Putten padding: 0 0.2em; 53929e0953SCedric van Putten visibility: hidden; 54929e0953SCedric van Putten 558c97fc97SBartosz Kaszubowski a:hover &, 568c97fc97SBartosz Kaszubowski a:focus-visible & { 57929e0953SCedric van Putten visibility: visible; 58929e0953SCedric van Putten } 59929e0953SCedric van Putten 60929e0953SCedric van Putten svg { 61929e0953SCedric van Putten width: 100%; 62929e0953SCedric van Putten height: auto; 63929e0953SCedric van Putten } 64929e0953SCedric van Putten`; 65929e0953SCedric van Putten 661f61a071SBartosz Kaszubowskiconst PermalinkBase = ({ component, children, className, ...rest }: BaseProps) => 67929e0953SCedric van Putten React.cloneElement( 68586106d6SBartłomiej Klocek component, 69586106d6SBartłomiej Klocek { 70586106d6SBartłomiej Klocek className: [className, component.props.className || ''].join(' '), 71586106d6SBartłomiej Klocek ...rest, 72586106d6SBartłomiej Klocek }, 73586106d6SBartłomiej Klocek children 74586106d6SBartłomiej Klocek ); 75586106d6SBartłomiej Klocek 761f61a071SBartosz Kaszubowskiconst Permalink: React.FC<EnhancedProps> = withHeadingManager( 771f61a071SBartosz Kaszubowski (props: EnhancedProps & HeadingManagerProps) => { 78586106d6SBartłomiej Klocek // NOTE(jim): Not the greatest way to generate permalinks. 79586106d6SBartłomiej Klocek // for now I've shortened the length of permalinks. 80586106d6SBartłomiej Klocek const component = props.children as JSX.Element; 81586106d6SBartłomiej Klocek const children = component.props.children || ''; 82586106d6SBartłomiej Klocek 83df72b035SBartosz Kaszubowski if (!props.nestingLevel) { 84df72b035SBartosz Kaszubowski return children; 85df72b035SBartosz Kaszubowski } 86df72b035SBartosz Kaszubowski 87df72b035SBartosz Kaszubowski const heading = props.headingManager.addHeading( 88fccf9c8cSCedric van Putten children, 89fccf9c8cSCedric van Putten props.nestingLevel, 90fccf9c8cSCedric van Putten props.additionalProps, 91b5ea8c8fSBartosz Kaszubowski props.id 92df72b035SBartosz Kaszubowski ); 93586106d6SBartłomiej Klocek 94586106d6SBartłomiej Klocek return ( 9524f68907SBartosz Kaszubowski <PermalinkBase component={component} style={props.additionalProps?.style}> 96df72b035SBartosz Kaszubowski <LinkBase css={STYLES_PERMALINK_LINK} href={'#' + heading.slug} ref={heading.ref}> 97df72b035SBartosz Kaszubowski <span css={STYLES_PERMALINK_TARGET} id={heading.slug} /> 98929e0953SCedric van Putten <span css={STYLED_PERMALINK_CONTENT}>{children}</span> 99*46b58c59SKeith Kurak <span css={STYLES_PERMALINK_ICON}> 100*46b58c59SKeith Kurak <PermalinkIcon /> 101*46b58c59SKeith Kurak </span> 102cb5b8d03SBartosz Kaszubowski </LinkBase> 103929e0953SCedric van Putten </PermalinkBase> 104586106d6SBartłomiej Klocek ); 1051f61a071SBartosz Kaszubowski } 1061f61a071SBartosz Kaszubowski); 107929e0953SCedric van Putten 108929e0953SCedric van Puttenexport default Permalink; 109