Skip to content

Commit

Permalink
feat: add playground v1
Browse files Browse the repository at this point in the history
  • Loading branch information
fantasticsoul committed Jan 13, 2024
1 parent 0d97690 commit dacb28c
Show file tree
Hide file tree
Showing 18 changed files with 683 additions and 50 deletions.
1 change: 1 addition & 0 deletions docs/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default defineConfig({
nav: [
{ title: '指南', link: '/guide' },
{ title: 'API', link: '/api' },
{ title: '演练场', link: '/playground' },
{ title: '参考', link: '/reference' },
{ title: '生态', link: '/ecosystem' },
{ title: 'GitHub', link: 'https://github.com/heluxjs/helux' },
Expand Down
2 changes: 2 additions & 0 deletions docs/docs/ecosystem/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ nav:
---

# 生态

to be added
2 changes: 2 additions & 0 deletions docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ hero:
actions:
- text: 快速开始
link: /guide/quick-start
- text: Playground
link: /playground
- text: Github
link: https://github.com/heluxjs/helux
features:
Expand Down
23 changes: 23 additions & 0 deletions docs/docs/playground/demos/Playground/ApiMenus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @ts-nocheck
import React from 'react';
import './index.less';

const c = '#e8ae56';

export default React.memo(({ onClick, name }: any) => {
const st = (toMatch: string) => ({ color: name === toMatch ? c : '' });
return (
<div style={{ width: '120px' }} onClick={e => {
const name = e.target.dataset.name;
if (name) {
onClick?.(name);
}
}}>
<div className="menuWrap" data-name="atom" style={st('atom')}>atom</div>
<div className="menuWrap" data-name="derive" style={st('derive')}>derive</div>
<div className="menuWrap" data-name="watch" style={st('watch')}>watch</div>
<div className="menuWrap" data-name="useAtom" style={st('useAtom')}>useAtom</div>
<div className="menuWrap" data-name="useDerived" style={st('useDerived')}>useDerived</div>
</div>
);
});
30 changes: 30 additions & 0 deletions docs/docs/playground/demos/Playground/Console.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react'
import { Hook, Console, Decode } from 'console-feed';
import './index.less';

class HeluxConsole extends React.Component<any, { logs: any[] }> {
state = {
logs: [],
}

componentDidMount() {
Hook(window.console, (log) => {
this.setState(({ logs }) => ({ logs: [...logs, Decode(log)] }))
});
console.log('welcome to helux playground ^_^');
}

render() {
const clear = () => this.setState({ logs: [] });
return (
<div className="liveConsoleWrap">
<button type="button" style={{ position: 'absolute', right: '12px', top: '1px', zIndex: 2000 }} onClick={clear}>clear</button>
<div className="liveConsole">
<Console logs={this.state.logs} variant="dark" />
</div>
</div>
)
}
}

export default React.memo(HeluxConsole);
41 changes: 41 additions & 0 deletions docs/docs/playground/demos/Playground/TopBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @ts-nocheck
import React from 'react';
import './index.less';
import * as codes from './codes';

const labelAlias: any = {
atom: {
dict_atomx: 'dict(atomx)',
}
};

function getLabel(name: string, subName: string) {
return labelAlias[name]?.[subName] || subName;
}

function renderItems(name: string, subName: string) {
const st = (toMatch: string) => subName === toMatch
? { backgroundColor: 'rgb(100, 90, 183)', color: '#fff' }
: { backgroundColor: '', color: 'rgb(100, 90, 183)' };

const codeDict: any = codes;
const subDict = codeDict[name] || {};
return Object.keys(subDict).map(key => (
<div key={key} className="topBarItem" data-name={key} style={st(key)}>{getLabel(name, key)}</div>
));
}

export default React.memo(({ onClick, name, subName }: any) => {
const handleClick = e => {
const subName = e.target.dataset.name;
if (subName) {
onClick?.(subName);
}
};

return (
<div className="topBar" onClick={handleClick}>
{renderItems(name, subName)}
</div>
);
});
45 changes: 45 additions & 0 deletions docs/docs/playground/demos/Playground/codes/atom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@


const primitive = `
const [ num, setNum ] = atom(1);
const change = ()=> {
setNum(prev=>prev+1);
console.log(\`num is \${num.val}\`);
};
render(<button onClick={change}>change {$(num)}</button>);
`;

const dict = `
const [dict, setDict] = atom({ a: 1, b: { b1: { b2: 1 } } });
const change = () => {
setDict(draft => {
// draft was already unboxed from { val: T } to T
draft.b.b1.b2 += 100;
})
console.log('dict.val.b.b1.b2 is ', dict.val.b.b1.b2);
};
render(<button onClick={ change } > change { $(dict.val.b.b1.b2)}</button>);
`;

const dict_atomx = `
// state was already unboxed from { val: T } to T
const { state, setDraft } = atomx({ a: 1, b: { b1: { b2: 1 } } });
const change = () => {
setDraft(draft => draft.b.b1.b2 += 100);
console.log('state.b.b1.b2 is ', state.b.b1.b2);
};
render(<button onClick={change}>change {$(state.b.b1.b2)}</button>);
`;


export default {
primitive,
dict,
dict_atomx,
} as Record<string, string>;
21 changes: 21 additions & 0 deletions docs/docs/playground/demos/Playground/codes/derive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

// render(<button onClick={change}>change</button>);

// const changeBtnStr = `render(<button onClick={change}>change</button>);`

const primitive = `
const [ num, setNum ] = atom(1);
const result = derive(()=> num.val + 1);
const change = ()=> {
setNum(prev=>prev+1);
console.log(\`num is \${num.val}\`);
console.log(\`result is \${result.val}\`);
};
render(<button onClick={change}>change {$(result.val)}</button>);
`;

export default {
primitive,
} as Record<string, string>;
5 changes: 5 additions & 0 deletions docs/docs/playground/demos/Playground/codes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as atom } from './atom';
export { default as derive } from './derive';
export { default as watch } from './watch';
export { default as useAtom } from './useAtom';
export { default as useDerived } from './useDerived';
25 changes: 25 additions & 0 deletions docs/docs/playground/demos/Playground/codes/useAtom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

const primitive = `
const [ num, setNum ] = atom(1);
const change = ()=> {
setNum(prev => prev + 1);
console.log(\`num is \${num.val}\`);
};
function Demo() {
const [ numVal ] = useAtom(num); // already unboxed
return (
<div>
num: {numVal}
<button onClick={change}>change</button>
</div>
);
};
render(<><Demo /><Demo /></>);
`;

export default {
primitive,
} as Record<string, string>;
26 changes: 26 additions & 0 deletions docs/docs/playground/demos/Playground/codes/useDerived.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

const primitive = `
const [ num, setNum ] = atom(1);
const result = derive(()=> num.val + 100);
const change = ()=> {
setNum(prev => prev + 1);
console.log(\`num is \${num.val}\`);
};
function Demo() {
const [ numVal ] = useDerived(result); // already unboxed
return (
<div>
derived num: {numVal}
<button onClick={change}>change</button>
</div>
);
};
render(<><h1>num: {$(num.val)}</h1><Demo /><Demo /></>);
`;

export default {
primitive,
} as Record<string, string>;
50 changes: 50 additions & 0 deletions docs/docs/playground/demos/Playground/codes/watch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@




const primitive = `
const [num, setNum] = atom(1);
watch(
// watch cb
() => {
console.log(\`change from \${getSnap(num).val} to \${num.val}\`);
},
// deps cb
() => [num],
);
const change = () => {
setNum(prev => prev + 1);
console.log(\`num is \${num.val}\`);
};
render(<button onClick={change}>change {$(num)}</button>);
`;

const dict = `
const [dict, setDict] = atom({ a: 1, b: { b1: { b2: 1 } } });
watch(
// watch cb
() => {
console.log(\`change from \${getSnap(dict).val.b.b1.b2} to \${dict.val.b.b1.b2}\`);
},
// deps cb
() => [dict.val.b.b1.b2],
);
const change = () => {
setDict(draft => {
// draft was already unboxed from { val: T } to T
draft.b.b1.b2 += 100;
});
console.log('dict.val.b.b1.b2 is ', dict.val.b.b1.b2);
};
render(<button onClick={change}>change {$(dict.val.b.b1.b2)}</button>);
`;

export default {
primitive,
dict,
} as Record<string, string>;
95 changes: 95 additions & 0 deletions docs/docs/playground/demos/Playground/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/** 美化滚动条 [Start] */
.playground-wrap .prism-code:-webkit-scrollbar {
width: 5px !important;
height: 5px !important;
}

.playground-wrap .prism-code::-webkit-scrollbar-track {
width: 5px !important;
background: hsla(0, 0%, 100%, 0.1) !important;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}

.playground-wrap .prism-code::-webkit-scrollbar-thumb {
background: hsla(0, 0%, 100%, 0.2) !important;
background-color: #c1c1c1 !important;
background-clip: padding-box;
min-height: 28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}

.playground-wrap .prism-code::-webkit-scrollbar-thumb:hover {
background-color: #443082 !important;
}

.playground-wrap {
width: 100vw;
height: calc(100vh - 76px);
position: fixed;
left: 0px;
top: 76px;
z-index: 888;
background-color: rgb(255, 255, 255);
}

.playground-wrap .prism-code {
height: calc(100vh - 158px);
}

.playground-wrap .liveErr {
color: red;
}

.playground-wrap .liveConsoleWrap {
position: relative;
height: 50%;
}

.playground-wrap .liveConsole {
background-color: #242424;
height: 100%;
overflow-y: auto;
}

.playground-wrap .menuWrap {
display: block;
height: 28px;
color: #4f5866;
font-size: 16px;
line-height: 28px;
text-decoration: none;
transition: all 0.3s;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.playground-wrap .topBar {
width: 200%;
height: 28px;
z-index: 200;
border: 1px solid #443782;
box-sizing: border-box;
}

.playground-wrap .topBarItem {
display: inline-block;
height: 22px;
color: #fff;
padding: 0 6px;
font-size: 14px;
line-height: 22px;
margin: 2px 5px;
}

.playground-wrap .topBarItem:hover {
cursor: pointer;
}

.playground-wrap .menuWrap:hover {
cursor: pointer;
}
Loading

0 comments on commit dacb28c

Please sign in to comment.