Skip to content
This repository has been archived by the owner on Jan 2, 2025. It is now read-only.

Commit

Permalink
Link click behavior and colors
Browse files Browse the repository at this point in the history
  • Loading branch information
ericvicenti committed Oct 17, 2023
1 parent a555c2a commit c8205f5
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 62 deletions.
8 changes: 8 additions & 0 deletions frontend/packages/app/pages/publication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import {VersionChangesInfo} from '../components/version-changes-info'
import {usePublicationInContext} from '../models/publication'
import {DocumentPlaceholder} from './document-placeholder'
import {useOpenUrl} from '../open-url'

export default function PublicationPage() {
const route = useNavRoute()
Expand Down Expand Up @@ -55,6 +56,8 @@ export default function PublicationPage() {
publication.status == 'success' ? docId : undefined,
)

const openUrl = useOpenUrl()

if (publication.data) {
return (
<ErrorBoundary
Expand Down Expand Up @@ -88,6 +91,11 @@ export default function PublicationPage() {
StaticGroup: StaticBlockGroup,
StaticPublication: StaticBlockPublication,
}}
onLinkClick={(href, e) => {
e.preventDefault()
e.stopPropagation()
openUrl(href)
}}
>
<StaticPublication publication={publication.data} />
</StaticPublicationProvider>
Expand Down
129 changes: 67 additions & 62 deletions frontend/packages/shared/src/static/static-renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,35 @@ let blockVerticalPadding: FontSizeTokens = '$4'
let blockHorizontalPadding: FontSizeTokens = '$4'
let blockBorderRadius = '$3'

export type StaticPublicationContextValue = EntityComponentsRecord | null

export const staticPublicationContext =
createContext<StaticPublicationContextValue>(null)

export type StaticEmbedProps = StaticBlockProps & ReturnType<typeof unpackHmId>
export type EntityComponentsRecord = {
StaticAccount: React.FC<StaticEmbedProps>
StaticGroup: React.FC<StaticEmbedProps>
StaticPublication: React.FC<StaticEmbedProps>
}

export type StaticPublicationContextValue = {
entityComponents: EntityComponentsRecord
onLinkClick: (dest: string, e: any) => void
}

export const staticPublicationContext =
createContext<StaticPublicationContextValue | null>(null)

export type StaticEmbedProps = StaticBlockProps & ReturnType<typeof unpackHmId>

export function StaticPublicationProvider({
children,
entityComponents = null,
}: PropsWithChildren<{entityComponents: StaticPublicationContextValue}>) {
entityComponents,
onLinkClick,
}: PropsWithChildren<StaticPublicationContextValue>) {
return (
<staticPublicationContext.Provider value={entityComponents}>
<staticPublicationContext.Provider value={{entityComponents, onLinkClick}}>
{children}
</staticPublicationContext.Provider>
)
}

export function useStaticPublication() {
export function useStaticPublicationContext() {
let context = useContext(staticPublicationContext)

if (!context) {
Expand Down Expand Up @@ -510,13 +515,24 @@ function StaticBlockVideo({block, depth}: StaticBlockProps) {
)
}

type LinkType = null | 'basic' | 'hypermedia'

function hmTextColor(linkType: LinkType): string {
if (linkType === 'basic') return '$blue11'
if (linkType === 'hypermedia') return '$mint11'
return '$color12'
}

function InlineContentView({
inline,
style,
linkType = null,
...props
}: SizableTextProps & {
inline: HMInlineContent[]
linkType?: LinkType
}) {
const {onLinkClick} = useStaticPublicationContext()
return (
<span>
{inline.map((content, index) => {
Expand All @@ -527,7 +543,8 @@ function InlineContentView({
| 'underline'
| 'underline line-through'
| undefined
if (content.styles.underline) {
const underline = linkType || content.styles.underline
if (underline) {
if (content.styles.strike) {
textDecorationLine = 'underline line-through'
} else {
Expand Down Expand Up @@ -559,71 +576,59 @@ function InlineContentView({
)
}

if (content.styles.backgroundColor) {
children = (
<span style={{backgroundColor: content.styles.backgroundColor}}>
{children}
</span>
)
}
// does anything use this?
// if (content.styles.backgroundColor) {
// children = (
// <span style={{backgroundColor: content.styles.backgroundColor}}>
// {children}
// </span>
// )
// }

if (content.styles.strike) {
children = <s>{children}</s>
}

if (content.styles.textColor) {
children = (
<span style={{color: content.styles.textColor}}>{children}</span>
)
}
// does anything use this?
// if (content.styles.textColor) {
// children = (
// <span style={{color: content.styles.textColor}}>{children}</span>
// )
// }

return (
<span key={index} style={{textDecorationLine}}>
<Text
key={index}
color={hmTextColor(linkType)}
textDecorationColor={hmTextColor(linkType)}
style={{textDecorationLine}}
>
{children}
</span>
</Text>
)
}
if (content.type === 'link') {
const href = isHypermediaScheme(content.href)
? idToUrl(content.href, null)
: content.href

const isExternal = isHypermediaScheme(content.href)
if (!href) return null
const isHmLink = isHypermediaScheme(content.href)
return (
href && ( // <Tooltip content={href}>
// <SizableText
// key={index}
// display="inline"
// {...props}
// {...inlineContentProps}
// >
// <a
// href={href}
// key={index}
// className={isExternal ? 'hm-link' : 'link'}
// style={{
// cursor: 'pointer',
// display: 'inline',
// }}
// >
// <InlineContentView inline={content.content} />
// {isExternal ? <ExternalLink size={10} /> : null}
// </a>
// </SizableText>
// </Tooltip>
<a
href={href}
key={index}
className={isExternal ? 'hm-link' : 'link'}
style={{
cursor: 'pointer',
display: 'inline',
}}
>
<InlineContentView inline={content.content} />
{isExternal ? <ExternalLink size={10} /> : null}
</a>
)
<a
href={href}
key={index}
onClick={(e) => onLinkClick(content.href, e)}
style={{
cursor: 'pointer',
display: 'inline',
textDecoration: 'none',
}}
>
<InlineContentView
inline={content.content}
linkType={isHmLink ? 'hypermedia' : 'basic'}
/>
</a>
)
}
return null
Expand All @@ -638,7 +643,7 @@ function stripHMLinkPrefix(link: string) {

export function StaticBlockEmbed(props: StaticBlockProps & {blockRef: string}) {
console.log('EMBED HERE', props)
const EmbedTypes = useStaticPublication()
const EmbedTypes = useStaticPublicationContext().entityComponents
const id = unpackHmId(props.blockRef)

if (id?.type == 'a') {
Expand Down

0 comments on commit c8205f5

Please sign in to comment.