feat: v0.1.0

This commit is contained in:
范胜发
2022-03-08 14:58:05 +08:00
commit 9bae8badbd
40 changed files with 14669 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# 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*

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
The page will reload when you make changes.\
You may also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)

61
main.js Normal file
View File

@ -0,0 +1,61 @@
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const url = require('url');
let win = null;
ipcMain.on('size-change', (event, flag) => {
const [x, y] = win.getPosition();
if (flag) {
win.setSize(500, 300, true);
win.setPosition(x, y - 300 + 75, true);
} else {
win.setSize(120, 75, true);
win.setPosition(x, y + 300 - 75, true);
}
});
ipcMain.on('pos-change', (event, { x, y }) => {
win.setPosition(x, y, true);
});
const { getTodo, setTodo } = require('./store');
ipcMain.handle('get-todo', () => {
console.log(getTodo());
return getTodo();
});
ipcMain.on('set-todo', (e, value) => {
setTodo(value);
});
function createWindow() {
win = new BrowserWindow({
width: 120,
height: 75,
maxHeight: 300,
maxWidth: 500,
frame: false,
transparent: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
win.loadURL(
url.format({
pathname: path.join(__dirname, './build/index.html'),
protocol: 'file:',
slashes: true,
})
);
// win.loadURL('http://localhost:3000/');
// win.webContents.openDevTools();
}
app.whenReady().then(() => {
createWindow();
});

12859
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

67
package.json Normal file
View File

@ -0,0 +1,67 @@
{
"name": "time-cat",
"version": "0.1.0",
"private": true,
"author": "mol",
"main": "main.js",
"homepage": ".",
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.5.0",
"electron-store": "^8.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"make": "node --max-old-space-size=8192 && electron-builder --win --x64",
"electron": "electron .",
"electron:build": "electron-packager ./build TimeCat --platform=win32 --arch=x64 --out=./../out --asar --app-version=0.1.0"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"electron": "^17.1.0",
"electron-builder": "^22.14.13",
"electron-packager": "^15.4.0"
},
"build": {
"appId": "time-cat-v0.1.0",
"productName": "timecat",
"win": {
"target": [
"nsis"
]
},
"nsis": {
"oneClick": false,
"perMachine": true,
"allowToChangeInstallationDirectory": true
},
"electronDownload": {
"mirror": "https://npmmirror.com/mirrors/electron/"
}
}
}

8
preload.js Normal file
View File

@ -0,0 +1,8 @@
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electron', {
ipcRenderer: {
...ipcRenderer,
on: ipcRenderer.on,
},
});

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

43
public/index.html Normal file
View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
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>

BIN
public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

61
public/main.js Normal file
View File

@ -0,0 +1,61 @@
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
const url = require('url');
let win = null;
ipcMain.on('size-change', (event, flag) => {
const [x, y] = win.getPosition();
if (flag) {
win.setSize(500, 300, true);
win.setPosition(x, y - 300 + 75, true);
} else {
win.setSize(120, 75, true);
win.setPosition(x, y + 300 - 75, true);
}
});
ipcMain.on('pos-change', (event, { x, y }) => {
win.setPosition(x, y, true);
});
const { getTodo, setTodo } = require('./store');
ipcMain.handle('get-todo', () => {
console.log(getTodo());
return getTodo();
});
ipcMain.on('set-todo', (e, value) => {
setTodo(value);
});
function createWindow() {
win = new BrowserWindow({
width: 120,
height: 75,
maxHeight: 300,
maxWidth: 500,
frame: false,
transparent: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
win.loadURL(
url.format({
pathname: path.join(__dirname, './index.html'),
protocol: 'file:',
slashes: true,
})
);
// win.loadURL('http://localhost:3000/');
// win.webContents.openDevTools();
}
app.whenReady().then(() => {
createWindow();
});

25
public/manifest.json Normal file
View File

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

52
public/package.json Normal file
View File

@ -0,0 +1,52 @@
{
"name": "time-cat",
"version": "0.1.0",
"private": true,
"main": "main.js",
"homepage": ".",
"dependencies": {
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.5.0",
"electron-drag": "^2.0.0",
"electron-store": "^8.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"electron": "electron .",
"electron:build": "electron-packager ./build TimeCat --platform=win32 --arch=x64 --out=./../out --ar --app-version=0.1.0 --electron-version=17.1.0"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"electron": "^17.1.0",
"electron-builder": "^22.14.13",
"electron-packager": "^15.4.0"
},
"build": {
"appId": "time-cat-v0.1.0"
}
}

8
public/preload.js Normal file
View File

@ -0,0 +1,8 @@
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electron', {
ipcRenderer: {
...ipcRenderer,
on: ipcRenderer.on,
},
});

