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

chore(CodeBlock): refactor and add support for a white background #3245

Merged
merged 1 commit into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
}
}

.whiteBackgroundStyle {
:global {
.example-box {
background-color: var(--color-white);
}
}
}

.toolbarStyle {
position: absolute;
z-index: 100; // over generally used z-indexes, like table rows
Expand Down
69 changes: 40 additions & 29 deletions packages/dnb-design-system-portal/src/shared/tags/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

import React from 'react'
import classnames from 'classnames'
import Highlight, { Prism, defaultProps } from 'prism-react-renderer'
import Highlight, {
Language,
Prism,
defaultProps,
} from 'prism-react-renderer'
import Tag from './Tag'
import { Button } from '@dnb/eufemia/src/components'
import { makeUniqueId } from '@dnb/eufemia/src/shared/component-helper'
Expand All @@ -15,6 +19,7 @@ import {
liveCodeEditorStyle,
toolbarStyle,
codeBlockStyle,
whiteBackgroundStyle,
} from './CodeBlock.module.scss'
import {
LiveProvider,
Expand All @@ -27,18 +32,33 @@ import {
import prismTheme from '@dnb/eufemia/src/style/themes/theme-ui/prism/dnb-prism-theme'
import { ContextProps } from '@dnb/eufemia/src/shared/Context'

export type CodeBlockProps = {
scope?: Record<string, unknown>
noInline?: boolean
hideToolbar?: boolean
hideCode?: boolean
hidePreview?: boolean
reactLive?: boolean
language?: Language
className?: string
background?: 'grid' | 'white'
children: string | React.ReactNode | (() => React.ReactNode)
tabMode?: 'focus' | 'indentation'
'data-visual-test'?: string
}

const CodeBlock = ({
language,
children: exampleCode,
reactLive: isReactLive,
...props
}) => {
}: CodeBlockProps) => {
const context = React.useContext(Context)

if (!language) {
language =
(String(props && props.className).match(/language-(.*)$|\s/) ||
[])[1] || 'jsx'
language = ((String(props && props.className).match(
/language-(.*)$|\s/,
) || [])[1] || 'jsx') as Language
}

if (((props && props.scope) || isReactLive) && language === 'jsx') {
Expand All @@ -49,14 +69,14 @@ const CodeBlock = ({
createSkeletonClass('code', context.skeleton),
)}
>
<LiveCode code={exampleCode} {...props} />
<LiveCode code={exampleCode as string} {...props} />
</div>
)
} else {
return (
<Highlight
{...defaultProps}
code={String(exampleCode).trim()}
code={exampleCode as string}
language={language}
theme={prismTheme}
>
Expand Down Expand Up @@ -86,27 +106,12 @@ const CodeBlock = ({

export default CodeBlock

export type LiveCodeProps = {
type LiveCodeProps = {
code: string
scope?: Record<string, unknown>
useRender?: boolean
noFragments?: boolean
hideToolbar?: boolean
hideCode?: boolean
hidePreview?: boolean
language?: string
tabMode?: 'focus' | 'indentation'
'data-visual-test'?: string
}

type LiveCodeDefaultState = LiveCodeProps & {
language?: string
}
} & Omit<CodeBlockProps, 'children'>

class LiveCode extends React.PureComponent<
LiveCodeProps,
LiveCodeDefaultState
> {
class LiveCode extends React.PureComponent<LiveCodeProps, LiveCodeProps> {
static contextType = Context

context!: ContextProps
Expand Down Expand Up @@ -165,9 +170,10 @@ class LiveCode extends React.PureComponent<
render() {
const {
scope = {},
useRender,
noInline,
noFragments = true,
language = 'jsx',
background,

code: _code, // eslint-disable-line
hideToolbar: _hideToolbar, // eslint-disable-line
Expand All @@ -188,16 +194,21 @@ class LiveCode extends React.PureComponent<
}

return (
<div className={liveCodeEditorStyle}>
<div
className={classnames(
liveCodeEditorStyle,
background && whiteBackgroundStyle,
)}
>
<LiveProvider
theme={prismTheme}
code={codeToUse}
scope={scope}
language={language}
transformCode={(code: string) =>
!useRender && noFragments ? `<>${code}</>` : code
!noInline && noFragments ? `<>${code}</>` : code
}
noInline={useRender}
noInline={noInline}
{...props}
>
{!hidePreview && (
Expand Down
19 changes: 2 additions & 17 deletions packages/dnb-design-system-portal/src/shared/tags/ComponentBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import React from 'react'
import CodeBlock, { LiveCodeProps } from './CodeBlock'
import CodeBlock, { CodeBlockProps } from './CodeBlock'
import styled from '@emotion/styled'
import { getComponents } from '@dnb/eufemia/src/components/lib'
import { getFragments } from '@dnb/eufemia/src/fragments/lib'
Expand All @@ -16,29 +16,15 @@ if (!globalThis.ComponentBoxMemo) {
globalThis.ComponentBoxMemo = {}
}

type ComponentBoxProps = {
children: React.ReactNode | (() => React.ReactNode)
useRender?: boolean

/** @deprecated Use "useRender" instead */
noInline?: boolean
} & Omit<LiveCodeProps, 'code'>

function ComponentBox(props: ComponentBoxProps) {
function ComponentBox(props: CodeBlockProps) {
const { children, scope = {}, ...rest } = props

const hash = children as string
if (globalThis.ComponentBoxMemo[hash]) {
return globalThis.ComponentBoxMemo[hash]
}

if (rest.noInline) {
rest.useRender = true
}

return (globalThis.ComponentBoxMemo[hash] = (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
<CodeBlock
scope={{
...getComponents(),
Expand All @@ -50,7 +36,6 @@ function ComponentBox(props: ComponentBoxProps) {
Form,
styled,
React,
// TestWrapper,// Not used as of now
...scope,
}}
{...rest}
Expand Down
Loading