mirror of https://github.com/sgoudham/carbon.git
embeds
expose CodeMirrorLink, load only necessary theme in embed implement copy button in Carbon window controls add copy to queryParam use next/head and metatags in /embed make editor have router prop fix now.json rewrites allow local stylesheets in embedmain
parent
1d85149a97
commit
c0ff116de8
@ -0,0 +1,36 @@
|
||||
// TODO publish rucksack and import from there
|
||||
|
||||
import React from 'react'
|
||||
import CopyToClipboard from 'react-copy-to-clipboard'
|
||||
|
||||
class CopyButton extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
copied: false
|
||||
}
|
||||
this.onCopy = this.onCopy.bind(this)
|
||||
}
|
||||
|
||||
onCopy() {
|
||||
this.setState({ copied: true })
|
||||
const component = this
|
||||
setTimeout(
|
||||
() => component.setState({ copied: false }),
|
||||
this.props.interval == null ? 1000 : this.props.interval
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<CopyToClipboard text={this.props.text} onCopy={this.onCopy}>
|
||||
{this.props.children({
|
||||
copied: this.state.copied
|
||||
})}
|
||||
</CopyToClipboard>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default CopyButton
|
@ -0,0 +1,46 @@
|
||||
import React from 'react'
|
||||
import { withRouter } from 'next/router'
|
||||
|
||||
import CopyButton from './CopyButton'
|
||||
|
||||
const toIFrame = url =>
|
||||
`<iframe
|
||||
src="https://carbon.now.sh/embed${url}"
|
||||
style="transform:scale(0.7); width:1024px; height:473px; border:0; overflow:hidden;"
|
||||
sandbox="allow-scripts allow-same-origin">
|
||||
</iframe>
|
||||
`
|
||||
|
||||
function ExportButton({ router, children, color }) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{children === 'COPY EMBED' ? (
|
||||
<CopyButton text={toIFrame(router.asPath)}>
|
||||
{({ copied }) => <button>{copied ? 'COPIED!' : 'EMBED CODE'}</button>}
|
||||
</CopyButton>
|
||||
) : (
|
||||
<button>{children}</button>
|
||||
)}
|
||||
<style jsx>
|
||||
{`
|
||||
button {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
color: ${color};
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active {
|
||||
outline: none;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default withRouter(ExportButton)
|
@ -0,0 +1,29 @@
|
||||
import React from 'react'
|
||||
|
||||
const SVG_RATIO = 0.81
|
||||
|
||||
const Copy = ({ size, color }) => {
|
||||
const width = size * SVG_RATIO
|
||||
const height = size
|
||||
|
||||
return (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 13 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8 0H3.40385C2.55385 0 1.84615 0.669231 1.84615 1.51923V1.84615H1.55769C0.707692 1.84615 0 2.51538 0 3.36538V14.4423C0 15.2923 0.707692 16 1.55769 16H9.55769C10.4077 16 11.0769 15.2923 11.0769 14.4423V14.1538H11.4038C12.2538 14.1538 12.9231 13.4462 12.9231 12.5962V4.92308L8 0ZM8 1.71538L11.2077 4.92308H8V1.71538ZM9.84615 14.4423C9.84615 14.6231 9.71538 14.7692 9.55769 14.7692H1.55769C1.38846 14.7692 1.23077 14.6115 1.23077 14.4423V3.36538C1.23077 3.20769 1.37692 3.07692 1.55769 3.07692H1.84615V12.9038C1.84615 13.7538 2.24615 14.1538 3.09615 14.1538H9.84615V14.4423ZM11.6923 12.5962C11.6923 12.7769 11.5615 12.9231 11.4038 12.9231H3.40385C3.23462 12.9231 3.07692 12.7654 3.07692 12.5962V1.51923C3.07692 1.36154 3.22308 1.23077 3.40385 1.23077H6.76923V6.15385H11.6923V12.5962Z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
Copy.defaultProps = {
|
||||
size: 16
|
||||
}
|
||||
|
||||
export default Copy
|
@ -0,0 +1,71 @@
|
||||
// Theirs
|
||||
import React from 'react'
|
||||
import Head from 'next/head'
|
||||
import { withRouter } from 'next/router'
|
||||
import url from 'url'
|
||||
|
||||
// Ours
|
||||
import { LOCAL_STYLESHEETS, CodeMirrorLink, MetaTags } from '../components/Meta'
|
||||
import Carbon from '../components/Carbon'
|
||||
import { DEFAULT_CODE, DEFAULT_SETTINGS } from '../lib/constants'
|
||||
|
||||
import { getQueryStringState } from '../lib/routing'
|
||||
|
||||
const Page = props => (
|
||||
<div>
|
||||
<Head>
|
||||
<MetaTags />
|
||||
{LOCAL_STYLESHEETS.indexOf(props.theme) > -1 ? (
|
||||
<link rel="stylesheet" href={`/static/themes/${props.theme}.css`} />
|
||||
) : (
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href={`//cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.2/theme/${props.theme}.min.css`}
|
||||
/>
|
||||
)}
|
||||
<CodeMirrorLink />
|
||||
</Head>
|
||||
{props.children}
|
||||
<style jsx global>
|
||||
{`
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
min-height: 0;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
</div>
|
||||
)
|
||||
|
||||
class Embed extends React.Component {
|
||||
state = {
|
||||
...DEFAULT_SETTINGS,
|
||||
code: DEFAULT_CODE,
|
||||
mounted: false
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { asPath = '' } = this.props.router
|
||||
const { query } = url.parse(asPath, true)
|
||||
const queryParams = getQueryStringState(query)
|
||||
const initialState = Object.keys(queryParams).length ? queryParams : {}
|
||||
|
||||
this.setState({ ...initialState, copyable: queryParams.copy !== false, mounted: true })
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Page theme={this.state.theme}>
|
||||
{this.state.mounted && (
|
||||
<Carbon config={this.state} copyable={this.state.copyable}>
|
||||
{this.state.code}
|
||||
</Carbon>
|
||||
)}
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(Embed)
|
Loading…
Reference in New Issue