3
public/robots.txt Normal file
View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

20
public/store.js Normal file
View File

@ -0,0 +1,20 @@
const Store = require('electron-store');
const store = new Store();
function initStore() {
if (!store.has('todo')) {
store.set('todo', []);
}
}
initStore();
module.exports = {
getTodo() {
return store.get('todo');
},
setTodo(value) {
console.log(store.path);
return store.set('todo', value);
},
};

18
src/App.css Normal file
View File

@ -0,0 +1,18 @@
.App {
position: relative;
height: 100vh;
width: 100vw;
text-align: center;
}
.cat {
width: 115px;
position: absolute;
bottom: 0;
left: 0;
cursor: pointer;
/* -webkit-app-region: drag; */
}

80
src/App.js Normal file
View File

@ -0,0 +1,80 @@
import React, { useState } from 'react';
import './App.css';
import './styles/index.css';
import Todo from './components/todo';
import catImg from './assets/img/cat.png';
function App() {
const initData = JSON.parse(localStorage.getItem('todo') || '[]');
const [show, setShow] = useState(false);
const [data, setData] = useState(initData);
const { ipcRenderer } = window.electron;
console.log(data);
function handleMouseDown(e) {
console.log('down');
const mouseX = e.pageX;
const mouseY = e.pageY;
const clientX = e.clientX;
const clientY = e.clientY;
let isDrag = false;
function handleMove(e) {
if (!isDrag) {
console.log('move');
const cMouseX = e.pageX;
const cMouseY = e.pageY;
const dis = Math.sqrt(
(cMouseX - mouseX) ** 2 + (cMouseY - mouseY) ** 2
);
if (dis > 10) {
console.log('drag');
isDrag = true;
}
} else {
ipcRenderer.send('pos-change', {
x: e.screenX - clientX,
y: e.screenY - clientY,
});
}
}
function handleMouseUp(e) {
if (!isDrag) changeSize();
isDrag = false;
catElm.removeEventListener('mousemove', handleMove);
catElm.removeEventListener('mouseup', handleMouseUp);
}
const catElm = document.getElementById('cat');
catElm.addEventListener('mousemove', handleMove);
catElm.addEventListener('mouseup', handleMouseUp);
}
function changeSize() {
setShow(!show);
ipcRenderer.send('size-change', !show);
}
return (
<div className="App" draggable="false">
<img
draggable="false"
id="cat"
className="cat"
src={catImg}
onMouseDown={handleMouseDown}
/>
{show && <Todo data={data} setData={setData}></Todo>}
</div>
);
}
export default App;

8
src/App.test.js Normal file
View File

@ -0,0 +1,8 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

539
src/assets/font/demo.css Normal file
View File

@ -0,0 +1,539 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View File

