Skip to content

Commit

Permalink
fix: sending in a true React Component with a title, did not work pro…
Browse files Browse the repository at this point in the history
…perly on #tabs
  • Loading branch information
tujoworker committed Jan 23, 2019
1 parent 058ba07 commit e7732c3
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 44 deletions.
134 changes: 111 additions & 23 deletions packages/dnb-design-system-portal/src/shared/inlineTags/CodeBlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
*
*/

import React from 'react'
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { css } from '@emotion/core'
import styled from '@emotion/styled'
import Highlight, { defaultProps } from 'prism-react-renderer'
import dnbTheme from './themes/dnb-prism-theme'
import { Button } from 'dnb-ui-lib/src'
import {
LiveProvider,
LiveEditor,
Expand All @@ -30,28 +33,7 @@ const CodeBlock = ({
}

if (((props && props.scope) || isReactLive) && language === 'jsx') {
const { caption, hideCode, hideExample, ...restProps } = props
return (
<LiveProvider
mountStylesheet={false}
css={prismStyle}
code={
typeof exampleCode === 'string'
? String(exampleCode).trim()
: null
}
{...restProps}
>
{!hideExample && (
<div className="example-box">
<LivePreview />
</div>
)}
{caption && <p className="example-caption">{caption}</p>}
{!hideCode && <LiveEditor language="jsx" />}
{!hideCode && <LiveError />}
</LiveProvider>
)
return <LiveCode code={exampleCode} {...props} />
} else {
return (
<Highlight
Expand Down Expand Up @@ -81,6 +63,112 @@ const CodeBlock = ({

export default CodeBlock

class LiveCode extends PureComponent {
static propTypes = {
code: PropTypes.string.isRequired,
scope: PropTypes.object.isRequired,
hideCode: PropTypes.bool,
hidePreview: PropTypes.bool,
caption: PropTypes.string
}
static defaultProps = {
caption: null,
hideCode: false,
hidePreview: false
}

constructor(props) {
super(props)
const { hideCode, hidePreview } = props
this.state = { hideCode, hidePreview }
}

toggleCode = () => {
this.setState(() => ({ hideCode: !this.state.hideCode }))
}
togglePreview = () => {
this.setState(() => ({ hidePreview: !this.state.hidePreview }))
}

render() {
const { code, caption, scope } = this.props
const { hideCode, hidePreview } = this.state

return (
<LiveCodeEditor>
<LiveProvider
mountStylesheet={false}
css={prismStyle}
code={typeof code === 'string' ? String(code).trim() : null}
scope={scope}
// onError={e => {
// console.log('error', e)
// }}
>
{!hidePreview && (
<>
<div className="example-box">
{this.props.hideCode && (
<Button
className="toggle-button"
on_click={this.toggleCode}
variant="secondary"
text="Code"
title="Toggle Code Snippet"
icon={`chevron-${hideCode ? 'down' : 'up'}`}
size="medium"
/>
)}
<LivePreview />
{caption && <p className="example-caption">{caption}</p>}
</div>
</>
)}
<Toolbar>
{!hideCode && (
<LiveError className="dnb-form-status dnb-form-status--text dnb-form-status--error" />
)}
{hidePreview && (
<Button
className="toggle-button"
on_click={this.togglePreview}
variant="secondary"
text="Preview"
title="Toggle Preview"
icon={`chevron-${!hidePreview ? 'down' : 'up'}`}
size="medium"
/>
)}
</Toolbar>
{!hideCode && <LiveEditor language="jsx" />}
</LiveProvider>
</LiveCodeEditor>
)
}
}

const LiveCodeEditor = styled.div`
position: relative;
p.example-caption {
margin-bottom: -1rem;
}
`

const Toolbar = styled.div`
position: absolute;
bottom: 0;
left: 0;
width: 100%;
display: flex;
flex-direction: row;
align-items: space-between;
justify-content: flex-end;
padding: 0 1rem 1rem;
`

/** Removes the last token from a code example if it's empty. */
const cleanTokens = tokens => {
const tokensLength = tokens.length
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getComponents } from 'dnb-ui-lib/src/components'

const ComponentBox = ({ children, ...rest }) => {
return (
<CodeBlock scope={getComponents()} {...rest}>
<CodeBlock scope={getComponents()} hidePreview {...rest}>
{children}
</CodeBlock>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'

import { css } from '@emotion/core'
// import styled from '@emotion/styled'
import { navigate, parsePath } from 'gatsby'
import { CloseButton } from 'dnb-ui-lib/src/components/modal'
import { fullscreen as fullscreenIcon } from 'dnb-ui-lib/src/icons/secondary_icons'
Expand All @@ -27,10 +26,6 @@ const getLocation = () => {
}
}

// const DemoWrapper = styled.div`
// padding: 2rem 0 0;
// `

const tabsWrapperStyle = css`
.fullscreen-page & {
top: 0;
Expand Down Expand Up @@ -101,7 +96,6 @@ class CustomTabs extends PureComponent {

return (
<Tabs
// id={this._id}
use_hash
data={data}
on_change={this.openTab}
Expand Down
25 changes: 14 additions & 11 deletions packages/dnb-ui-lib/src/components/tabs/Tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,21 @@ export default class Tabs extends PureComponent {
(content.type.name || content.type.displayName) ===
'CustomContent'
) {
const { title, key: _key, hash, ...rest } = {
// props from the "CustomContent" Component
...content.props,

// tabs data from main prop
...((props.tabs &&
Array.isArray(props.tabs) &&
props.tabs[i]) ||
{}),
// tabs data from main prop
const dataProps =
(props.tabs && Array.isArray(props.tabs) && props.tabs[i]) ||
{}

// props from the "CustomContent" Component
const componentProps = { ...content.props }
if (componentProps.title === null) {
delete componentProps.title
}

// remove children, if there is some
...{ children: null }
const { title, key: _key, hash, ...rest } = {
...dataProps,
...componentProps,
...{ children: null } // remove children, if there is some
}

acc.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,18 @@ describe('A single Tab component', () => {

it('has to work with "Tabs.Content" as children Components', () => {
const Comp = mount(
<Component>
<Component.Content title="first">first</Component.Content>
<Component.Content title="second" selected>
<Component data={tablistData}>
<Component.Content title="first title">first</Component.Content>
<Component.Content title="second title" selected>
second
</Component.Content>
</Component>
)
expect(Comp.find('button.selected').exists()).toBe(true)
expect(Comp.find('div.dnb-tabs__content').text()).toBe('second')
expect(
Comp.find('button[aria-selected=true] span.dnb-tablink-title').text()
).toBe('second title')
})
})

Expand Down

0 comments on commit e7732c3

Please sign in to comment.