[housekeeping] Remove fixtures/

Do we still use these? I'm happy to close this PR if we still want this but it 
feels like these may have served their purpose and no longer be necessary.
This commit is contained in:
Joe Savona
2024-01-12 12:22:19 -08:00
parent 653373141a
commit 33118be835
164 changed files with 0 additions and 46305 deletions
-3
View File
@@ -1,3 +0,0 @@
{
"plugins": ["../../"]
}
-1
View File
@@ -1 +0,0 @@
SKIP_PREFLIGHT_CHECK=true
-21
View File
@@ -1,21 +0,0 @@
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-29
View File
@@ -1,29 +0,0 @@
# React Forget Demo - 2021 Q3
[Google Slides (FB.com permission)](https://docs.google.com/presentation/d/1W4heHbak1GrfYQIJpUCMkn1g68z8ab3B_nIy7_ZXHI8/edit?usp=sharing)
## Get Started
This is a Create-React-App project.
### Compile
Currently the compilation is all ad-hoc
1. Add your file in `run-forget.sh`
2. Run the sh
```
# or npm run forget
./run-forget.sh
```
### Measurement
Currently, the measurement is done by manually
1. Copy/Paste JSX lowered file
2. add the file to `uglify_gzip.sh`
3. run `uglify_gzip.sh`
4. `ls -l`
@@ -1,140 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { createContext, useRef, useReducer, useContext } from "react";
import "./styles.css";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const initialStore = {
left: undefined,
right: undefined,
};
const reducer = (state, action) => {
switch (action.tag) {
case "left":
return { ...state, left: action.payload };
case "right":
return { ...state, right: action.payload };
default:
return state;
}
};
const BinaryContext = /*#__PURE__*/ createContext(initialStore);
function Input({ value, onChange }) {
return /*#__PURE__*/ _jsx("input", {
className: "Search",
placeholder: "...",
value: value,
onChange: onChange,
});
}
function Left() {
const [{ left }, dispatch] = useContext(BinaryContext);
const rerenderCount = useRef(0);
return /*#__PURE__*/ _jsxs("div", {
className: "column Demo2",
children: [
/*#__PURE__*/ _jsxs("header", {
className: "Header row",
children: [
/*#__PURE__*/ _jsx("div", {
className: "Icon",
children: "\u269B\uFE0F",
}),
/*#__PURE__*/ _jsx(Input, {
value: left,
onChange: (e) =>
dispatch({
tag: "left",
payload: e.target.value,
}),
}),
],
}),
/*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
/*#__PURE__*/ _jsx("div", {
className: "FeedItem",
children: left,
}),
],
}),
],
});
}
function Right() {
const [{ right }, dispatch] = useContext(BinaryContext);
const rerenderCount = useRef(0);
return /*#__PURE__*/ _jsxs("div", {
className: "column Demo2",
children: [
/*#__PURE__*/ _jsxs("header", {
className: "Header row",
children: [
/*#__PURE__*/ _jsx("div", {
className: "Icon",
children: "\u269B\uFE0F",
}),
/*#__PURE__*/ _jsx(Input, {
value: right,
onChange: (e) =>
dispatch({
tag: "right",
payload: e.target.value,
}),
}),
],
}),
/*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
/*#__PURE__*/ _jsx("div", {
className: "FeedItem",
children: right,
}),
],
}),
],
});
}
export default function Demo2() {
const [state, dispatch] = useReducer(reducer, initialStore);
const store = [state, dispatch];
return /*#__PURE__*/ _jsx(BinaryContext.Provider, {
value: store,
children: /*#__PURE__*/ _jsxs("div", {
className: "App",
children: [
/*#__PURE__*/ _jsx("h2", {
children: "Demo2 - Context",
}),
/*#__PURE__*/ _jsxs("div", {
className: "row",
children: [
/*#__PURE__*/ _jsx(Left, {}),
/*#__PURE__*/ _jsx(Right, {}),
],
}),
],
}),
});
}
@@ -1,188 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { createContext, useRef, useReducer, useContext } from "react";
import "./styles.css";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
const initialStore = {
left: undefined,
right: undefined,
};
const reducer = (state, action) => {
switch (action.tag) {
case "left":
return { ...state, left: action.payload };
case "right":
return { ...state, right: action.payload };
default:
return state;
}
};
const BinaryContext = /*#__PURE__*/ createContext(initialStore);
function Input(props) {
let $ = useMemoCache(2);
let prevProps = $[0];
let c_props = !prevProps || prevProps !== props;
if (c_props) $[0] = props;
let c_value = c_props && prevProps.value !== props.value;
let c_onChange = c_props && prevProps.onChange !== props.onChange;
return c_value || c_onChange
? ($[1] = /*#__PURE__*/ _jsx("input", {
className: "Search",
placeholder: "...",
value: props.value,
onChange: props.onChange,
}))
: $[1];
}
function Left() {
let $ = useMemoCache(9);
const [{ left }, dispatch] = useContext(BinaryContext);
let c_dispatch = $[2] !== dispatch;
if (c_dispatch) $[2] = dispatch;
let c_left = $[1] !== left;
if (c_left) $[1] = left;
const rerenderCount = useRef(0);
return c_left || c_dispatch
? ($[8] = /*#__PURE__*/ _jsxs("div", {
className: "column Demo2",
children: [
c_left || c_dispatch
? ($[5] = /*#__PURE__*/ _jsxs("header", {
className: "Header row",
children: [
/*#__PURE__*/ _jsx("div", {
className: "Icon",
children: "\u269B\uFE0F",
}),
c_left || c_dispatch
? ($[4] = /*#__PURE__*/ _jsx(Input, {
value: left,
onChange: c_dispatch
? ($[3] = (e) =>
dispatch({
tag: "left",
payload: e.target.value,
}))
: $[3],
}))
: $[4],
],
}))
: $[5],
c_left
? ($[7] = /*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
c_left
? ($[6] = /*#__PURE__*/ _jsx("div", {
className: "FeedItem",
children: left,
}))
: $[6],
],
}))
: $[7],
],
}))
: $[8];
}
function Right() {
let $ = useMemoCache(9);
const [{ right }, dispatch] = useContext(BinaryContext);
let c_dispatch = $[2] !== dispatch;
if (c_dispatch) $[2] = dispatch;
let c_right = $[1] !== right;
if (c_right) $[1] = right;
const rerenderCount = useRef(0);
return c_right || c_dispatch
? ($[8] = /*#__PURE__*/ _jsxs("div", {
className: "column Demo2",
children: [
c_right || c_dispatch
? ($[5] = /*#__PURE__*/ _jsxs("header", {
className: "Header row",
children: [
/*#__PURE__*/ _jsx("div", {
className: "Icon",
children: "\u269B\uFE0F",
}),
c_right || c_dispatch
? ($[4] = /*#__PURE__*/ _jsx(Input, {
value: right,
onChange: c_dispatch
? ($[3] = (e) =>
dispatch({
tag: "right",
payload: e.target.value,
}))
: $[3],
}))
: $[4],
],
}))
: $[5],
c_right
? ($[7] = /*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
c_right
? ($[6] = /*#__PURE__*/ _jsx("div", {
className: "FeedItem",
children: right,
}))
: $[6],
],
}))
: $[7],
],
}))
: $[8];
}
export default function Demo2() {
let $ = useMemoCache(4);
const [state, dispatch] = useReducer(reducer, initialStore);
let c_state = $[1] !== state;
if (c_state) $[1] = state;
const store = c_state ? ($[2] = [state, dispatch]) : $[2];
return c_state
? ($[3] = /*#__PURE__*/ _jsx(BinaryContext.Provider, {
value: store,
children: /*#__PURE__*/ _jsxs("div", {
className: "App",
children: [
/*#__PURE__*/ _jsx("h2", {
children: "Demo2 - Context",
}),
/*#__PURE__*/ _jsxs("div", {
className: "row",
children: [
/*#__PURE__*/ _jsx(Left, {}),
/*#__PURE__*/ _jsx(Right, {}),
],
}),
],
}),
}))
: $[3];
}
@@ -1,8 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import{useMemoCache}from"./useMemoCache";import React,{createContext,useRef,useReducer,useContext}from"react";import"./styles.css";import{jsx as _jsx}from"react/jsx-runtime";import{jsxs as _jsxs}from"react/jsx-runtime";const initialStore={left:void 0,right:void 0},reducer=(e,t)=>{switch(t.tag){case"left":return{...e,left:t.payload};case"right":return{...e,right:t.payload};default:return e}},BinaryContext=createContext(initialStore);function Input(e){let t=useMemoCache(2);var a=t[0],s=!a||a!==e;s&&(t[0]=e);var r=s&&a.value!==e.value,a=s&&a.onChange!==e.onChange;return r||a?t[1]=_jsx("input",{className:"Search",placeholder:"...",value:e.value,onChange:e.onChange}):t[1]}function Left(){let e=useMemoCache(9);const[{left:t},a]=useContext(BinaryContext);var s=e[2]!==a;s&&(e[2]=a);var r=e[1]!==t;r&&(e[1]=t);const n=useRef(0);return r||s?e[8]=_jsxs("div",{className:"column Demo2",children:[r||s?e[5]=_jsxs("header",{className:"Header row",children:[_jsx("div",{className:"Icon",children:"⚛️"}),r||s?e[4]=_jsx(Input,{value:t,onChange:s?e[3]=e=>a({tag:"left",payload:e.target.value}):e[3]}):e[4]]}):e[5],r?e[7]=_jsxs("div",{className:"Feed",children:[_jsx("h3",{children:n.current++}),r?e[6]=_jsx("div",{className:"FeedItem",children:t}):e[6]]}):e[7]]}):e[8]}function Right(){let e=useMemoCache(9);const[{right:t},a]=useContext(BinaryContext);var s=e[2]!==a;s&&(e[2]=a);var r=e[1]!==t;r&&(e[1]=t);const n=useRef(0);return r||s?e[8]=_jsxs("div",{className:"column Demo2",children:[r||s?e[5]=_jsxs("header",{className:"Header row",children:[_jsx("div",{className:"Icon",children:"⚛️"}),r||s?e[4]=_jsx(Input,{value:t,onChange:s?e[3]=e=>a({tag:"right",payload:e.target.value}):e[3]}):e[4]]}):e[5],r?e[7]=_jsxs("div",{className:"Feed",children:[_jsx("h3",{children:n.current++}),r?e[6]=_jsx("div",{className:"FeedItem",children:t}):e[6]]}):e[7]]}):e[8]}export default function Demo2(){let e=useMemoCache(4);var[t,a]=useReducer(reducer,initialStore),s=e[1]!==t;s&&(e[1]=t);a=s?e[2]=[t,a]:e[2];return s?e[3]=_jsx(BinaryContext.Provider,{value:a,children:_jsxs("div",{className:"App",children:[_jsx("h2",{children:"Demo2 - Context"}),_jsxs("div",{className:"row",children:[_jsx(Left,{}),_jsx(Right,{})]})]})}):e[3]}
@@ -1,8 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React,{createContext,useRef,useReducer,useContext}from"react";import"./styles.css";import{jsx as _jsx}from"react/jsx-runtime";import{jsxs as _jsxs}from"react/jsx-runtime";const initialStore={left:void 0,right:void 0},reducer=(e,t)=>{switch(t.tag){case"left":return{...e,left:t.payload};case"right":return{...e,right:t.payload};default:return e}},BinaryContext=createContext(initialStore);function Input({value:e,onChange:t}){return _jsx("input",{className:"Search",placeholder:"...",value:e,onChange:t})}function Left(){const[{left:e},t]=useContext(BinaryContext),s=useRef(0);return _jsxs("div",{className:"column Demo2",children:[_jsxs("header",{className:"Header row",children:[_jsx("div",{className:"Icon",children:"⚛️"}),_jsx(Input,{value:e,onChange:e=>t({tag:"left",payload:e.target.value})})]}),_jsxs("div",{className:"Feed",children:[_jsx("h3",{children:s.current++}),_jsx("div",{className:"FeedItem",children:e})]})]})}function Right(){const[{right:e},t]=useContext(BinaryContext),s=useRef(0);return _jsxs("div",{className:"column Demo2",children:[_jsxs("header",{className:"Header row",children:[_jsx("div",{className:"Icon",children:"⚛️"}),_jsx(Input,{value:e,onChange:e=>t({tag:"right",payload:e.target.value})})]}),_jsxs("div",{className:"Feed",children:[_jsx("h3",{children:s.current++}),_jsx("div",{className:"FeedItem",children:e})]})]})}export default function Demo2(){var[e,t]=useReducer(reducer,initialStore),t=[e,t];return _jsx(BinaryContext.Provider,{value:t,children:_jsxs("div",{className:"App",children:[_jsx("h2",{children:"Demo2 - Context"}),_jsxs("div",{className:"row",children:[_jsx(Left,{}),_jsx(Right,{})]})]})})}
@@ -1,46 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useRef } from "react";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
export function FeedItem({ data, onClick }) {
const rerenderCount = useRef(0);
return /*#__PURE__*/ _jsx("a", {
href: `./item/${data.value}`,
className: "FeedItem",
onClick: onClick,
children: rerenderCount.current++,
});
}
export function Feed({ items }) {
const rerenderCount = useRef(0);
const onClick = (e) => {
e.preventDefault();
alert(e.target.href);
};
return /*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
items.map((item, index) =>
/*#__PURE__*/ _jsx(
FeedItem,
{
data: item,
onClick: onClick,
},
index
)
),
],
});
}
@@ -1,64 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { useRef } from "react";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
export function FeedItem(props) {
let $ = useMemoCache(2);
let prevProps = $[0];
let c_props = !prevProps || prevProps !== props;
if (c_props) $[0] = props;
let c_data = c_props && prevProps.data !== props.data;
let c_onClick = c_props && prevProps.onClick !== props.onClick;
const rerenderCount = useRef(0);
return c_data || c_onClick
? ($[1] = /*#__PURE__*/ _jsx("a", {
href: `./item/${props.data.value}`,
className: "FeedItem",
onClick: props.onClick,
children: rerenderCount.current++,
}))
: $[1];
}
export function Feed(props) {
let $ = useMemoCache(3);
let prevProps = $[0];
let c_props = !prevProps || prevProps !== props;
if (c_props) $[0] = props;
let c_items = c_props && prevProps.items !== props.items;
const rerenderCount = useRef(0);
const onClick =
$[1] ||
($[1] = (e) => {
e.preventDefault();
alert(e.target.href);
});
return c_items
? ($[2] = /*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
props.items.map((item, index) =>
/*#__PURE__*/ _jsx(
FeedItem,
{
data: item,
onClick: onClick,
},
index
)
),
],
}))
: $[2];
}
@@ -1,8 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import{useMemoCache}from"./useMemoCache";import React,{useRef}from"react";import{jsx as _jsx}from"react/jsx-runtime";import{jsxs as _jsxs}from"react/jsx-runtime";function FeedItem(e){let t=useMemoCache(2);var r=t[0],a=!r||r!==e;a&&(t[0]=e);var s=a&&r.data!==e.data,r=a&&r.onClick!==e.onClick;const m=useRef(0);return s||r?t[1]=_jsx("a",{href:`./item/${e.data.value}`,className:"FeedItem",onClick:e.onClick,children:m.current++}):t[1]}function Feed(e){let t=useMemoCache(3);var r=t[0],a=!r||r!==e;a&&(t[0]=e);r=a&&r.items!==e.items;const s=useRef(0),m=t[1]||(t[1]=e=>{e.preventDefault(),alert(e.target.href)});return r?t[2]=_jsxs("div",{className:"Feed",children:[_jsx("h3",{children:s.current++}),e.items.map((e,t)=>_jsx(FeedItem,{data:e,onClick:m},t))]}):t[2]}export{FeedItem,Feed};
@@ -1,47 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useRef, useCallback } from "react";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function FeedItem({ data, onClick }) {
const rerenderCount = useRef(0);
return /*#__PURE__*/ _jsx("a", {
href: `./item/${data.value}`,
className: "FeedItem",
onClick: onClick,
children: rerenderCount.current++,
});
}
const FeedItemMemoized = /*#__PURE__*/ React.memo(FeedItem);
export const Feed = /*#__PURE__*/ React.memo(({ items }) => {
const rerenderCount = useRef(0);
const onClick = useCallback((e) => {
e.preventDefault();
alert(e.target.href);
}, []);
return /*#__PURE__*/ _jsxs("div", {
className: "Feed",
children: [
/*#__PURE__*/ _jsx("h3", {
children: rerenderCount.current++,
}),
items.map((item, index) =>
/*#__PURE__*/ _jsx(
FeedItemMemoized,
{
data: item,
onClick: onClick,
},
index
)
),
],
});
});
@@ -1,8 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React,{useRef,useCallback}from"react";import{jsx as _jsx}from"react/jsx-runtime";import{jsxs as _jsxs}from"react/jsx-runtime";function FeedItem({data:e,onClick:t}){const r=useRef(0);return _jsx("a",{href:`./item/${e.value}`,className:"FeedItem",onClick:t,children:r.current++})}const FeedItemMemoized=React.memo(FeedItem),Feed=React.memo(({items:e})=>{const t=useRef(0),r=useCallback(e=>{e.preventDefault(),alert(e.target.href)},[]);return _jsxs("div",{className:"Feed",children:[_jsx("h3",{children:t.current++}),e.map((e,t)=>_jsx(FeedItemMemoized,{data:e,onClick:r},t))]})});export{Feed};
-8
View File
@@ -1,8 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React,{useRef}from"react";import{jsx as _jsx}from"react/jsx-runtime";import{jsxs as _jsxs}from"react/jsx-runtime";function FeedItem({data:e,onClick:t}){const r=useRef(0);return _jsx("a",{href:`./item/${e.value}`,className:"FeedItem",onClick:t,children:r.current++})}function Feed({items:e}){const t=useRef(0),r=e=>{e.preventDefault(),alert(e.target.href)};return _jsxs("div",{className:"Feed",children:[_jsx("h3",{children:t.current++}),e.map((e,t)=>_jsx(FeedItem,{data:e,onClick:r},t))]})}export{FeedItem,Feed};
@@ -1,12 +0,0 @@
uglifyjs --compress --mangle -- Feed.babel.js > Feed.min.js
uglifyjs --compress --mangle -- Feed.hook.babel.js > Feed.hook.min.js
uglifyjs --compress --mangle -- Feed.forget.babel.js > Feed.forget.min.js
uglifyjs --compress --mangle -- Demo2.babel.js > Demo2.min.js
uglifyjs --compress --mangle -- Demo2.forget.babel.js > Demo2.forget.min.js
gzip -k Feed.min.js
gzip -k Feed.hook.min.js
gzip -k Feed.forget.min.js
gzip -k Demo2.min.js
gzip -k Demo2.forget.min.js
@@ -1,35 +0,0 @@
{
"name": "react",
"version": "1.0.0",
"description": "React example starter project",
"keywords": [
"react",
"starter"
],
"main": "src/index.js",
"dependencies": {
"react": "17.0.2",
"react-dom": "17.0.2",
"react-scripts": "4.0.0",
"uglify-js": "^3.14.2"
},
"devDependencies": {
"@babel/cli": "^7.15.7",
"@babel/core": "^7.15.5",
"@babel/runtime": "7.13.8",
"typescript": "4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"forget": "./run-forget.sh"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
@@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
@@ -1,14 +0,0 @@
# this is so temporary otherwise we should use a makefile or at least a loop?
npx babel src/Feed.js --out-file src/Feed.forget.js
echo "import { useMemoCache } from \"./useMemoCache\"; \n$(cat src/Feed.forget.js)" > src/Feed.forget.js
npx babel src/Demo1.js --out-file src/Demo1.forget.js
echo "import { useMemoCache } from \"./useMemoCache\"; \n$(cat src/Demo1.forget.js)" > src/Demo1.forget.js
npx babel src/Demo2.js --out-file src/Demo2.forget.js
echo "import { useMemoCache } from \"./useMemoCache\"; \n$(cat src/Demo2.forget.js)" > src/Demo2.forget.js
-22
View File
@@ -1,22 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import Demo1 from "./Demo1";
import Demo1Forget from "./Demo1.forget.js";
import Demo2 from "./Demo2";
import Demo2Forget from "./Demo2.forget.js";
export default function App() {
return (
<>
<Demo1 />
{/* <Demo1Forget /> */}
{/* <Demo2 /> */}
{/* <Demo2Forget /> */}
</>
);
}
@@ -1,71 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { useState } from "react";
import "./styles.css";
import * as Feed from "./Feed";
import * as FeedMemoized from "./FeedMemoized";
import * as FeedForget from "./Feed.forget.js";
const mockServer = {
usePaginatedData() {
let $ = useMemoCache(3);
let [data, setData] = useState([]);
let c_data = $[1] !== data;
if (c_data) $[1] = data;
const loadNext = c_data ? $[2] = num => {
let newData = new Array(num).fill(0).map((_, idx) => ({
value: data.length + idx
}));
setData([...data, ...newData]);
} : $[2];
return {
data,
loadNext
};
}
};
export default function Demo1() {
let $ = useMemoCache(17);
let [text, setText] = useState("");
let c_text = $[1] !== text;
if (c_text) $[1] = text;
let {
data,
loadNext
} = mockServer.usePaginatedData();
let c_loadNext = $[3] !== loadNext;
if (c_loadNext) $[3] = loadNext;
let c_data = $[2] !== data;
if (c_data) $[2] = data;
return c_text || c_loadNext || c_data ? $[16] = <div className="App">
<h2>Demo1 - Feeds</h2>
{c_text || c_loadNext ? $[8] = <header className="Header row">
<div className="Icon">⚛️</div>
{
/* TODO: no need to memo for host component? */
}
{c_text ? $[5] = <input className="Search" placeholder="Search" value={text} onChange={$[4] || ($[4] = e => setText(e.target.value))} /> : $[5]}
{c_loadNext ? $[7] = <button className="Load" onClick={c_loadNext ? $[6] = e => loadNext(1) : $[6]}>
🎲
</button> : $[7]}
</header> : $[8]}
{c_data ? $[15] = <div className="Feeds row">
{c_data ? $[10] = <div className="column">
{c_data ? $[9] = <Feed.Feed items={data} /> : $[9]}
</div> : $[10]}
{c_data ? $[12] = <div className="column">
{c_data ? $[11] = <FeedMemoized.Feed items={data} /> : $[11]}
</div> : $[12]}
{c_data ? $[14] = <div className="column">
{c_data ? $[13] = <FeedForget.Feed items={data} /> : $[13]}
</div> : $[14]}
</div> : $[15]}
</div> : $[16];
}
@@ -1,64 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useState } from "react";
import "./styles.css";
import * as Feed from "./Feed";
import * as FeedMemoized from "./FeedMemoized";
import * as FeedForget from "./Feed.forget.js";
const mockServer = {
usePaginatedData() {
let [data, setData] = useState([]);
const loadNext = (num) => {
let newData = new Array(num)
.fill(0)
.map((_, idx) => ({ value: data.length + idx }));
setData([...data, ...newData]);
};
return { data, loadNext };
},
};
export default function Demo1() {
let [text, setText] = useState("");
let { data, loadNext } = mockServer.usePaginatedData();
return (
<div className="App">
<h2>Demo1 - Feeds</h2>
<header className="Header row">
<div className="Icon">⚛️</div>
{/* TODO: no need to memo for host component? */}
<input
className="Search"
placeholder="Search"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button className="Load" onClick={(e) => loadNext(1)}>
🎲
</button>
</header>
<div className="Feeds row">
<div className="column">
<Feed.Feed items={data} />
</div>
<div className="column">
<FeedMemoized.Feed items={data} />
</div>
<div className="column">
<FeedForget.Feed items={data} />
</div>
</div>
</div>
);
}
@@ -1,111 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { createContext, useRef, useReducer, useContext } from "react";
import "./styles.css";
const initialStore = {
left: undefined,
right: undefined
};
const reducer = (state, action) => {
switch (action.tag) {
case "left":
return { ...state,
left: action.payload
};
case "right":
return { ...state,
right: action.payload
};
default:
return state;
}
};
const BinaryContext = createContext(initialStore);
function Input(props) {
let $ = useMemoCache(2);
let prevProps = $[0];
let c_props = !prevProps || prevProps !== props;
if (c_props) $[0] = props;
let c_value = c_props && prevProps.value !== props.value;
let c_onChange = c_props && prevProps.onChange !== props.onChange;
return c_value || c_onChange ? $[1] = <input className="Search" placeholder="..." value={props.value} onChange={props.onChange} /> : $[1];
}
function Left() {
let $ = useMemoCache(9);
const [{
left
}, dispatch] = useContext(BinaryContext);
let c_dispatch = $[2] !== dispatch;
if (c_dispatch) $[2] = dispatch;
let c_left = $[1] !== left;
if (c_left) $[1] = left;
const rerenderCount = useRef(0);
return c_left || c_dispatch ? $[8] = <div className="column Demo2">
{c_left || c_dispatch ? $[5] = <header className="Header row">
<div className="Icon">⚛️</div>
{c_left || c_dispatch ? $[4] = <Input value={left} onChange={c_dispatch ? $[3] = e => dispatch({
tag: "left",
payload: e.target.value
}) : $[3]} /> : $[4]}
</header> : $[5]}
{c_left ? $[7] = <div className="Feed">
<h3>{rerenderCount.current++}</h3>
{c_left ? $[6] = <div className="FeedItem">{left}</div> : $[6]}
</div> : $[7]}
</div> : $[8];
}
function Right() {
let $ = useMemoCache(9);
const [{
right
}, dispatch] = useContext(BinaryContext);
let c_dispatch = $[2] !== dispatch;
if (c_dispatch) $[2] = dispatch;
let c_right = $[1] !== right;
if (c_right) $[1] = right;
const rerenderCount = useRef(0);
return c_right || c_dispatch ? $[8] = <div className="column Demo2">
{c_right || c_dispatch ? $[5] = <header className="Header row">
<div className="Icon">⚛️</div>
{c_right || c_dispatch ? $[4] = <Input value={right} onChange={c_dispatch ? $[3] = e => dispatch({
tag: "right",
payload: e.target.value
}) : $[3]} /> : $[4]}
</header> : $[5]}
{c_right ? $[7] = <div className="Feed">
<h3>{rerenderCount.current++}</h3>
{c_right ? $[6] = <div className="FeedItem">{right}</div> : $[6]}
</div> : $[7]}
</div> : $[8];
}
export default function Demo2() {
let $ = useMemoCache(4);
const [state, dispatch] = useReducer(reducer, initialStore);
let c_state = $[1] !== state;
if (c_state) $[1] = state;
const store = c_state ? $[2] = [state, dispatch] : $[2]; // const store = React.useMemo(() => [state, dispatch], [state]);
return c_state ? $[3] = <BinaryContext.Provider value={store}>
<div className="App">
<h2>Demo2 - Context</h2>
<div className="row">
<Left />
<Right />
</div>
</div>
</BinaryContext.Provider> : $[3];
}
@@ -1,96 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { createContext, useRef, useReducer, useContext } from "react";
import "./styles.css";
const initialStore = {
left: undefined,
right: undefined,
};
const reducer = (state, action) => {
switch (action.tag) {
case "left":
return { ...state, left: action.payload };
case "right":
return { ...state, right: action.payload };
default:
return state;
}
};
const BinaryContext = createContext(initialStore);
function Input({ value, onChange }) {
return (
<input
className="Search"
placeholder="..."
value={value}
onChange={onChange}
/>
);
}
function Left() {
const [{ left }, dispatch] = useContext(BinaryContext);
const rerenderCount = useRef(0);
return (
<div className="column Demo2">
<header className="Header row">
<div className="Icon">⚛️</div>
<Input
value={left}
onChange={(e) => dispatch({ tag: "left", payload: e.target.value })}
/>
</header>
<div className="Feed">
<h3>{rerenderCount.current++}</h3>
<div className="FeedItem">{left}</div>
</div>
</div>
);
}
function Right() {
const [{ right }, dispatch] = useContext(BinaryContext);
const rerenderCount = useRef(0);
return (
<div className="column Demo2">
<header className="Header row">
<div className="Icon">⚛️</div>
<Input
value={right}
onChange={(e) => dispatch({ tag: "right", payload: e.target.value })}
/>
</header>
<div className="Feed">
<h3>{rerenderCount.current++}</h3>
<div className="FeedItem">{right}</div>
</div>
</div>
);
}
export default function Demo2() {
const [state, dispatch] = useReducer(reducer, initialStore);
const store = [state, dispatch];
// const store = React.useMemo(() => [state, dispatch], [state]);
return (
<BinaryContext.Provider value={store}>
<div className="App">
<h2>Demo2 - Context</h2>
<div className="row">
<Left />
<Right />
</div>
</div>
</BinaryContext.Provider>
);
}
@@ -1,41 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { useRef } from "react";
function FeedItem(props) {
let $ = useMemoCache(2);
let prevProps = $[0];
let c_props = !prevProps || prevProps !== props;
if (c_props) $[0] = props;
let c_data = c_props && prevProps.data !== props.data;
let c_onClick = c_props && prevProps.onClick !== props.onClick;
const rerenderCount = useRef(0);
return c_data || c_onClick ? $[1] = <a href={`./item/${props.data.value}`} className="FeedItem" onClick={props.onClick}>
{rerenderCount.current++}
</a> : $[1];
}
export function Feed(props) {
let $ = useMemoCache(3);
let prevProps = $[0];
let c_props = !prevProps || prevProps !== props;
if (c_props) $[0] = props;
let c_items = c_props && prevProps.items !== props.items;
const rerenderCount = useRef(0);
const onClick = $[1] || ($[1] = e => {
e.preventDefault();
alert(e.target.href);
});
return c_items ? $[2] = <div className="Feed">
<h3>{rerenderCount.current++}</h3>
{props.items.map((item, index) => <FeedItem key={index} data={item} onClick={onClick} />)}
</div> : $[2];
}
-35
View File
@@ -1,35 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useRef } from "react";
function FeedItem({ data, onClick }) {
const rerenderCount = useRef(0);
return (
<a href={`./item/${data.value}`} className="FeedItem" onClick={onClick}>
{rerenderCount.current++}
</a>
);
}
export function Feed({ items }) {
const rerenderCount = useRef(0);
const onClick = (e) => {
e.preventDefault();
alert(e.target.href);
};
return (
<div className="Feed">
<h3>{rerenderCount.current++}</h3>
{items.map((item, index) => (
<FeedItem key={index} data={item} onClick={onClick} />
))}
</div>
);
}
@@ -1,37 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useRef, useCallback } from "react";
function FeedItem({ data, onClick }) {
const rerenderCount = useRef(0);
return (
<a href={`./item/${data.value}`} className="FeedItem" onClick={onClick}>
{rerenderCount.current++}
</a>
);
}
const FeedItemMemoized = React.memo(FeedItem);
export const Feed = React.memo(({ items }) => {
const rerenderCount = useRef(0);
const onClick = useCallback((e) => {
e.preventDefault();
alert(e.target.href);
}, []);
return (
<div className="Feed">
<h3>{rerenderCount.current++}</h3>
{items.map((item, index) => (
<FeedItemMemoized key={index} data={item} onClick={onClick} />
))}
</div>
);
});
@@ -1,19 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
rootElement
);
@@ -1,99 +0,0 @@
body {
background-color: #f0f2f5;
padding: 0;
margin: 0;
}
.App {
font-family: -apple-system, BlinkMacSystemFont;
text-align: center;
}
.Header {
box-sizing: border-box;
position: fixed;
width: 100%;
height: 72px;
line-height: 72px;
background-color: white;
padding: 0 12px;
}
.Demo2 {
padding: 16px;
}
.Demo2 .Header {
position: relative;
}
.Demo2 .Feeds {
padding-top: 16px;
}
.Feeds {
padding: 16px;
padding-top: 72px;
}
.Icon {
font-size: 2em;
font-weight: 800;
margin: 0 12px;
}
.Search {
flex: 1;
padding: 16px;
margin: 12px;
border-radius: 50px;
outline: none;
border: none;
background-color: rgb(240, 242, 245);
}
.Load {
margin: 12px;
width: 48px;
height: 48px;
border-radius: 50%;
outline: none;
border: none;
background-color: rgb(240, 242, 245);
}
.Feed {
padding: 16px;
}
.FeedItem {
display: block;
width: 100%;
height: 64px;
line-height: 64px;
background-color: rgb(14, 165, 233);
color: white;
border-radius: 6px;
font-weight: 900;
margin-bottom: 16px;
}
.FeedItem.large {
height: 80px;
line-height: 80px;
}
.FeedItem.small {
height: 64px;
line-height: 64px;
}
.row {
display: flex;
}
.column {
display: flex;
flex-direction: column;
flex: 1;
}
@@ -1,15 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useRef } from "react";
const placeholder = NaN;
export function useMemoCache(i) {
const ref = useRef(new Array(i).fill(placeholder));
return ref.current;
}
File diff suppressed because it is too large Load Diff
@@ -1,3 +0,0 @@
{
"plugins": ["../../"]
}
@@ -1 +0,0 @@
SKIP_PREFLIGHT_CHECK=true
@@ -1,21 +0,0 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -1,24 +0,0 @@
# React Forget Demo - Todo List Live
This is a "cleaned up" verison of Todolist used in React Conf 2021 "live demo".
## Get Started
This is a Create-React-App project.
## Structure
- `forget` - a CLI driver to call the compiler from `../`
- `index.js` - the entry point of demo
- `source` - source dir
- `compiled` - output dir
### Compile
```
# npm
npm run forget
# yarn
yarn forget
```
@@ -1,58 +0,0 @@
#!/bin/bash
#############################################################
#
# Forget Shell Driver
#
# Usage:
# $ forget <src> <dist>
#
#############################################################
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
function cleanup() {
for file in "$1"/*
do
file=$file;
fullname="$(basename $file)"
name="${fullname%*.}"
if [ "$name" != "useMemoCache.js" ]; then
echo "[Forget] cleanup: ${file}"
rm $file
fi
done
}
function traverse() {
for file in "$1"/*
do
dir="$(dirname $file)"
fullname="$(basename $file)"
ext="${fullname##*.}"
name="${fullname%.*}"
maybeExt="${name##*.}"
# echo "dir=$dir"
# echo "file=$file"
# echo "fullname=$fullname"
# echo "name=$name"
# echo "ext=$ext"
# echo "maybeExt=$maybeExt"
source=$file;
output="${2}/${fullname}"
if [ "$maybeExt" != "memo" ]; then
echo "[Forget] compile: ${source} -> ${output}"
npx babel ${source} --out-file ${output};
before=$(cat ${output})
echo -e "import { useMemoCache } from \"./useMemoCache\";\n${before}" > $output
fi
done
}
cleanup "$2"
traverse "$1" "$2"
@@ -1,32 +0,0 @@
{
"name": "react-doc-todo",
"main": "src/index.js",
"dependencies": {
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-scripts": "^4.0.0"
},
"version": "0.0.0",
"devDependencies": {
"@babel/cli": "^7.15.7",
"@babel/core": "^7.15.5",
"@babel/runtime": "7.13.8",
"babel-preset-react-app": "^10.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"forget": "./forget src/source src/compiled"
},
"prettier": {
"arrowParens": "avoid"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

@@ -1,38 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
@@ -1,15 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
@@ -1,53 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { useState } from "react";
export default function AddTodo({
setTodos,
themeColor = "#045975"
}) {
let $ = useMemoCache(13);
let c_setTodos = $[0] !== setTodos;
if (c_setTodos) $[0] = setTodos;
let c_themeColor = $[1] !== themeColor;
if (c_themeColor) $[1] = themeColor;
const [text, setText] = useState(defaultTodo);
let c_text = $[2] !== text;
if (c_text) $[2] = text;
const handleAddTodo = c_setTodos ? $[3] = text => {
setTodos(ts => [...ts, {
id: nextId++,
text: text,
done: false
}]);
} : $[3];
const bgGradient = c_themeColor ? $[4] = `linear-gradient(
209.21deg,
${themeColor}22 0%,
${themeColor}ee 100%
)` : $[4];
return c_text || c_setTodos || c_themeColor ? $[12] = <div className="AddTodo">
{c_text || c_setTodos || c_themeColor ? $[11] = <form onSubmit={c_text || c_setTodos ? $[5] = e => {
e.preventDefault();
setText(defaultTodo);
handleAddTodo(text.trim() === "" ? fallbackTodo : text);
} : $[5]}>
{c_text ? $[7] = <input placeholder="Add todo" value={text} onChange={$[6] || ($[6] = e => setText(e.target.value))} /> : $[7]}
{c_themeColor ? $[10] = <div className="tail">
{c_themeColor ? $[9] = <button type="submit" style={c_themeColor ? $[8] = {
background: bgGradient
} : $[8]}>
Add
</button> : $[9]}
</div> : $[10]}
</form> : $[11]}
</div> : $[12];
}
let nextId = 3;
const defaultTodo = "";
const fallbackTodo = "oops";
@@ -1,83 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import getUpdated from "../utils/getUpdated";
import getFiltered from "../utils/getFiltered";
import initialTodos from "../utils/InitialTodos";
import ColorPicker from "../utils/ColorPicker";
import CountBadge from "../utils/CountBadge";
import React, { useState, useRef } from "react";
import Select from "../utils/Select";
import Todo from "./Todo";
import AddTodo from "./AddTodo";
function TodoList({
visibility,
themeColor
}) {
let $ = useMemoCache(8);
let c_visibility = $[0] !== visibility;
if (c_visibility) $[0] = visibility;
let c_themeColor = $[1] !== themeColor;
if (c_themeColor) $[1] = themeColor;
const [todos, setTodos] = useState(initialTodos);
let c_todos = $[2] !== todos;
if (c_todos) $[2] = todos;
const handleChange = $[3] || ($[3] = todo => setTodos(todos => getUpdated(todos, todo)));
const filtered = c_todos || c_visibility ? $[4] = getFiltered(todos, visibility) : $[4];
return c_todos || c_visibility || c_themeColor ? $[7] = <div>
{c_todos || c_visibility ? $[5] = <ul>
{filtered.map(todo => <Todo key={todo.id} todo={todo} onChange={handleChange} />)}
</ul> : $[5]}
{c_themeColor ? $[6] = <AddTodo setTodos={setTodos} themeColor={themeColor} /> : $[6]}
</div> : $[7];
}
export default function BlazingTodoList() {
let $ = useMemoCache(14);
const [themeColor, setThemeColor] = useState("#045975");
let c_themeColor = $[0] !== themeColor;
if (c_themeColor) $[0] = themeColor;
const [visibility, setVisibility] = useState("all");
let c_visibility = $[1] !== visibility;
if (c_visibility) $[1] = visibility;
const bgGradient = c_themeColor ? $[2] = `linear-gradient(
209.21deg,
rgb(8, 126, 164) 13.57%,
${themeColor} 98.38%
)` : $[2];
return c_themeColor || c_visibility ? $[13] = <div className="column Neo">
{c_themeColor || c_visibility ? $[12] = <div className="TodoListApp" style={c_themeColor ? $[3] = {
background: bgGradient
} : $[3]}>
<div className="FilterCountBanner">
<code>getFiltered()</code> was called
<CountBadge />
times
</div>
{c_themeColor || c_visibility ? $[10] = <header>
{c_themeColor ? $[5] = <ColorPicker value={themeColor} onChange={$[4] || ($[4] = e => setThemeColor(e.target.value))} /> : $[5]}
{c_visibility ? $[9] = <div className="VisibilityFilter">
{c_visibility ? $[8] = <Select value={visibility} options={$[6] || ($[6] = [{
value: "all",
label: "All"
}, {
value: "active",
label: "Active"
}, {
value: "completed",
label: "Completed"
}])} onChange={$[7] || ($[7] = value => setVisibility(value))} /> : $[8]}
</div> : $[9]}
</header> : $[10]}
{c_visibility || c_themeColor ? $[11] = <TodoList visibility={visibility} themeColor={themeColor} /> : $[11]}
</div> : $[12]}
</div> : $[13];
}
@@ -1,50 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useMemoCache } from "./useMemoCache";
import React, { useState, useRef } from "react";
import CountBadge from "../utils/CountBadge";
export default function Todo({
todo,
onChange
}) {
let $ = useMemoCache(7);
let c_todo = $[0] !== todo;
if (c_todo) $[0] = todo;
let c_onChange = $[1] !== onChange;
if (c_onChange) $[1] = onChange;
const inputRef = useRef(null);
const count = useRef(0);
const [isEditing, setIsEditing] = useState(false);
let c_isEditing = $[2] !== isEditing;
if (c_isEditing) $[2] = isEditing;
const onSave = c_onChange || c_todo ? $[3] = e => {
e.preventDefault();
setIsEditing(false);
onChange({ ...todo,
text: inputRef.current.value
});
} : $[3];
const checkBox = c_isEditing || c_todo || c_onChange ? $[4] = !isEditing && <button className={todo.done ? "Checkbox done" : "Checkbox"} onClick={e => {
e.target.blur();
onChange({ ...todo,
done: !todo.done
});
}}></button> : $[4];
const todoBody = c_isEditing || c_todo || c_onChange ? $[5] = isEditing ? <form value={todo.text} onSubmit={onSave} onBlur={onSave}>
<input ref={inputRef} defaultValue={todo.text} autoFocus />
</form> : <div className={"TodoBody" + (todo.done ? " done" : "")} onClick={() => setIsEditing(true)}>
{todo.text}
</div> : $[5];
return c_isEditing || c_todo || c_onChange ? $[6] = <li className="Todo">
{checkBox}
{todoBody}
<div className="tail">
<CountBadge count={count.current++} type={"warning"} rounded />
</div>
</li> : $[6];
}
@@ -1,15 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useRef } from "react";
const placeholder = NaN;
export function useMemoCache(i) {
const ref = useRef(new Array(i).fill(placeholder));
return ref.current;
}
@@ -1,59 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.
export default function register() {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
navigator.serviceWorker
.register(swUrl)
.then(registration => {
// eslint-disable-next-line no-param-reassign
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('New content is available; please refresh.'); // eslint-disable-line no-console
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.'); // eslint-disable-line no-console
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
});
}
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}
@@ -1,22 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { StrictMode } from "react";
import ReactDOM from "react-dom";
import "./normalize.css";
import "./styles.css";
// import BlazingTodoList from "./source/BlazingTodoList";
import BlazingTodoList from "./compiled/BlazingTodoList";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<BlazingTodoList />
</StrictMode>,
rootElement
);
-351
View File
@@ -1,351 +0,0 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
/* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
/* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}
@@ -1,11 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
@@ -1,55 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useState } from "react";
export default function AddTodo({ setTodos, themeColor = "#045975" }) {
const [text, setText] = useState(defaultTodo);
const handleAddTodo = text => {
setTodos(ts => [
...ts,
{
id: nextId++,
text: text,
done: false,
},
]);
};
const bgGradient = `linear-gradient(
209.21deg,
${themeColor}22 0%,
${themeColor}ee 100%
)`;
return (
<div className="AddTodo">
<form
onSubmit={e => {
e.preventDefault();
setText(defaultTodo);
handleAddTodo(text.trim() === "" ? fallbackTodo : text);
}}
>
<input
placeholder="Add todo"
value={text}
onChange={e => setText(e.target.value)}
/>
<div className="tail">
<button type="submit" style={{ background: bgGradient }}>
Add
</button>
</div>
</form>
</div>
);
}
let nextId = 3;
const defaultTodo = "";
const fallbackTodo = "oops";
@@ -1,74 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import getUpdated from "../utils/getUpdated";
import getFiltered from "../utils/getFiltered";
import initialTodos from "../utils/InitialTodos";
import ColorPicker from "../utils/ColorPicker";
import CountBadge from "../utils/CountBadge";
import React, { useState, useRef } from "react";
import Select from "../utils/Select";
import Todo from "./Todo";
import AddTodo from "./AddTodo";
function TodoList({ visibility, themeColor }) {
const [todos, setTodos] = useState(initialTodos);
const handleChange = todo => setTodos(todos => getUpdated(todos, todo));
const filtered = getFiltered(todos, visibility);
return (
<div>
<ul>
{filtered.map(todo => (
<Todo key={todo.id} todo={todo} onChange={handleChange} />
))}
</ul>
<AddTodo setTodos={setTodos} themeColor={themeColor} />
</div>
);
}
export default function BlazingTodoList() {
const [themeColor, setThemeColor] = useState("#045975");
const [visibility, setVisibility] = useState("all");
const bgGradient = `linear-gradient(
209.21deg,
rgb(8, 126, 164) 13.57%,
${themeColor} 98.38%
)`;
return (
<div className="column Neo">
<div className="TodoListApp" style={{ background: bgGradient }}>
<div className="FilterCountBanner">
<code>getFiltered()</code> was called
<CountBadge />
times
</div>
<header>
<ColorPicker
value={themeColor}
onChange={e => setThemeColor(e.target.value)}
/>
<div className="VisibilityFilter">
<Select
value={visibility}
options={[
{ value: "all", label: "All" },
{ value: "active", label: "Active" },
{ value: "completed", label: "Completed" },
]}
onChange={value => setVisibility(value)}
/>
</div>
</header>
<TodoList visibility={visibility} themeColor={themeColor} />
</div>
</div>
);
}
@@ -1,60 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useState, useRef } from "react";
import CountBadge from "../utils/CountBadge";
export default function Todo({ todo, onChange }) {
const inputRef = useRef(null);
const count = useRef(0);
const [isEditing, setIsEditing] = useState(false);
const onSave = e => {
e.preventDefault();
setIsEditing(false);
onChange({
...todo,
text: inputRef.current.value,
});
};
const checkBox = !isEditing && (
<button
className={todo.done ? "Checkbox done" : "Checkbox"}
onClick={e => {
e.target.blur();
onChange({
...todo,
done: !todo.done,
});
}}
></button>
);
const todoBody = isEditing ? (
<form value={todo.text} onSubmit={onSave} onBlur={onSave}>
<input ref={inputRef} defaultValue={todo.text} autoFocus />
</form>
) : (
<div
className={"TodoBody" + (todo.done ? " done" : "")}
onClick={() => setIsEditing(true)}
>
{todo.text}
</div>
);
return (
<li className="Todo">
{checkBox}
{todoBody}
<div className="tail">
<CountBadge count={count.current++} type={"warning"} rounded />
</div>
</li>
);
}
@@ -1,376 +0,0 @@
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
margin: 20px;
padding: 0;
/* React dark bg */
background-color: #24272e;
}
h1 {
margin-top: 0;
font-size: 22px;
}
h2 {
margin-top: 0;
font-size: 20px;
}
h3 {
margin-top: 0;
font-size: 18px;
}
h4 {
margin-top: 0;
font-size: 16px;
}
h5 {
margin-top: 0;
font-size: 14px;
}
h6 {
margin-top: 0;
font-size: 12px;
}
ul {
padding-left: 20px;
}
button {
margin: 5px;
}
li {
list-style-type: none;
}
ul,
li {
margin: 0;
padding: 0;
}
.row {
display: flex;
}
.column {
flex-direction: column;
flex: 1;
padding: 32px;
display: flex;
align-items: center;
}
.TodoListApp {
transform: scale(1.05);
transform-origin: top;
}
/* copy from neo.css */
.Neo {
font-family: "Optimistic Display App", "Open Sans", -apple-system,
BlinkMacSystemFont, "Helvetica Neue", sans-serif !important;
}
.Neo code {
font-family: "Iosevka SS05";
padding-right: 6px;
}
.TodoListApp {
min-width: 320px;
max-width: 320px;
position: relative;
/* overflow: hidden; */
color: white;
padding: 16px;
border-radius: 24px;
margin-top: 96px;
/* for Neo1 */
background: linear-gradient(
209.21deg,
rgb(8, 126, 164) 13.57%,
rgb(4, 89, 117) 98.38%
);
box-shadow: 0px 0.8px 2px rgba(0, 0, 0, 0.032),
0px 2.7px 6.7px rgba(0, 0, 0, 0.048), 0px 12px 30px rgba(0, 0, 0, 0.08);
}
.TodoListApp header {
height: auto;
position: relative;
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 12px;
}
.TodoListApp .FilterCountBanner {
display: flex;
align-items: center;
justify-content: center;
color: #fffc;
font-size: 14.5px;
height: 40px;
position: absolute;
width: 100%;
left: 0;
top: -40px;
}
.TodoListApp .FilterCountBanner .badge {
margin: 0 6px;
}
input[type="color"].ColorPicker {
width: auto;
height: 40px;
border: none;
cursor: pointer;
background-color: transparent;
border-radius: 50%;
display: flex;
align-items: center;
margin-right: 10px;
}
input[type="color"]::-webkit-color-swatch-wrapper {
width: 34px;
height: 34px;
padding: 0;
border-radius: 50%;
}
input[type="color"]::-webkit-color-swatch {
border: none;
border-radius: 50%;
}
.ColorPicker span {
line-height: 32px;
position: absolute;
top: 0;
right: 6px;
font-size: 14px;
/* click through */
pointer-events: none;
}
.AddTodo,
.Todo,
.VisibilityFilter {
transition: background-color 0.3s ease;
display: flex;
align-items: center;
border-radius: 24px;
font-size: 17px;
color: #fffd;
background-color: #0001;
padding: 0px 18px;
min-height: 56px;
margin-bottom: 12px;
flex-wrap: nowrap;
}
.VisibilityFilter {
min-height: auto;
margin: 0px;
padding: 0 12px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
}
.AddTodo {
margin-bottom: 0px;
}
/* .Todo:last-of-type {
margin-bottom: 0px;
} */
.Todo:hover,
.AddTodo:hover {
background-color: #0002;
}
.Todo:focus-within,
.AddTodo:focus-within {
background-color: #0003;
box-shadow: rgb(255 255 255 / 20%) 0px 0px 0px 0.5px inset;
}
.Todo input,
.AddTodo input {
width: 100%;
flex: 1 1;
color: rgb(235, 236, 240);
background-color: transparent;
border: none;
outline: 0px;
}
.Todo input,
.Todo .TodoBody,
.AddTodo input {
padding: 18px 0;
}
.Select {
display: flex;
justify-content: space-evenly;
flex: 1;
align-items: center;
flex-wrap: nowrap;
border: none;
border-radius: 18px;
}
.AddTodo button,
.Select button {
cursor: pointer;
height: 40px;
width: auto;
border: none;
border-radius: 18px;
padding: 0 14px;
transition: all 0.3s ease;
color: #fffb;
margin-right: -9px;
/* For Neo1 */
background: linear-gradient(
209.21deg,
rgba(4, 89, 117, 0.133) 0%,
rgba(4, 89, 117, 0.933) 100%
);
box-shadow: rgb(255 255 255 / 20%) 0px 0px 0px 0.5px inset,
rgb(23 0 102 / 20%) 0px 20px 40px, rgb(0 0 0 / 10%) 0px 1px 3px;
}
.Select button {
margin: 0;
background: transparent;
box-shadow: none;
color: #fff7;
font-size: 14.5px;
padding: 0 4px;
}
.Select button.selected {
color: #fffc;
}
.Select button:hover {
color: #fffc;
}
.AddTodo button:hover {
color: #fffc;
box-shadow: rgb(255 255 255 / 20%) 0px 0px 0px 0.5px inset,
rgb(23 0 102 / 30%) 0px 40px 80px, rgb(0 0 0 / 30%) 0px 10px 30px;
}
.AddTodo form,
.Todo form,
.Todo .TodoBody {
display: flex;
cursor: pointer;
flex: 1;
align-items: center;
overflow-wrap: anywhere;
}
.AddTodo input::placeholder {
color: #fff7;
}
.Todo .done {
text-decoration: line-through;
font-style: italic;
color: #fff7;
}
.Todo .Checkbox {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 22px;
height: 22px;
padding: 0px;
border: none;
cursor: pointer;
background-color: transparent;
border-radius: 50%;
border: 0.5px solid #fff3;
margin: 0px;
margin-right: 12px;
}
.Todo .Checkbox.done {
border: 0.5px solid #fff5;
}
.Todo .Checkbox.done::after {
content: "";
width: 16px;
height: 16px;
position: absolute;
border-radius: 50%;
background-color: #fffc;
}
.tail {
margin-left: 8px;
justify-content: flex-end;
}
.VisibilityFilter {
flex: 1;
}
.VisibilityFilter .tail {
margin-left: 0px;
display: flex;
}
/*
* https://getbootstrap.com/docs/5.1/components/badge/
*/
.badge {
/* so width won't change when bumping. */
font-family: "Iosevka SS05", menlo, monospace;
display: inline-block;
padding: 0.35em 0.65em;
font-size: 13.5px;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 0.25rem;
}
.rounded-pill {
border-radius: 50rem !important;
}
.badge-danger {
color: #fff;
background-color: #dc3545;
}
.badge-warning {
color: #212529;
background-color: #ffc107;
}
@@ -1,19 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default function ColorPicker({ value, onChange }) {
return (
<input
className="ColorPicker"
type="color"
id="head"
name="head"
value={value}
onChange={onChange}
/>
);
}
@@ -1,24 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { forwardRef } from "react";
// Capped to 3 digits
const CountBadge = forwardRef(
({ count = 0, type = "danger", rounded = false }, ref) => {
return (
<span
ref={ref}
className={`badge ${rounded && "rounded-pill"} badge-${type}`}
>
{count > 999 ? 999 : count}
</span>
);
}
);
export default CountBadge;
@@ -1,14 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const initialTodos = [
{ id: 0, text: "memo", done: true },
{ id: 1, text: "useCallback", done: false },
{ id: 2, text: "useMemo", done: false },
];
export default initialTodos;
@@ -1,29 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default function Select({ value, options, onChange }) {
return (
<div className="Select">
{options.map(o => {
if (value === o.value) {
return (
<button key={o.value} className="selected">
{" "}
{o.label}{" "}
</button>
);
} else {
return (
<button key={o.value} onClick={() => onChange(o.value)}>
{o.label}
</button>
);
}
})}
</div>
);
}
@@ -1,28 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function delay() {
let now = performance.now();
while (performance.now() - now < 16) {
// Artificial delay -- do nothing for 100ms
}
}
export default function getFiltered(todos, visibility) {
//delay()
// This only works when there is only one counter unfortunately...
const $filterCountBadge = document.querySelector(".FilterCountBanner .badge");
if ($filterCountBadge)
$filterCountBadge.textContent = parseInt($filterCountBadge.textContent) + 1;
switch (visibility) {
case "all":
return todos;
case "active":
return todos.filter(t => !t.done);
case "completed":
return todos.filter(t => t.done);
}
}
@@ -1,18 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default function getUpdated(tasks, newTodo) {
return tasks
.map(t => {
if (t.id === newTodo.id) {
return newTodo;
} else {
return t;
}
})
.filter(t => !!t.text);
}
File diff suppressed because it is too large Load Diff
@@ -1,13 +0,0 @@
{
"presets": [
[
"next/babel",
{
"preset-env": {
"exclude": ["transform-block-scoping"]
}
}
]
],
"plugins": [["../../", { "optIn": true }]]
}
@@ -1,3 +0,0 @@
{
"extends": "next/core-web-vitals"
}
@@ -1,35 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
@@ -1,34 +0,0 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
@@ -1,56 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use forget";
import React, { useState } from "react";
export default function AddTodo({ setTodos, themeColor = "#045975" }) {
const [text, setText] = useState(defaultTodo);
const handleAddTodo = (text) => {
setTodos((ts) => [
...ts,
{
id: nextId++,
text: text,
done: false,
},
]);
};
const bgGradient = `linear-gradient(
209.21deg,
${themeColor}22 0%,
${themeColor}ee 100%
)`;
return (
<div className="AddTodo">
<form
onSubmit={(e) => {
e.preventDefault();
setText(defaultTodo);
handleAddTodo(text.trim() === "" ? fallbackTodo : text);
}}
>
<input
placeholder="Add todo"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<div className="tail">
<button type="submit" style={{ background: bgGradient }}>
Add
</button>
</div>
</form>
</div>
);
}
let nextId = 3;
const defaultTodo = "";
const fallbackTodo = "oops";
@@ -1,75 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use forget";
import getUpdated from "../utils/getUpdated";
import getFiltered from "../utils/getFiltered";
import initialTodos from "../utils/InitialTodos";
import ColorPicker from "../utils/ColorPicker";
import CountBadge from "../utils/CountBadge";
import React, { useState } from "react";
import Select from "../utils/Select";
import Todo from "./Todo";
import AddTodo from "./AddTodo";
function TodoList({ visibility, themeColor }) {
const [todos, setTodos] = useState(initialTodos);
const handleChange = (todo) => setTodos((todos) => getUpdated(todos, todo));
let filtered = [];
for (const todo of getFiltered(todos, visibility)) {
filtered.push(<Todo key={todo.id} todo={todo} onChange={handleChange} />);
}
return (
<div>
<ul>{filtered}</ul>
<AddTodo setTodos={setTodos} themeColor={themeColor} />
</div>
);
}
export default function BlazingTodoList() {
const [themeColor, setThemeColor] = useState("#045975");
const [visibility, setVisibility] = useState("all");
const bgGradient = `linear-gradient(
209.21deg,
rgb(8, 126, 164) 13.57%,
${themeColor} 98.38%
)`;
return (
<div className="column Neo">
<div className="TodoListApp" style={{ background: bgGradient }}>
<div className="FilterCountBanner">
<code>getFiltered()</code> was called
<CountBadge />
times
</div>
<header>
<ColorPicker
value={themeColor}
onChange={(e) => setThemeColor(e.target.value)}
/>
<div className="VisibilityFilter">
<Select
value={visibility}
options={[
{ value: "all", label: "All" },
{ value: "active", label: "Active" },
{ value: "completed", label: "Completed" },
]}
onChange={(value) => setVisibility(value)}
/>
</div>
</header>
<TodoList visibility={visibility} themeColor={themeColor} />
</div>
</div>
);
}
@@ -1,66 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
"use forget";
import React, { useState, useRef } from "react";
import CountBadge from "../utils/CountBadge";
export default function Todo({ todo, onChange }) {
const inputRef = useRef(null);
const count = useRef(0);
const [isEditing, setIsEditing] = useState(false);
const onSave = (e) => {
e.preventDefault();
setIsEditing(false);
onChange({
...todo,
text: inputRef.current.value,
});
};
const checkBox = !isEditing && (
<button
className={todo.done ? "Checkbox done" : "Checkbox"}
onClick={(e) => {
e.target.blur();
onChange({
...todo,
done: !todo.done,
});
}}
></button>
);
let todoBody;
if (isEditing) {
todoBody = (
<form value={todo.text} onSubmit={onSave} onBlur={onSave}>
<input ref={inputRef} defaultValue={todo.text} autoFocus />
</form>
);
} else {
todoBody = (
<div
className={"TodoBody" + (todo.done ? " done" : "")}
onClick={() => setIsEditing(true)}
>
{todo.text}
</div>
);
}
return (
<li className="Todo">
{checkBox}
{todoBody}
<div className="tail">
<CountBadge count={count.current++} type={"warning"} rounded />
</div>
</li>
);
}
@@ -1,12 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const nextConfig = {
reactStrictMode: true,
}
module.exports = nextConfig
@@ -1,20 +0,0 @@
{
"name": "demo-todolist-next",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "12.1.0",
"react": "17.0.2",
"react-dom": "17.0.2"
},
"devDependencies": {
"eslint": "8.10.0",
"eslint-config-next": "12.1.0"
}
}
@@ -1,20 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import "../styles/normalize.css";
import "../styles/styles.css";
// Monkeypatch useMemoCache
import React from "react";
import { useMemoCache } from "../utils/useMemoCache";
React.useMemoCache = useMemoCache;
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
@@ -1,12 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
@@ -1,12 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import BlazingTodoList from "../components/BlazingTodoList";
export default function Home() {
return <BlazingTodoList />;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

@@ -1,4 +0,0 @@
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,116 +0,0 @@
.container {
padding: 0 2rem;
}
.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.footer {
display: flex;
flex: 1;
padding: 2rem 0;
border-top: 1px solid #eaeaea;
justify-content: center;
align-items: center;
}
.footer a {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
.title a {
color: #0070f3;
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.title {
margin: 0;
line-height: 1.15;
font-size: 4rem;
}
.title,
.description {
text-align: center;
}
.description {
margin: 4rem 0;
line-height: 1.5;
font-size: 1.5rem;
}
.code {
background: #fafafa;
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 800px;
}
.card {
margin: 1rem;
padding: 1.5rem;
text-align: left;
color: inherit;
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
max-width: 300px;
}
.card:hover,
.card:focus,
.card:active {
color: #0070f3;
border-color: #0070f3;
}
.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
.logo {
height: 1em;
margin-left: 0.5rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}
@@ -1,16 +0,0 @@
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
* {
box-sizing: border-box;
}
@@ -1,351 +0,0 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input {
/* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select {
/* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}
@@ -1,376 +0,0 @@
* {
box-sizing: border-box;
}
body {
font-family: sans-serif;
margin: 20px;
padding: 0;
/* React dark bg */
background-color: #24272e;
}
h1 {
margin-top: 0;
font-size: 22px;
}
h2 {
margin-top: 0;
font-size: 20px;
}
h3 {
margin-top: 0;
font-size: 18px;
}
h4 {
margin-top: 0;
font-size: 16px;
}
h5 {
margin-top: 0;
font-size: 14px;
}
h6 {
margin-top: 0;
font-size: 12px;
}
ul {
padding-left: 20px;
}
button {
margin: 5px;
}
li {
list-style-type: none;
}
ul,
li {
margin: 0;
padding: 0;
}
.row {
display: flex;
}
.column {
flex-direction: column;
flex: 1;
padding: 32px;
display: flex;
align-items: center;
}
.TodoListApp {
transform: scale(1.05);
transform-origin: top;
}
/* copy from neo.css */
.Neo {
font-family: "Optimistic Display App", "Open Sans", -apple-system,
BlinkMacSystemFont, "Helvetica Neue", sans-serif !important;
}
.Neo code {
font-family: "Iosevka SS05";
padding-right: 6px;
}
.TodoListApp {
min-width: 320px;
max-width: 320px;
position: relative;
/* overflow: hidden; */
color: white;
padding: 16px;
border-radius: 24px;
margin-top: 96px;
/* for Neo1 */
background: linear-gradient(
209.21deg,
rgb(8, 126, 164) 13.57%,
rgb(4, 89, 117) 98.38%
);
box-shadow: 0px 0.8px 2px rgba(0, 0, 0, 0.032),
0px 2.7px 6.7px rgba(0, 0, 0, 0.048), 0px 12px 30px rgba(0, 0, 0, 0.08);
}
.TodoListApp header {
height: auto;
position: relative;
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 12px;
}
.TodoListApp .FilterCountBanner {
display: flex;
align-items: center;
justify-content: center;
color: #fffc;
font-size: 14.5px;
height: 40px;
position: absolute;
width: 100%;
left: 0;
top: -40px;
}
.TodoListApp .FilterCountBanner .badge {
margin: 0 6px;
}
input[type="color"].ColorPicker {
width: auto;
height: 40px;
border: none;
cursor: pointer;
background-color: transparent;
border-radius: 50%;
display: flex;
align-items: center;
margin-right: 10px;
}
input[type="color"]::-webkit-color-swatch-wrapper {
width: 34px;
height: 34px;
padding: 0;
border-radius: 50%;
}
input[type="color"]::-webkit-color-swatch {
border: none;
border-radius: 50%;
}
.ColorPicker span {
line-height: 32px;
position: absolute;
top: 0;
right: 6px;
font-size: 14px;
/* click through */
pointer-events: none;
}
.AddTodo,
.Todo,
.VisibilityFilter {
transition: background-color 0.3s ease;
display: flex;
align-items: center;
border-radius: 24px;
font-size: 17px;
color: #fffd;
background-color: #0001;
padding: 0px 18px;
min-height: 56px;
margin-bottom: 12px;
flex-wrap: nowrap;
}
.VisibilityFilter {
min-height: auto;
margin: 0px;
padding: 0 12px;
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
}
.AddTodo {
margin-bottom: 0px;
}
/* .Todo:last-of-type {
margin-bottom: 0px;
} */
.Todo:hover,
.AddTodo:hover {
background-color: #0002;
}
.Todo:focus-within,
.AddTodo:focus-within {
background-color: #0003;
box-shadow: rgb(255 255 255 / 20%) 0px 0px 0px 0.5px inset;
}
.Todo input,
.AddTodo input {
width: 100%;
flex: 1 1;
color: rgb(235, 236, 240);
background-color: transparent;
border: none;
outline: 0px;
}
.Todo input,
.Todo .TodoBody,
.AddTodo input {
padding: 18px 0;
}
.Select {
display: flex;
justify-content: space-evenly;
flex: 1;
align-items: center;
flex-wrap: nowrap;
border: none;
border-radius: 18px;
}
.AddTodo button,
.Select button {
cursor: pointer;
height: 40px;
width: auto;
border: none;
border-radius: 18px;
padding: 0 14px;
transition: all 0.3s ease;
color: #fffb;
margin-right: -9px;
/* For Neo1 */
background: linear-gradient(
209.21deg,
rgba(4, 89, 117, 0.133) 0%,
rgba(4, 89, 117, 0.933) 100%
);
box-shadow: rgb(255 255 255 / 20%) 0px 0px 0px 0.5px inset,
rgb(23 0 102 / 20%) 0px 20px 40px, rgb(0 0 0 / 10%) 0px 1px 3px;
}
.Select button {
margin: 0;
background: transparent;
box-shadow: none;
color: #fff7;
font-size: 14.5px;
padding: 0 4px;
}
.Select button.selected {
color: #fffc;
}
.Select button:hover {
color: #fffc;
}
.AddTodo button:hover {
color: #fffc;
box-shadow: rgb(255 255 255 / 20%) 0px 0px 0px 0.5px inset,
rgb(23 0 102 / 30%) 0px 40px 80px, rgb(0 0 0 / 30%) 0px 10px 30px;
}
.AddTodo form,
.Todo form,
.Todo .TodoBody {
display: flex;
cursor: pointer;
flex: 1;
align-items: center;
overflow-wrap: anywhere;
}
.AddTodo input::placeholder {
color: #fff7;
}
.Todo .done {
text-decoration: line-through;
font-style: italic;
color: #fff7;
}
.Todo .Checkbox {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 22px;
height: 22px;
padding: 0px;
border: none;
cursor: pointer;
background-color: transparent;
border-radius: 50%;
border: 0.5px solid #fff3;
margin: 0px;
margin-right: 12px;
}
.Todo .Checkbox.done {
border: 0.5px solid #fff5;
}
.Todo .Checkbox.done::after {
content: "";
width: 16px;
height: 16px;
position: absolute;
border-radius: 50%;
background-color: #fffc;
}
.tail {
margin-left: 8px;
justify-content: flex-end;
}
.VisibilityFilter {
flex: 1;
}
.VisibilityFilter .tail {
margin-left: 0px;
display: flex;
}
/*
* https://getbootstrap.com/docs/5.1/components/badge/
*/
.badge {
/* so width won't change when bumping. */
font-family: "Iosevka SS05", menlo, monospace;
display: inline-block;
padding: 0.35em 0.65em;
font-size: 13.5px;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 0.25rem;
}
.rounded-pill {
border-radius: 50rem !important;
}
.badge-danger {
color: #fff;
background-color: #dc3545;
}
.badge-warning {
color: #212529;
background-color: #ffc107;
}
@@ -1,19 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default function ColorPicker({ value, onChange }) {
return (
<input
className="ColorPicker"
type="color"
id="head"
name="head"
value={value}
onChange={onChange}
/>
);
}
@@ -1,24 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { forwardRef } from "react";
// Capped to 3 digits
const CountBadge = forwardRef(
({ count = 0, type = "danger", rounded = false }, ref) => {
return (
<span
ref={ref}
className={`badge ${rounded && "rounded-pill"} badge-${type}`}
>
{count > 999 ? 999 : count}
</span>
);
}
);
export default CountBadge;
@@ -1,14 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const initialTodos = [
{ id: 0, text: "memo", done: true },
{ id: 1, text: "useCallback", done: false },
{ id: 2, text: "useMemo", done: false },
];
export default initialTodos;
@@ -1,29 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default function Select({ value, options, onChange }) {
return (
<div className="Select">
{options.map(o => {
if (value === o.value) {
return (
<button key={o.value} className="selected">
{" "}
{o.label}{" "}
</button>
);
} else {
return (
<button key={o.value} onClick={() => onChange(o.value)}>
{o.label}
</button>
);
}
})}
</div>
);
}
@@ -1,35 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function delay() {
let now = performance.now();
while (performance.now() - now < 16) {
// Artificial delay -- do nothing for 100ms
}
}
export default function getFiltered(todos, visibility) {
//delay()
// client-only
if (typeof window !== "undefined") {
// This only works when there is only one counter unfortunately...
const $filterCountBadge = document.querySelector(
".FilterCountBanner .badge"
);
if ($filterCountBadge)
$filterCountBadge.textContent =
parseInt($filterCountBadge.textContent) + 1;
}
switch (visibility) {
case "all":
return todos;
case "active":
return todos.filter((t) => !t.done);
case "completed":
return todos.filter((t) => t.done);
}
}
@@ -1,18 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
export default function getUpdated(tasks, newTodo) {
return tasks
.map(t => {
if (t.id === newTodo.id) {
return newTodo;
} else {
return t;
}
})
.filter(t => !!t.text);
}
@@ -1,17 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { useRef } from "react";
const REACT_MEMOCACHE_SENTINEL = Symbol.for('react.memocache_sentinel');
export function useMemoCache(i) {
const $ = new Array(i).fill(REACT_MEMOCACHE_SENTINEL)
$._ = REACT_MEMOCACHE_SENTINEL
const ref = useRef($);
return ref.current;
};
File diff suppressed because it is too large Load Diff
@@ -1,3 +0,0 @@
{
"plugins": ["../../"]
}
@@ -1 +0,0 @@
SKIP_PREFLIGHT_CHECK=true
@@ -1,21 +0,0 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
@@ -1,30 +0,0 @@
# React Forget Demo - Todo List Playground
This is a playground that compare different version of Todolist implementation.
## Get Started
This is a Create-React-App project.
## Structure
- `forget` - a CLI driver to call the compiler from `../`
- `index.js` - the entry point of demo
- `source` - source dir
- `*.js` - unmemoized code
- `*.memo.js` - manually memoized code, will be ignored by `forget`
- `*.half.memo.js` - partially memoized code, will also be ignored by `forget`
- `forget` - output dir
### Compile
```
# npm
npm run forget
# yarn
yarn forget
```
@@ -1,58 +0,0 @@
#!/bin/bash
#############################################################
#
# Forget Shell Driver
#
# Usage:
# $ forget <src> <dist>
#
#############################################################
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
function cleanup() {
for file in "$1"/*
do
file=$file;
fullname="$(basename $file)"
name="${fullname%*.}"
if [ "$name" != "useMemoCache.js" ]; then
echo "[Forget] cleanup: ${file}"
rm $file
fi
done
}
function traverse() {
for file in "$1"/*
do
dir="$(dirname $file)"
fullname="$(basename $file)"
ext="${fullname##*.}"
name="${fullname%.*}"
maybeExt="${name##*.}"
# echo "dir=$dir"
# echo "file=$file"
# echo "fullname=$fullname"
# echo "name=$name"
# echo "ext=$ext"
# echo "maybeExt=$maybeExt"
source=$file;
output="${2}/${fullname}"
if [ "$maybeExt" != "memo" ]; then
echo "[Forget] compile: ${source} -> ${output}"
npx babel ${source} --out-file ${output};
before=$(cat ${output})
echo -e "import { useMemoCache } from \"./useMemoCache\";\n${before}" > $output
fi
done
}
cleanup "$2"
traverse "$1" "$2"
@@ -1,32 +0,0 @@
{
"name": "react-doc-todo",
"main": "src/index.js",
"dependencies": {
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-scripts": "^4.0.0"
},
"version": "0.0.0",
"devDependencies": {
"@babel/cli": "^7.15.7",
"@babel/core": "^7.15.5",
"@babel/runtime": "7.13.8",
"babel-preset-react-app": "^10.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"forget": "./forget src/source src/forget"
},
"prettier": {
"arrowParens": "avoid"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

@@ -1,38 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
@@ -1,15 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "192x192",
"type": "image/png"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Some files were not shown because too many files have changed in this diff Show More