@ -0,0 +1,280 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>iconfont Demo</title>
<link rel="shortcut icon" href="//img.alicdn.com/imgextra/i2/O1CN01ZyAlrn1MwaMhqz36G_!!6000000001499-73-tps-64-64.ico" type="image/x-icon"/>
<link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01EYTRnJ297D6vehehJ_!!6000000008020-55-tps-64-64.svg"/>
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
<script src="iconfont.js"></script>
<!-- jQuery -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
<!-- 代码高亮 -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
<style>
.main .logo {
margin-top: 0;
height: auto;
}
.main .logo a {
display: flex;
align-items: center;
}
.main .logo .sub-title {
margin-left: 0.5em;
font-size: 22px;
color: #fff;
background: linear-gradient(-45deg, #3967FF, #B500FE);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
</head>
<body>
<div class="main">
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
<img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
</a></h1>
<div class="nav-tabs">
<ul id="tabs" class="dib-box">
<li class="dib active"><span>Unicode</span></li>
<li class="dib"><span>Font class</span></li>
<li class="dib"><span>Symbol</span></li>
</ul>
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3226183" target="_blank" class="nav-more">查看项目</a>
</div>
<div class="tab-container">
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xeaf1;</span>
<div class="name">对号</div>
<div class="code-name">&amp;#xeaf1;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xeaf2;</span>
<div class="name">关闭</div>
<div class="code-name">&amp;#xeaf2;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xeaf3;</span>
<div class="name">加号</div>
<div class="code-name">&amp;#xeaf3;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xeb80;</span>
<div class="name">全局设置_o</div>
<div class="code-name">&amp;#xeb80;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
<hr>
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版 iconfont 支持两种方式引用多色图标SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
</blockquote>
<p>Unicode 使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1646623670176') format('woff2'),
url('iconfont.woff?t=1646623670176') format('woff'),
url('iconfont.ttf?t=1646623670176') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
<pre><code class="language-css"
>.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre>
<code class="language-html"
>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-duihao"></span>
<div class="name">
对号
</div>
<div class="code-name">.icon-duihao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-guanbi"></span>
<div class="name">
关闭
</div>
<div class="code-name">.icon-guanbi
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-jiahao"></span>
<div class="name">
加号
</div>
<div class="code-name">.icon-jiahao
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-setup"></span>
<div class="name">
全局设置_o
</div>
<div class="code-name">.icon-setup
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
<hr>
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
<p>与 Unicode 使用方式相比,具有如下特点:</p>
<ul>
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"
iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-duihao"></use>
</svg>
<div class="name">对号</div>
<div class="code-name">#icon-duihao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-guanbi"></use>
</svg>
<div class="name">关闭</div>
<div class="code-name">#icon-guanbi</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-jiahao"></use>
</svg>
<div class="name">加号</div>
<div class="code-name">#icon-jiahao</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-setup"></use>
</svg>
<div class="name">全局设置_o</div>
<div class="code-name">#icon-setup</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</code></pre>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('.tab-container .content:first').show()
$('#tabs li').click(function (e) {
var tabContent = $('.tab-container .content')
var index = $(this).index()
if ($(this).hasClass('active')) {
return
} else {
$('#tabs li').removeClass('active')
$(this).addClass('active')
tabContent.hide().eq(index).fadeIn()
}
})
})
</script>
</body>
</html>

View File

