Skip to content

Commit

Permalink
docs: support copying token (#97)
Browse files Browse the repository at this point in the history
Co-authored-by: Jiachi Liu <[email protected]>
  • Loading branch information
TinsFox and huozhi authored May 3, 2024
1 parent 17ffebe commit 14df889
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 36 deletions.
7 changes: 7 additions & 0 deletions docs/app/components/copy-button.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.copy-button{
background-color:transparent;
border:none;
cursor:pointer;
padding:0;
border-radius:0;
}
5 changes: 4 additions & 1 deletion docs/app/components/copy-button.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import "./copy-button.css"

export function CopyButton({ codeSnippet, ...props }) {
return (
<button
{...props}
onClick={() => {
navigator.clipboard.writeText(codeSnippet)
}}
className="copy-button"
>
Copy Code
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="lucide lucide-copy"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
</button>
)
}
79 changes: 48 additions & 31 deletions docs/app/live-editor.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use client'

import { useState, useEffect, useRef } from 'react'
import { useState, useEffect, useRef, useMemo } from 'react'
import { highlight, tokenize, SugarHigh } from 'sugar-high'
import { Editor } from 'codice'
import { CopyButton } from './components/copy-button'

const defaultColorPlateColors = {
class: '#8d85ff',
Expand All @@ -18,7 +19,7 @@ const defaultColorPlateColors = {
space: '#ffffff',
}

function debounce(func, timeout = 200){
function debounce(func, timeout = 200) {
let timer
return (...args) => {
clearTimeout(timer)
Expand Down Expand Up @@ -48,12 +49,11 @@ export default function App() {
`

function useTextTypingAnimation(targetText, delay, onReady) {

const [text, setText] = useState('')
const [isTyping, setIsTyping] = useState(true)
const animationDuration = delay / targetText.length
let timeoutId = useRef(null)

useEffect(() => {
if (isTyping && targetText.length) {
if (text.length < targetText.length) {
Expand All @@ -65,7 +65,6 @@ function useTextTypingAnimation(targetText, delay, onReady) {
timeoutId.current = setTimeout(() => {
setText(nextText)
}, animationDuration)

} else if (text.length === targetText.length) {
setIsTyping(false)
onReady()
Expand All @@ -89,13 +88,10 @@ function useDefaultLiveCode() {
useEffect(() => {
if (defaultCode) return

setCode(
window.localStorage.getItem(DEFAULT_LIVE_CODE_KEY) || DEFAULT_LIVE_CODE
)
setCode(window.localStorage.getItem(DEFAULT_LIVE_CODE_KEY) || DEFAULT_LIVE_CODE)
}, [defaultCode])

const setDefaultLiveCode = (code) =>
window.localStorage.setItem(DEFAULT_LIVE_CODE_KEY, code)
const setDefaultLiveCode = (code) => window.localStorage.setItem(DEFAULT_LIVE_CODE_KEY, code)

return {
defaultLiveCode: defaultCode,
Expand All @@ -109,7 +105,11 @@ export default function LiveEditor() {
const isDebug = process.env.NODE_ENV === 'development'

const { defaultLiveCode, setDefaultLiveCode } = useDefaultLiveCode()
const { text: liveCode, setText: setLiveCode, isTyping } = useTextTypingAnimation(defaultLiveCode, 1000, () => {
const {
text: liveCode,
setText: setLiveCode,
isTyping,
} = useTextTypingAnimation(defaultLiveCode, 1000, () => {
if (editorRef.current) {
// focus needs to be delayed
setTimeout(() => {
Expand All @@ -118,14 +118,23 @@ export default function LiveEditor() {
}
})


const [liveCodeTokens, setLiveCodeTokens] = useState([])
const debouncedTokenizeRef = useRef(debounce((c) => {
const tokens = tokenize(c)
setLiveCodeTokens(tokens)
}))
const debouncedTokenizeRef = useRef(
debounce((c) => {
const tokens = tokenize(c)
setLiveCodeTokens(tokens)
})
)
const debouncedTokenize = debouncedTokenizeRef.current

const customizableColorsString = useMemo(() => {
return customizableColors
.map(([tokenType, tokenTypeName]) => {
return `--sh-${tokenTypeName}: ${colorPlateColors[tokenTypeName]};`
})
.join('\n')
}, [colorPlateColors])

return (
<div className={`max-width-container live-editor-section`}>
<style>{`
Expand All @@ -141,13 +150,12 @@ export default function LiveEditor() {
--sh-comment: ${colorPlateColors.comment};
--sh-jsxliterals: ${colorPlateColors.jsxliterals};
}
`}`
}</style>
`}`}</style>

<div className='flex live-editor'>
<div className="flex live-editor">
<Editor
ref={editorRef}
className='codice-editor flex-1'
className="codice-editor flex-1"
highlight={highlight}
value={liveCode}
onChange={(newCode) => {
Expand All @@ -157,18 +165,24 @@ export default function LiveEditor() {
}}
/>

<ul className='live-editor__color'>
<h3>Color palette</h3>
<ul className="live-editor__color">
<h3>
Color palette <CopyButton codeSnippet={customizableColorsString} />
</h3>
{customizableColors.map(([tokenType, tokenTypeName]) => {
const inputId = `live-editor-color__input--${tokenTypeName}`
return (
<li key={tokenType} className='live-editor__color__item'>
<label htmlFor={inputId} className='flex align-center'>
<span className={`live-editor__color__item__indicator live-editor__color__item__indicator--${tokenTypeName}`} style={{ color: colorPlateColors[tokenTypeName] }} />
<li key={tokenType} className="live-editor__color__item">
<label htmlFor={inputId} className="flex align-center">
<span
className={`live-editor__color__item__indicator live-editor__color__item__indicator--${tokenTypeName}`}
style={{ color: colorPlateColors[tokenTypeName] }}
/>
{tokenTypeName}
</label>

<input
type='color'
type="color"
defaultValue={colorPlateColors[tokenTypeName]}
id={inputId}
onChange={(e) => {
Expand All @@ -178,24 +192,27 @@ export default function LiveEditor() {
})
}}
/>
<span>{colorPlateColors[tokenTypeName]}</span>
</li>
)
})}
</ul>
</div>
{isDebug &&
<div className='editor-tokens'>
{isDebug && (
<div className="editor-tokens">
<pre>
{liveCodeTokens.map(([tokenType, token], index) => {
const tokenTypeName = SugarHigh.TokenTypes[tokenType]
return (
<div key={index}>{tokenTypeName}{' '.repeat(12 - tokenTypeName.length)} {token}</div>
<div key={index}>
{tokenTypeName}
{' '.repeat(12 - tokenTypeName.length)} {token}
</div>
)
})}
</pre>
</div>
}
)}
</div>
)
}

19 changes: 15 additions & 4 deletions docs/app/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
}

html {
font-family: "Inter",-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
}
body {
margin: 0;
Expand All @@ -27,7 +29,7 @@ body {
padding: 0 10px 40px;
margin: auto;
}
input[type=radio] {
input[type="radio"] {
display: none;
}
.flex {
Expand Down Expand Up @@ -194,7 +196,6 @@ code {
width: 100%;
}


pre code .sh__line::before {
counter-increment: sh-line-number 1;
content: counter(sh-line-number);
Expand Down Expand Up @@ -231,8 +232,11 @@ pre code .sh__line::before {
margin: 24px 0;
padding: 0 24px;
}

.live-editor__color h3 {
margin: 0 0 24px;
display: flex;
gap: 8px;
}
.live-editor__color input[type="color"] {
display: inline;
Expand All @@ -249,7 +253,14 @@ pre code .sh__line::before {
align-items: center;
color: #666;
margin: 4px 0;
}

.live-editor__color__item .copy-button {
visibility: hidden;
}

.live-editor__color__item:hover .copy-button {
visibility: visible;
}
.live-editor__color__item:hover,
.live-editor__color__item:hover label {
Expand Down Expand Up @@ -285,4 +296,4 @@ pre code .sh__line::before {
.live-editor__color {
display: none;
}
}
}

0 comments on commit 14df889

Please sign in to comment.