Skip to content

Commit

Permalink
feat: add todo and color page
Browse files Browse the repository at this point in the history
  • Loading branch information
shu committed Dec 21, 2021
1 parent 9678047 commit dbe25de
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 34 deletions.
1 change: 0 additions & 1 deletion config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const config = {
},
},
pages,
homePage: 'home',
publicPath: '/',
}

Expand Down
1 change: 1 addition & 0 deletions src/components/editor/index.module.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.editor {
height: 100%;
min-height: 100px;
width: auto;
}
14 changes: 10 additions & 4 deletions src/components/editor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import * as monaco from 'monaco-editor'
import { useEffect, useRef } from 'react'
import { useEffect, useRef, useState } from 'react'
import styles from './index.module.scss'

export function Editor() {
const [loading, setLoading] = useState(false)
const divEl = useRef<HTMLDivElement>(null)
let editor: monaco.editor.IStandaloneCodeEditor
useEffect(() => {
const resizeObserver = new ResizeObserver((entries) => {
editor?.layout()
})
if (divEl.current) {
import('monaco-editor').then(m => {
import('monaco-editor').then((m) => {
setLoading(false)
editor = m.editor.create(divEl.current, {
value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join(
'\n'
Expand All @@ -23,7 +25,7 @@ export function Editor() {
wordWrap: 'on',
renderControlCharacters: true,
rulers: [80, 120],
theme: 'vs-light+'
theme: 'vs-light+',
})
resizeObserver.observe(divEl.current)
})
Expand All @@ -33,5 +35,9 @@ export function Editor() {
resizeObserver.disconnect()
}
}, [])
return <div className={styles.editor} ref={divEl}></div>
return (
<div className={styles.editor} ref={divEl}>
{loading && 'loading...'}
</div>
)
}
2 changes: 1 addition & 1 deletion src/components/render/base.scss
Original file line number Diff line number Diff line change
@@ -1 +1 @@
@import "~bootstrap";
@import "~bootstrap/scss/bootstrap";
8 changes: 7 additions & 1 deletion src/components/render/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import ReactDOM from 'react-dom'
import { Wrap } from './wrap'
import './base.scss'
import { pages } from '../../pages/index'

export function render(App: () => JSX.Element) {
ReactDOM.render(
<Wrap>
<Wrap
sidebars={pages.map((item) => ({
name: item.title,
link: `/${item.link}`,
}))}
>
<App />
</Wrap>,
document.querySelector('#root')
Expand Down
28 changes: 26 additions & 2 deletions src/components/render/wrap.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
import React from 'react'

export function Wrap(props: React.PropsWithChildren<{}>) {
return <div>{props.children}</div>
type SidebarProp = { name: string; link: string }[]
interface WrapProps {
sidebars: SidebarProp
}

const Sidebar = (props: { sidebars: SidebarProp }) => (
<ul className="list-group">
{props.sidebars.map((item) => (
<li className="list-group-item" key={item.name}>
<a href={item.link}>{item.name}</a>
</li>
))}
</ul>
)

export function Wrap(props: React.PropsWithChildren<WrapProps>) {
return (
<div className="container-fluid p-3">
<div className="row">
<div className="col-md-auto">
<Sidebar sidebars={props.sidebars} />
</div>
<div className="col">{props.children}</div>
</div>
</div>
)
}
15 changes: 0 additions & 15 deletions src/pages/bootstrap.tsx

This file was deleted.

157 changes: 157 additions & 0 deletions src/pages/color.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import React, { useEffect, useState } from 'react'
import { render } from '../components'
import clsx from 'clsx'

enum ColorType {
HEX3 = '十六进制(3)',
HEX6 = '十六进制(6)',
RGB = 'RGB',
// HSL = 'HSL',
// HSB = 'HSB/HSV',
}

const regexp = {
HEX: /^#?[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/,
HEX3: /^#?[0-9a-fA-F]{3}$/,
HEX6: /^#?[0-9a-fA-F]{6}$/,
number255: /^([0-9]{1,2}|[01][0-9]{2}|2[0-5]{2})$/,
}

const ColorPage = () => {
const [input, setInput] = useState<string>('')
const changeinput = (e: React.ChangeEvent<HTMLInputElement>) =>
setInput(e.target.value)

const [sourceRGB, setSourceRGB] = useState<number[]>()
const [type, setType] = useState<ColorType>()
const [target, setTarget] = useState<{ hex: string[] }>()

useEffect(() => {
switch (true) {
case regexp.HEX3.test(input):
setType(ColorType.HEX3)
setSourceRGB(HexToRgb(input))
break
case regexp.HEX6.test(input):
setType(ColorType.HEX6)
setSourceRGB(HexToRgb(input))
break
case checkRgb(input):
setType(ColorType.RGB)
setSourceRGB(formatRgb(input))
break
default:
setType(undefined)
setSourceRGB(undefined)
}
}, [input])
useEffect(() => {
if (!sourceRGB) setTarget(undefined)
else {
setTarget({
hex: RgbToHex(sourceRGB),
})
}
}, [sourceRGB])

function checkRgb(source: string): boolean {
return (
source
.replace(/(rgba?|\(|\))/gi, '')
.split(',')
.map((n) => regexp.number255.test(n.trim()))
.filter(Boolean).length === 3
)
}

function formatRgb(source: string): number[] {
return source
.replace(/(rgba?|\(|\))/gi, '')
.split(',')
.map((item) => +item.trim())
}

// hex{3,6} => rgb
function HexToRgb(source: string): number[] {
const _source = source.replace('#', '').toLocaleUpperCase()

if (_source.length === 3)
return _source.split('').map((item) => (parseInt(item, 16) * 255) / 15)

if (_source.length === 6) {
const list = []
_source.replace(/[0-9A-F]{2}/g, (match) => {
list.push(match)
return ''
})
return list.map((item) => parseInt(item, 16))
}
}

// rgb => hex
function RgbToHex(source: number[]): string[] {
return source.map((item) => Number(item).toString(16).padStart(2, '0'))
}

return (
<div>
<div className="row align-items-center">
<div className="col-auto">
<label htmlFor="colorInput" className="col-form-label">
颜色值
</label>
</div>
<div className="col-auto">
<input
id="colorInput"
type="search"
className="form-control"
placeholder="输入一个颜色的值"
value={input}
onChange={changeinput}
/>
</div>
</div>

<ul className="list-group mt-3">
<li className="list-group-item">
颜色:{' '}
<span
className="mx-3 d-inline-block align-middle"
style={{
width: '1rem',
height: '1rem',
background: sourceRGB
? `rgb(${sourceRGB.join(',')})`
: 'transparent',
}}
></span>
</li>
<li className="list-group-item">
类型:{' '}
{Object.entries(ColorType).map(([key, value]) => (
<span
className={clsx(
'badge mx-1 d-inline-block',
type + '' === value ? 'bg-primary' : 'bg-secondary opacity-25'
)}
key={key}
>
{value}
</span>
))}
</li>
<li className="list-group-item">
{ColorType.RGB}:{' '}
{sourceRGB ? <code>{`rgb(${sourceRGB.join(', ')})`}</code> : '---'}
</li>
<li className="list-group-item">
{ColorType.HEX6}:{' '}
{target?.hex ? <code>{`#${target?.hex?.join('')}`}</code> : '---'}
</li>
</ul>
</div>
)
}

render(ColorPage)
11 changes: 6 additions & 5 deletions src/pages/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const pages = [
{ title: 'home', filename: 'home', id: 'home' },
{ title: 'title', filename: 'title', id: 'title' },
{ title: 'Bootstrap', filename: 'bootstrap', id: 'bootstrap' },
{ title: 'Editor', filename: 'editor', id: 'editor' },
]
// { title: 'home', filename: 'home', id: 'home' },
// { title: 'title', filename: 'title', id: 'title' },
// { title: 'Editor', filename: 'editor', id: 'editor' },
{ title: '颜色值转换', filename: 'color', id: 'color' },
{ title: 'todo', filename: 'todo', id: 'todo' },
].map((item) => ({ ...item, link: item.id === 'home' ? '' : item.filename }))
25 changes: 25 additions & 0 deletions src/pages/todo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { render } from '../components'

const TodoPage = () => {
const list = [
{ title: '颜色转换', checked: false },
{ title: 'JSON 格式化', checked: false },
]

return (
<div className="">
<p>记录一些这个网站会做的事情</p>
<ul>
{list.map((item) => (
<li key={item.title}>
<input type="checkbox" checked={item.checked} />
{' ' + item.title}
</li>
))}
<input type="checkbox" className="bg-primary" />
</ul>
</div>
)
}

render(TodoPage)
4 changes: 3 additions & 1 deletion src/styles/editor.module.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@import "~bootstrap/scss/bootstrap";

.page {
height: 100vh;
height: calc(100vh - $spacer * 2);
overflow: auto;
}
5 changes: 1 addition & 4 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ function compiler(): webpack.Configuration {
title: page.title,
chunks: [page.filename],
scriptLoading: 'module',
filename:
page.id === config.homePage
? 'index.html'
: page.filename + '/index.html',
filename: (page.link === '' ? '' : `${page.link}/`) + 'index.html',
minify: {
collapseWhitespace: true,
keepClosingSlash: true,
Expand Down

0 comments on commit dbe25de

Please sign in to comment.