Skip to content

Commit

Permalink
chore: add more case to playground
Browse files Browse the repository at this point in the history
  • Loading branch information
fantasticsoul committed Jan 13, 2024
1 parent dacb28c commit 61fac2a
Show file tree
Hide file tree
Showing 11 changed files with 366 additions and 21 deletions.
49 changes: 37 additions & 12 deletions docs/docs/playground/demos/Playground/ApiMenus.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,48 @@
// @ts-nocheck
import React from 'react';
import './index.less';
import * as codes from './codes';

const c = '#e8ae56';

export default React.memo(({ onClick, name }: any) => {
const orderedKeys = [
'atom',
'derive',
'watch',
'reactive',
'signal',
'modular',
'useAtom',
'useDerived',
];

function noDupPush(list: string[], item: string) {
if (!list.includes(item)) {
list.push(item);
}
}

function renderItems(name: string) {
const st = (toMatch: string) => ({ color: name === toMatch ? c : '' });

const codeDict: any = codes;
const keys = orderedKeys.slice();
Object.keys(codeDict).forEach(key => noDupPush(keys, key));
return keys.map(key => (
<div key={key} className="menuWrap" data-name={key} style={st(key)}>{key}</div>
));
}

export default React.memo(({ onClick, name }: any) => {
const handleClick = e => {
const name = e.target.dataset.name;
if (name) {
onClick?.(name);
}
};
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 style={{ width: '120px' }} onClick={handleClick}>
{renderItems(name)}
</div>
);
});
9 changes: 8 additions & 1 deletion docs/docs/playground/demos/Playground/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import * as codes from './codes';
const labelAlias: any = {
atom: {
dict_atomx: 'dict(atomx)',
}
dict_sharex: 'dict(sharex)',
},
reactive: {
dict_atomx: 'dict(atomx)',
},
useReactive: {
primitive_atomx: 'primitive(atomx)',
},
};