@ -0,0 +1,31 @@
@font-face {
font-family: "iconfont"; /* Project id 3226183 */
src: url('iconfont.woff2?t=1646623670176') format('woff2'),
url('iconfont.woff?t=1646623670176') format('woff'),
url('iconfont.ttf?t=1646623670176') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-duihao:before {
content: "\eaf1";
}
.icon-guanbi:before {
content: "\eaf2";
}
.icon-jiahao:before {
content: "\eaf3";
}
.icon-setup:before {
content: "\eb80";
}

View File

@ -0,0 +1 @@
!function(e){var t,n,l,o,i,c='<svg><symbol id="icon-duihao" viewBox="0 0 1024 1024"><path d="M392.533333 806.4L85.333333 503.466667l59.733334-59.733334 247.466666 247.466667L866.133333 213.333333l59.733334 59.733334L392.533333 806.4z" fill="#444444" ></path></symbol><symbol id="icon-guanbi" viewBox="0 0 1024 1024"><path d="M576 512l277.333333 277.333333-64 64-277.333333-277.333333L234.666667 853.333333 170.666667 789.333333l277.333333-277.333333L170.666667 234.666667 234.666667 170.666667l277.333333 277.333333L789.333333 170.666667 853.333333 234.666667 576 512z" fill="#444444" ></path></symbol><symbol id="icon-jiahao" viewBox="0 0 1024 1024"><path d="M469.333333 469.333333V170.666667h85.333334v298.666666h298.666666v85.333334h-298.666666v298.666666h-85.333334v-298.666666H170.666667v-85.333334h298.666666z" fill="#444444" ></path></symbol><symbol id="icon-setup" viewBox="0 0 1024 1024"><path d="M256 755.2l55.466667-17.066667 17.066666 12.8c21.333333 12.8 38.4 25.6 64 38.4l21.333334 8.533334 8.533333 55.466666h145.066667l12.8-55.466666 21.333333-8.533334c21.333333-8.533333 42.666667-21.333333 64-38.4l17.066667-12.8 55.466666 17.066667 72.533334-128-42.666667-38.4 4.266667-21.333333c0-12.8 4.266667-25.6 4.266666-38.4s0-25.6-4.266666-38.4l-4.266667-17.066667 42.666667-38.4-72.533334-128-55.466666 21.333333-17.066667-12.8c-21.333333-12.8-38.4-25.6-64-38.4l-21.333333-8.533333-12.8-55.466667H422.4l-12.8 55.466667-21.333333 8.533333c-21.333333 8.533333-42.666667 21.333333-59.733334 34.133334l-21.333333 17.066666L256 311.466667l-72.533333 128 42.666666 38.4-4.266666 21.333333c0 12.8-4.266667 25.6-4.266667 38.4s0 25.6 4.266667 38.4l4.266666 21.333333-42.666666 38.4L256 755.2z m-76.8-179.2c0-12.8-4.266667-25.6-4.266667-42.666667s0-29.866667 4.266667-42.666666L128 443.733333l106.666667-183.466666 64 21.333333c21.333333-17.066667 46.933333-29.866667 72.533333-42.666667L388.266667 170.666667h213.333333l17.066667 68.266666c25.6 12.8 51.2 25.6 72.533333 42.666667l64-21.333333 106.666667 183.466666-51.2 46.933334c0 12.8 4.266667 25.6 4.266666 42.666666s0 29.866667-4.266666 42.666667l51.2 46.933333-106.666667 183.466667-64-21.333333c-21.333333 17.066667-46.933333 29.866667-72.533333 42.666666l-17.066667 68.266667h-213.333333l-17.066667-68.266667c-25.6-12.8-51.2-25.6-72.533333-42.666666l-64 21.333333L128 622.933333l51.2-46.933333z m315.733333 64c59.733333 0 106.666667-46.933333 106.666667-106.666667S554.666667 426.666667 494.933333 426.666667s-106.666667 46.933333-106.666666 106.666666 46.933333 106.666667 106.666666 106.666667z m0 42.666667c-81.066667 0-149.333333-68.266667-149.333333-149.333334S413.866667 384 494.933333 384s149.333333 68.266667 149.333334 149.333333-68.266667 149.333333-149.333334 149.333334z" fill="#444444" ></path></symbol></svg>',d=(d=document.getElementsByTagName("script"))[d.length-1].getAttribute("data-injectcss"),s=function(e,t){t.parentNode.insertBefore(e,t)};if(d&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}function a(){i||(i=!0,l())}function m(){try{o.documentElement.doScroll("left")}catch(e){return void setTimeout(m,50)}a()}t=function(){var e,t=document.createElement("div");t.innerHTML=c,c=null,(t=t.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",t=t,(e=document.body).firstChild?s(t,e.firstChild):e.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(l=t,o=e.document,i=!1,m(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,a())})}(window);

View File

@ -0,0 +1,37 @@
{
"id": "3226183",
"name": "Time Cat",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "5387519",
"name": "对号",
"font_class": "duihao",
"unicode": "eaf1",
"unicode_decimal": 60145
},
{
"icon_id": "5387522",
"name": "关闭",
"font_class": "guanbi",
"unicode": "eaf2",
"unicode_decimal": 60146
},
{
"icon_id": "5387527",
"name": "加号",
"font_class": "jiahao",
"unicode": "eaf3",
"unicode_decimal": 60147
},
{
"icon_id": "5387888",
"name": "全局设置_o",
"font_class": "setup",
"unicode": "eb80",
"unicode_decimal": 60288
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/assets/img/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,47 @@
.todo-form {
width: 200px;
height: 120px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #ccc;
border-radius: 5px;
background-color: #fff;
overflow: hidden;
}
.todo-form__header {
padding: 5px 10px;
text-align: right;
}
.todo-form__content {
padding: 0 10px;
}
.form-item {
margin-bottom: 8px;
}
.form-item__content {
margin-left: 40px;
}
.form-item__content--button {
margin-left: 0;
}
.form-item__label {
float: left;
padding-right: 8px;
font-size: 14px;
vertical-align: middle;
}
.form-item__input {
width: 100%;
}

View File

@ -0,0 +1,61 @@
import React, { useState } from 'react';
import './index.css';
export function TodoForm(props) {
const [title, setTitle] = useState(props.data.title);
const [time, setTime] = useState(props.data.time);
function handleSubmit(e) {
props.submit({
title,
time,
});
props.setIsShowForm(false);
e.preventDefault();
}
return (
<div className="todo-form">
<div className="todo-form__header">
<span
className="button-text iconfont icon-guanbi header__close-button"
onClick={() => props.setIsShowForm(false)}
></span>
</div>
<form className="todo-form__content">
<div className="form-item">
<label className="form-item__label">日程:</label>
<div className="form-item__content">
<input
className="form-item__input"
type="text"
value={title}
onInput={(e) => setTitle(e.target.value)}
/>
</div>
</div>
<div className="form-item">
<label className="form-item__label">时间:</label>
<div className="form-item__content">
<input
className="form-item__input"
type="text"
value={time}
onInput={(e) => setTime(e.target.value)}
/>
</div>
</div>
<div className="form-item">
<div className="form-item__content form-item__content--button">
<button
className="button-text form-item__button"
onClick={handleSubmit}
>
确定
</button>
</div>
</div>
</form>
</div>
);
}

View File

@ -0,0 +1,58 @@
.todo {
width: 300px;
height: 150px;
position: absolute;
bottom: 20%;
left: 50%;
transform: translate(-50%, 0);
border: 1px solid #ccc;
border-radius: 5px;
background-color: rgba(255, 255, 255, 0.658);
overflow: hidden;
}
.todo-header {
display: flex;
height: 28px;
}
.todo-header__title {
flex: 1;
font-size: 16px;
line-height: 28px;
}
.todo-container {
height: calc(100% - 28px);
padding: 0 20px;
overflow-y: auto;
}
.todo-item {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
border-bottom: 1px solid #ccc;
line-height: 24px;
}
.todo-tools {
padding: 0 20px;
text-align: right;
}
.todo-tools__button {
font-size: 24px;
}
.todo-item__button {
margin-left: 8px;
}

View File

@ -0,0 +1,92 @@
import React, { useState } from 'react';
import './index.css';
import { TodoForm } from '../todo-form';
function Todo(props) {
const [isShowForm, setIsShowForm] = useState(false);
const [editData, setEditData] = useState({
title: '',
time: '',
});
const { ipcRenderer } = window.electron;
function handleAdd() {
setEditData({
title: '',
time: '',
});
setIsShowForm(true);
}
function handleEdit({ title, time }, e) {
setEditData({
title,
time,
});
setIsShowForm(true);
}
function handleSubmit(data) {
props.setData([...props.data, data]);
ipcRenderer.send('set-todo', [...props.data, data]);
localStorage.setItem('todo', JSON.stringify([...props.data, data]));
}
function handleDel(index) {
const temp = props.data.filter((item, i) => i !== index);
props.setData(temp);
ipcRenderer.send('set-todo', temp);
localStorage.setItem('todo', JSON.stringify(temp));
}
return (
<div className="todo">
<header className="todo-header">
<h1 className="todo-header__title">time cat</h1>
<div className="todo-tools">
<button
className="button-text todo-tools__button"
onClick={handleAdd}
>
+
</button>
</div>
</header>
<ul className="todo-container">
{props.data.map((todo, i) => {
return (
<li className="todo-item" key={i}>
<div className="todo-item__title">{todo.title}</div>
<div className="todo-item__time">{todo.time}</div>
<div className="todo-item__buttons">
<button
className="button-text iconfont icon-setup todo-item__button"
onClick={handleEdit.bind(this, {
title: todo.title,
time: todo.time,
})}
></button>
<button
className="button-text iconfont icon-guanbi todo-item__button"
onClick={handleDel.bind(this, i)}
></button>
<button className="button-text iconfont icon-duihao todo-item__button"></button>
</div>
</li>
);
})}
</ul>
{isShowForm && (
<TodoForm
data={editData}
setIsShowForm={setIsShowForm}
submit={handleSubmit}
></TodoForm>
)}
</div>
);
}
export default Todo;

28
src/index.css Normal file
View File

@ -0,0 +1,28 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
html,
body {
background-color: transparent;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
li {
list-style: none;
}

22
src/index.js Normal file
View File

@ -0,0 +1,22 @@
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const { ipcRenderer } = window.electron;
console.log(1);
ipcRenderer.invoke('get-todo').then((value) => {
localStorage.setItem('todo', JSON.stringify(value));
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
});

1
src/logo.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

13
src/reportWebVitals.js Normal file
View File

@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

5
src/setupTests.js Normal file
View File

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

9
src/styles/common.css Normal file
View File

@ -0,0 +1,9 @@
.button-text {
border: none;
background: none;
outline: none;
color: #6989f1;
cursor: pointer;
}

19
src/styles/index.css Normal file
View File

@ -0,0 +1,19 @@
* {
font-size: 14px;
}
::-webkit-scrollbar {
width: 5px;
}
::-webkit-scrollbar-thumb {
background-color: #6989f1;
border-radius: 5px;
}
::-webkit-scrollbar-track {
background-color: azure;
}
@import '../assets/font/iconfont.css';
@import './common.css';

20
store.js Normal file
View File

@ -0,0 +1,20 @@
const Store = require('electron-store');
const store = new Store();
function initStore() {
if (!store.has('todo')) {
store.set('todo', []);
}
}
initStore();
module.exports = {
getTodo() {
return store.get('todo');
},
setTodo(value) {
console.log(store.path);
return store.set('todo', value);
},
};