diff --git a/package-lock.json b/package-lock.json index 7a836c9a..79f18d86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1034,6 +1034,11 @@ "@hapi/hoek": "^8.3.0" } }, + "@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==" + }, "@jest/console": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", @@ -1511,6 +1516,15 @@ "csstype": "^2.2.0" } }, + "@types/react-color": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-3.0.1.tgz", + "integrity": "sha512-J6mYm43Sid9y+OjZ7NDfJ2VVkeeuTPNVImNFITgQNXodHteKfl/t/5pAR5Z9buodZ2tCctsZjgiMlQOpfntakw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-dom": { "version": "16.9.4", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.4.tgz", @@ -9369,6 +9383,11 @@ "object-visit": "^1.0.0" } }, + "material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -12094,6 +12113,19 @@ "whatwg-fetch": "^3.0.0" } }, + "react-color": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz", + "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==", + "requires": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.11", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + } + }, "react-dev-utils": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.0.0.tgz", @@ -12315,6 +12347,14 @@ "workbox-webpack-plugin": "4.3.1" } }, + "reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "requires": { + "lodash": "^4.0.1" + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -14397,6 +14437,11 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tinycolor2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 735e8be1..1be5d6df 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,14 @@ "main": "src/index.js", "dependencies": { "react": "16.12.0", + "react-color": "^2.17.3", "react-dom": "16.12.0", "react-scripts": "3.3.0", "roughjs": "3.1.0" }, "devDependencies": { "@types/react": "16.9.17", + "@types/react-color": "^3.0.1", "@types/react-dom": "16.9.4", "husky": "3.1.0", "lint-staged": "9.5.0", diff --git a/src/index.tsx b/src/index.tsx index 874b8461..7ca767c1 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,6 +2,7 @@ import React from "react"; import ReactDOM from "react-dom"; import rough from "roughjs/bin/wrappers/rough"; import { RoughCanvas } from "roughjs/bin/canvas"; +import { SketchPicker } from "react-color"; import { moveOneLeft, moveAllLeft, moveOneRight, moveAllRight } from "./zindex"; @@ -816,9 +817,16 @@ function restore( } } +enum ColorPicker { + CANVAS_BACKGROUND, + SHAPE_STROKE, + SHAPE_BACKGROUND +} + type AppState = { draggingElement: ExcalidrawElement | null; resizingElement: ExcalidrawElement | null; + currentColorPicker: ColorPicker | null; elementType: string; exportBackground: boolean; currentItemStrokeColor: string; @@ -889,7 +897,6 @@ const SHAPES = [ const shapesShortcutKeys = SHAPES.map(shape => shape.value[0]); - function capitalize(str: string) { return str.charAt(0).toUpperCase() + str.slice(1); } @@ -953,6 +960,7 @@ class App extends React.Component<{}, AppState> { draggingElement: null, resizingElement: null, elementType: "selection", + currentColorPicker: null, exportBackground: true, currentItemStrokeColor: "#000000", currentItemBackgroundColor: "#ffffff", @@ -1134,7 +1142,11 @@ class App extends React.Component<{}, AppState> {

Shapes

{SHAPES.map(({ value, icon }) => ( -

Colors

-

Canvas

diff --git a/src/styles.scss b/src/styles.scss index 343c9311..70d215e9 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -22,7 +22,6 @@ body { .sidePanel { width: 230px; background-color: #eee; - padding: 10px; overflow-y: auto; @@ -42,6 +41,17 @@ body { .panelColumn { display: flex; flex-direction: column; + + h5 { + margin-top: 4px; + margin-bottom: 4px; + font-size: 12px; + color: #333; + } + + h5:first-of-type { + margin-top: 0; + } } } @@ -134,3 +144,32 @@ button { cursor: not-allowed; } } + +.popover { + position: absolute; + z-index: 2; + + .cover { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + } +} + +.swatch { + height: 24px; + width: 24px; + display: inline; + margin-right: 4px; +} + +.swatch-input { + font-size: 16px; + display: inline; + width: 100px; + border-radius: 2px; + padding: 2px 4px; + border: 1px solid #ddd; +}