function getLabel(name: string, subName: string) {
Expand Down
17 changes: 16 additions & 1 deletion docs/docs/playground/demos/Playground/codes/atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,35 @@ render(<button onClick={ change } > change { $(dict.val.b.b1.b2)}</button>);
`;

const dict_atomx = `
// stateRoot was still boxed,
// state was already unboxed from { val: T } to T
const { state, setDraft } = atomx({ a: 1, b: { b1: { b2: 1 } } });
const { state, stateRoot, 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);
console.log('stateRoot.val.b.b1.b2 is ', stateRoot.val.b.b1.b2);
};
render(<button onClick={change}>change {$(state.b.b1.b2)}</button>);
`;

const dict_sharex = `
// state === stateRoot when use sharex
const { state, stateRoot, setDraft } = sharex({ 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);
console.log('stateRoot.b.b1.b2 is ', stateRoot.b.b1.b2);
};
render(<button onClick={change}>change {$(state.b.b1.b2)}</button>);
`;

export default {
primitive,
dict,
dict_atomx,
dict_sharex,
} 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
@@ -1,5 +1,10 @@
export { default as atom } from './atom';
export { default as derive } from './derive';
export { default as watch } from './watch';
export { default as reactive } from './reactive';
export { default as signal } from './signal';
export { default as modular } from './modular';
export { default as useAtom } from './useAtom';
export { default as useDerived } from './useDerived';
export { default as useReactive } from './useReactive';
export { default as useWatch } from './useWatch';
51 changes: 51 additions & 0 deletions docs/docs/playground/demos/Playground/codes/modular.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@


const defineActions = `
const { defineActions, useState } = sharex({ a: 1, b: { b1: { b2: 1 } } });
const delay = (ms = 1000) => new Promise(r => setTimeout(r, ms));
const { actions, useLoading } = defineActions()({
changeA({ draft }) {
draft.a += 1;
},
async changeB2Async({ draft }) {
await delay();
const { b1 } = draft.b;
b1.b2 += 10;
if (b1.b2 > 30 && b1.b2 < 50) {
throw new Error('throw err to useLoading');
}
},
});
function Demo() {
const [state] = useState();
return (
<div>
<h1>state.a: {state.a} </h1>
<button onClick={actions.changeA}>changeA</button>
</div>
);
}
function DemoWithLoading() {
const [state] = useState();
const { changeB2Async: { ok, loading, err } } = useLoading();
return (
<div>
{ok && <h1>state.b.b1.b2: {state.b.b1.b2} </h1>}
{loading && <h1>loading...</h1>}
{err && <h1 style={{ color: 'red' }}> {err.message} </h1>}
<button onClick={actions.changeB2Async}>changeB2Async</button>
<h5>click 3 times will trigger error</h5>
</div>
);
}
render(<><Demo /><DemoWithLoading /></>);
`;

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


const primitive = `
const [ num, , { reactiveRoot } ] = atom(1);
const change = ()=> {
reactiveRoot.val++; // commit at next tick
setTimeout(()=>{
console.log(\`num is \${num.val}\`);
},0);
};
render(<button onClick={change}>change {$(num)}</button>);
`;

const primitive_flush = `
const [ num, , { reactiveRoot, flush: flushChanged } ] = atom(1);
const change = ()=> {
reactiveRoot.val++; // commit at next tick
flushChanged(); // commit changed data immediately
console.log(\`num is \${num.val}\`);
};
render(<button onClick={change}>change {$(num)}</button>);
`;

const dict = `
// use unboxed reactive insteadof boxed reactiveRoot
const [dict, , { reactive }] = atom({ a: 1, b: { b1: { b2: 1 } } });
const change = () => {
reactive.b.b1.b2 += 100; // already unboxed
setTimeout(()=>{
console.log('reactive.b.b1.b2 is ', reactive.b.b1.b2);
},0);
};
render(<button onClick={ change } > change { $(reactive.b.b1.b2)}</button>);
`;

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


export default {
primitive,
primitive_flush,
dict,
dict_atomx,
} as Record<string, string>;
66 changes: 66 additions & 0 deletions docs/docs/playground/demos/Playground/codes/signal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const primitive = `
const [ num, setNum ] = atom(1);
const change = ()=> {
setNum(prev=>prev+1);
console.log(\`num is \${num.val}\`);
};
render(<button onClick={change}>change {signal(num)}</button>);
`;

const alias = `
const [ num, setNum ] = atom(1);
const change = ()=> {
setNum(prev=>prev+1);
console.log(\`num is \${num.val}\`);
};
// use $ instead of signal to wrap shared state primitive value
render(<button onClick={change}>change {$(num)}</button>);
`;

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

const block = `
const [ num, setNum ] = atom(1);
const change = ()=> {
setNum(prev=>prev+1);
console.log(\`num is \${num.val}\`);
};
const Num = block(()=>{
const [ count, setCount ] = React.useState(0);
return (
<div>
{/** pass shared state primite value without hook */}
{num.val}
<br />
local count: {count}
<button onClick={change}>change</button>
<button onClick={()=>setCount(prev=>prev+1)}>change count</button>
</div>
);
});
render(<><Num /><Num /></>);
`;

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

const primitive = `
const [ num, , { reactiveRoot, useReactive: useReactiveState } ] = atom(1);
const change = ()=> {
reactiveRoot.val++; // commit at next tick
};
function Demo() {
const [ numVal ] = useReactiveState(); // already unboxed
return (
<div>
num: {numVal}
<button onClick={change}>change</button>
</div>
);
};
render(<><Demo /><Demo /></>);
`;

const primitive_atomx = `
const ctx = atomx(1); // atomx return dict, atom return tuple
const { reactiveRoot } = ctx;
const change = ()=> {
reactiveRoot.val++; // commit at next tick
};
function Demo() {
const [ numVal ] = ctx.useReactive(); // already unboxed
return (
<div>
num: {numVal}
<button onClick={change}>change</button>
</div>
);
};
render(<><Demo /><Demo /></>);
`;

export default {
primitive,
primitive_atomx,
} as Record<string, string>;
Loading

0 comments on commit 61fac2a

Please sign in to comment.