@tolokoban/ui
Version:
React components with theme
112 lines • 11.2 kB
JavaScript
import { __awaiter } from "tslib";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useEffect } from "react";
import { Theme } from "../../theme/index.js";
import { styleChild } from "../../theme/styles/child.js";
import { ViewPanel } from "../Panel/index.js";
import { ViewTouchable } from "../Touchable/index.js";
import IconLoading from "../icons/IconLoading.js";
import BackURL from "./back.jpg";
import Styles from "./InputImage.module.css";
import { ViewLabel } from "../Label/index.js";
export function ViewInputImage(props) {
const { value, onChange, width, height, busyIcon: BusyIcon = IconLoading, } = props;
const refCanvas = React.useRef(null);
const refInput = React.useRef(null);
const [busy, setBusy] = React.useState(false);
const paintOnCanvas = useCanvasPainter(value, refCanvas);
const style = Object.assign({}, styleChild(props));
const handleImport = (evt) => {
var _a;
const input = evt.target;
if (!input)
return;
const file = (_a = input.files) === null || _a === void 0 ? void 0 : _a[0];
if (!file)
return;
try {
setBusy(true);
const reader = new FileReader();
reader.addEventListener("load", () => {
const url = reader.result;
if (typeof url !== "string") {
console.error("URL should be a string and not a:", url);
return;
}
paintOnCanvas(url)
.then((dataUrl) => {
if (dataUrl)
onChange === null || onChange === void 0 ? void 0 : onChange(dataUrl);
})
.catch(console.error);
});
reader.addEventListener("error", (ex) => {
console.error(`Unable to load file "${file.name}":`, ex);
});
reader.readAsDataURL(file);
}
catch (ex) {
console.error("Error in handleFileChange(): ");
console.error(ex);
}
finally {
setBusy(false);
}
};
const triggerFileInput = () => {
const input = refInput.current;
if (!input)
return;
input.click();
};
return (_jsx(ViewLabel, { value: props.label, children: _jsx(ViewTouchable, { onClick: triggerFileInput, children: _jsxs("div", { className: Theme.classNames.join(props.className, Styles.InputImage), style: Object.assign(Object.assign({}, style), { maxWidth: `${width}px`, height: "auto", aspectRatio: `${width} / ${height}`, backgroundImage: `url(${BackURL})` }), children: [_jsx("canvas", { width: width, height: height, ref: refCanvas }), _jsx(ViewPanel, { className: busy ? Styles.busy : Styles.notBusy, display: "grid", placeItems: "center", color: "neutral-1-5", children: _jsx(BusyIcon, { size: "XL", animate: true }) }), _jsx("input", { ref: refInput, type: "file", style: { display: "none" }, accept: "image/*", multiple: false, onChange: handleImport })] }) }) }));
}
function useCanvasPainter(value, refCanvas) {
const importImage = React.useCallback((url) => __awaiter(this, void 0, void 0, function* () {
const img = yield loadImage(url);
if (!img)
return null;
const canvas = refCanvas.current;
if (canvas) {
const ctx = canvas.getContext("2d");
if (!ctx)
throw Error("unable to get a 2D context!");
const w = canvas.width;
const h = canvas.height;
ctx.clearRect(0, 0, w, h);
const scaleX = w / img.width;
const scaleY = h / img.height;
const scale = Math.max(scaleX, scaleY);
const dw = img.width * scale;
const dh = img.height * scale;
const x = 0.5 * (w - dw);
const y = 0.5 * (h - dh);
ctx.drawImage(img, x, y, dw, dh);
const dataUrl = canvas.toDataURL("image/webp", 0.7);
return dataUrl === value ? null : dataUrl;
}
return null;
}), [refCanvas, value]);
useEffect(() => {
if (value)
void importImage(value);
}, [importImage, value]);
return importImage;
}
function loadImage(url) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => {
resolve(img);
};
img.onerror = () => {
console.error("Unable to load image:", url);
resolve(null);
};
img.src = url;
});
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5wdXRJbWFnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy92aWV3L0lucHV0SW1hZ2UvSW5wdXRJbWFnZS50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEtBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxNQUFNLE9BQU8sQ0FBQTtBQUV4QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUE7QUFDNUMsT0FBTyxFQUFtQixVQUFVLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUV6RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDN0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFBO0FBQ3JELE9BQU8sV0FBVyxNQUFNLHlCQUF5QixDQUFBO0FBR2pELE9BQU8sT0FBTyxNQUFNLFlBQVksQ0FBQTtBQUVoQyxPQUFPLE1BQU0sTUFBTSx5QkFBeUIsQ0FBQTtBQUM1QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBY3BDLE1BQU0sVUFBVSxjQUFjLENBQUMsS0FBc0I7SUFDakQsTUFBTSxFQUNGLEtBQUssRUFDTCxRQUFRLEVBQ1IsS0FBSyxFQUNMLE1BQU0sRUFDTixRQUFRLEVBQUUsUUFBUSxHQUFHLFdBQVcsR0FDbkMsR0FBRyxLQUFLLENBQUE7SUFDVCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUEyQixJQUFJLENBQUMsQ0FBQTtJQUM5RCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUEwQixJQUFJLENBQUMsQ0FBQTtJQUM1RCxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDN0MsTUFBTSxhQUFhLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQ3hELE1BQU0sS0FBSyxxQkFDSixV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