Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit af27be1

Browse files
Merge branch 'develop' into develop
2 parents ba5a157 + f8b039d commit af27be1

File tree

16 files changed

+279
-82
lines changed

16 files changed

+279
-82
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"deploy-storybook": "storybook-to-ghpages -- --out=.out",
4040
"now-build-storybook": "build-storybook -o dist/storybook",
4141
"docs:dev": "yarn docs-dev",
42+
"docs:lint": "yarn workspace chakra-ui-docs lint",
4243
"theme:dev": "yarn workspace @chakra-ui/theme-vue build",
4344
"docs-dev": "yarn workspace chakra-ui-docs dev",
4445
"evalbundle": "bundlesize"

packages/chakra-ui-core/src/utils/playground.stories.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint import/namespace: [2, { allowComputed: true }] */
22
import { storiesOf } from '@storybook/vue'
33
import Vue from 'vue'
4-
import CodeBlock from '../../../../website/components/CodeBlock.js'
4+
import { MDXCodeBlock } from '../../../../website/components/code'
55
import * as ChakraComponents from '..'
66

77
Object.keys(ChakraComponents).forEach((key) => {
@@ -18,7 +18,9 @@ Object.keys(ChakraComponents).forEach((key) => {
1818

1919
storiesOf('Playground', module)
2020
.add('New', () => ({
21-
components: { CodeBlock: CodeBlock({ live: true, lang: 'vue', className: 'lang-vue' }) },
21+
components: {
22+
CodeBlock: MDXCodeBlock({ live: true, lang: 'vue', className: 'lang-vue' })
23+
},
2224
template: `
2325
<c-box max-w="500px" h="100vh" mt="200px">
2426
<h2 v-chakra font-weight="bold" font-size="xl">Chakra UI Vue Playground ⚡️</h2>

website/components/MDXComponents.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { css } from 'emotion'
22
import { CHeading, CBox, Css, CPseudoBox, CCode, CText } from '@chakra-ui/vue'
3-
import CodeBlock from './CodeBlock'
3+
import { MDXCodeBlock } from './code'
44
import { stringToUrl } from '~/utils'
55
import pages from '~/utils/all-routes'
66

@@ -115,8 +115,7 @@ const MDXComponents = {
115115
)
116116
}
117117
}),
118-
// eslint-disable-next-line
119-
'code': CodeBlock,
118+
code: MDXCodeBlock,
120119
pre: props => ({
121120
name: 'Box',
122121
render () {

website/components/CodeBlock.js renamed to website/components/code/code-block.vue

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1+
<script>
12
import 'prismjs'
23
import PrismEditor from 'vue-prism-editor'
3-
import '../css/night-owl.css'
44
import 'vue-prism-editor/dist/VuePrismEditor.css'
5-
import copy from 'copy-to-clipboard'
6-
import LiveEditor from './LiveEditor'
5+
import '../../css/night-owl.css'
76
8-
function getLanguage (string) {
9-
return string.slice(string.indexOf('-') + 1)
10-
}
7+
import LiveEditor from './live-editor/live-editor.vue'
8+
import { getLanguage } from './utils'
9+
import { CopyTextMixin } from './mixins'
1110
12-
const CodeBlock = props => ({
11+
export default {
1312
name: 'CodeBlock',
13+
mixins: [CopyTextMixin],
1414
props: {
1515
lang: {
1616
type: String,
@@ -31,36 +31,14 @@ const CodeBlock = props => ({
3131
autoStyleLineNumbers: {
3232
type: Boolean,
3333
default: true
34-
},
35-
live: Boolean
36-
},
37-
data () {
38-
return {
39-
text: undefined,
40-
copyTimeout: null,
41-
copyButtonText: 'Copy'
42-
}
43-
},
44-
methods: {
45-
async copy () {
46-
// Copy text to clipboard
47-
await copy(this.text)
48-
49-
// Handle timeouts for copy button text
50-
if (this.copyTimeout) { clearTimeout(this.copyTimeout) }
51-
this.copyButtonText = 'Copied!'
52-
this.copyTimeout = setTimeout(() => {
53-
this.copyButtonText = 'Copy'
54-
clearTimeout(this.copyTimeout)
55-
}, 1000)
5634
}
5735
},
5836
render (h) {
59-
const language = getLanguage(props.className)
37+
const language = getLanguage(this.lang)
6038
const code = this.$slots.default[0].text
6139
this.text = code
6240
63-
if (!props.live) {
41+
if (this.isReadOnly) {
6442
return h('CBox', {
6543
attrs: {
6644
rounded: 'md',
@@ -95,18 +73,15 @@ const CodeBlock = props => ({
9573
])
9674
} else {
9775
const liveEditor = h(LiveEditor, {
98-
props: {
99-
code
100-
}
76+
props: { code }
10177
})
10278
103-
if (props.browser) {
79+
if (process.browser) {
10480
return h('client-only', [liveEditor])
10581
} else {
10682
return liveEditor
10783
}
10884
}
10985
}
110-
})
111-
112-
export default CodeBlock
86+
}
87+
</script>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<script>
2+
import {
3+
CTab,
4+
CTabs,
5+
CTabList,
6+
CTabPanel,
7+
CTabPanels
8+
} from '@chakra-ui/vue'
9+
import CodeBlock from '../code-block.vue'
10+
import { tryParseBoolean } from '../utils'
11+
12+
export default {
13+
name: 'CodeGroup',
14+
props: {
15+
lang: {
16+
type: String,
17+
required: false,
18+
default: ''
19+
},
20+
live: {
21+
type: Boolean,
22+
required: false,
23+
default: false
24+
}
25+
},
26+
render (h) {
27+
const getPanelCode = (vnode) => {
28+
// traverse until we reach the *Text* node
29+
let lastVNode = null
30+
let node = vnode
31+
while (node?.componentOptions?.children) {
32+
lastVNode = node
33+
node = node?.componentOptions?.children[0]
34+
}
35+
36+
if (!lastVNode?.tag.includes(CodeBlock.name)) {
37+
// node is not a CodeBlock component, reset this
38+
lastVNode = null
39+
}
40+
41+
return { code: node?.text, codeBlock: lastVNode }
42+
}
43+
44+
const tabs = this.$scopedSlots.default()
45+
const tabLabels = tabs.map(vnode => h(CTab, { attrs: { py: 2 } }, [vnode.componentOptions.propsData.label]))
46+
const tabPanels = tabs.map((vnode) => {
47+
const { code, codeBlock } = getPanelCode(vnode)
48+
49+
const lang = vnode.componentOptions?.propsData.lang || this.lang
50+
const live = tryParseBoolean(vnode.componentOptions?.propsData.live) ?? this.live
51+
52+
if (codeBlock) {
53+
const codeBlockLangProp = codeBlock.data?.className || codeBlock?.data?.lang
54+
const codeBlockLiveProp = tryParseBoolean(codeBlock.data?.live)
55+
56+
// merge component and mdx options, predefined mdx codeblock values take precedence
57+
codeBlock.componentOptions.propsData.lang = codeBlockLangProp || lang
58+
codeBlock.componentOptions.propsData.isReadOnly = !(codeBlockLiveProp ?? live)
59+
return h(CTabPanel, [codeBlock])
60+
}
61+
62+
return h(CTabPanel, [h(CodeBlock, { props: { lang, isReadOnly: !live } }, [code])])
63+
})
64+
65+
return h(CTabs, {
66+
props: { size: 'sm', variantColor: 'vue' },
67+
attrs: { rounded: 'md', bg: '#011627', color: 'white' }
68+
}, [
69+
h(CTabList, { attrs: { borderColor: 'vue.800' } }, tabLabels),
70+
h(CTabPanels, tabPanels)
71+
])
72+
}
73+
}
74+
</script>
75+
76+
<style lang="scss" scoped>
77+
::v-deep [role="tab"][aria-selected] {
78+
color: #3caa79 !important; // vue.500
79+
}
80+
</style>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script>
2+
export default {
3+
name: 'CodeTab',
4+
props: {
5+
label: {
6+
type: String,
7+
required: true
8+
},
9+
lang: {
10+
type: String,
11+
required: false,
12+
default: null
13+
},
14+
live: {
15+
type: Boolean,
16+
required: false,
17+
default: false
18+
}
19+
}
20+
}
21+
</script>

website/components/code/index.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import CodeBlock from './code-block.vue'
2+
import LiveEditor from './live-editor/live-editor.vue'
3+
import CodeGroup from './code-group/code-group.vue'
4+
import CodeTab from './code-group/code-tab.vue'
5+
import { CopyTextMixin } from './mixins'
6+
7+
const MDXCodeBlock = (props) => {
8+
const isReadOnly = !props.live
9+
const lang = props.className || props.lang || 'vue'
10+
11+
return {
12+
name: 'CodeBlock',
13+
extend: CodeBlock,
14+
mixins: [CopyTextMixin],
15+
props: {
16+
...CodeBlock.props,
17+
isReadOnly: {
18+
type: Boolean,
19+
default: isReadOnly
20+
},
21+
lang: {
22+
type: String,
23+
default: lang
24+
}
25+
},
26+
render: CodeBlock.render
27+
}
28+
}
29+
30+
export {
31+
CodeBlock,
32+
CodeGroup,
33+
CodeTab,
34+
LiveEditor,
35+
MDXCodeBlock
36+
}

website/components/LiveEditor.js renamed to website/components/code/live-editor/live-editor.vue

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
<script>
12
import copy from 'copy-to-clipboard'
23
import Layout from './live-editor-layout.vue'
34
4-
const LiveEditor = {
5+
export default {
56
name: 'LiveEditor',
67
props: {
7-
code: String
8+
code: {
9+
type: String,
10+
default: null
11+
}
812
},
913
data () {
1014
return {
@@ -15,6 +19,13 @@ const LiveEditor = {
1519
codeText: undefined
1620
}
1721
},
22+
watch: {
23+
codeText (newVal, oldVal) {
24+
if (this.error && (newVal !== oldVal)) {
25+
this.error = null
26+
}
27+
}
28+
},
1829
async mounted () {
1930
await this.$nextTick()
2031
this.copyButton = this.$el.querySelector('[chakra-copy-button]')
@@ -35,13 +46,6 @@ const LiveEditor = {
3546
})
3647
}
3748
},
38-
watch: {
39-
codeText (newVal, oldVal) {
40-
if (this.error && (newVal !== oldVal)) {
41-
this.error = null
42-
}
43-
}
44-
},
4549
methods: {
4650
async copy () {
4751
// Copy text to clipboard
@@ -83,5 +87,4 @@ const LiveEditor = {
8387
])
8488
}
8589
}
86-
87-
export default LiveEditor
90+
</script>

website/components/code/mixins.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import copy from 'copy-to-clipboard'
2+
3+
export const CopyTextMixin = {
4+
data () {
5+
return {
6+
text: undefined,
7+
copyTimeout: null,
8+
copyButtonText: 'Copy'
9+
}
10+
},
11+
methods: {
12+
async copy () {
13+
// Copy text to clipboard
14+
await copy(this.text)
15+
16+
// Handle timeouts for copy button text
17+
this.copyTimeout && clearTimeout(this.copyTimeout)
18+
19+
this.copyButtonText = 'Copied!'
20+
this.copyTimeout = setTimeout(() => {
21+
this.copyButtonText = 'Copy'
22+
clearTimeout(this.copyTimeout)
23+
}, 1000)
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)