@amaui/ui-react
Version:
UI for React
759 lines (758 loc) • 54.9 kB
JavaScript
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importDefault(require("react"));
const utils_1 = require("@amaui/utils");
const style_react_1 = require("@amaui/style-react");
const IconMaterialDoneW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialDoneW100"));
const IconMaterialCloseW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialCloseW100"));
const IconMaterialTuneW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialTuneW100"));
const IconMaterialCropW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialCropW100"));
const IconMaterialAspectRatioW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialAspectRatioW100"));
const IconMaterialHighQualityW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialHighQualityW100"));
const IconMaterialClearAllW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialClearAllW100"));
const IconMaterialDownloadW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialDownloadW100"));
const IconMaterialCloudW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialCloudW100"));
const IconMaterialWaterDropW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialWaterDropW100"));
const IconMaterialFlakyW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialFlakyW100"));
const IconMaterialWbSunnyW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialWbSunnyW100"));
const IconMaterialTonalityW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialTonalityW100"));
const IconMaterialNightlightW100_1 = __importDefault(require("@amaui/icons-material-rounded-react/IconMaterialNightlightW100"));
const Type_1 = __importDefault(require("../Type"));
const Surface_1 = __importDefault(require("../Surface"));
const Tooltip_1 = __importDefault(require("../Tooltip"));
const IconButton_1 = __importDefault(require("../IconButton"));
const Expand_1 = __importDefault(require("../Expand"));
const Divider_1 = __importDefault(require("../Divider"));
const Slider_1 = __importDefault(require("../Slider"));
const NumericTextField_1 = __importDefault(require("../NumericTextField"));
const ImageCrop_1 = __importDefault(require("../ImageCrop"));
const Chip_1 = __importDefault(require("../Chip"));
const Line_1 = __importDefault(require("../Line"));
const utils_2 = require("../utils");
const useStyle = (0, style_react_1.style)(theme => ({
root: {},
option: {
width: '100%',
padding: `${theme.methods.space.value(2, 'px')} ${theme.methods.space.value(3, 'px')}`
},
options: {
width: '100%',
overflowX: 'auto',
padding: `${theme.methods.space.value(2, 'px')} ${theme.methods.space.value(3, 'px')}`
},
canvas: {
width: '100%',
height: 'auto',
zIndex: '1'
},
inputs: {
width: '100%'
},
divider: {
'&.amaui-Divider-root': {
margin: '0px'
}
},
imageWrapper: {
position: 'relative',
height: '400px',
width: '100%',
'&::before': {
content: '""',
position: 'absolute',
inset: '0',
width: '100%',
height: '100%',
background: 'currentColor',
zIndex: '0',
opacity: '0.94'
}
},
canvasWrapper: {
position: 'relative',
lineHeight: '0'
},
image: {
width: '100%',
height: 'auto'
},
imageCopy: {
width: '100%',
height: 'auto'
},
imageCrop: {
position: 'absolute',
inset: '0',
width: '100% !important',
height: '100% !important'
},
meta: {
width: '100%',
padding: `${theme.methods.space.value(1.5, 'px')} ${theme.methods.space.value(3, 'px')}`
},
optionInput: {
'& .amaui-TextField-input-wrapper': {
padding: '0px',
height: 'auto'
},
'& .amaui-TextField-input': {
textAlign: 'center'
}
},
filters: {
width: '100%',
overflowX: 'auto',
'& > *': {
flex: '0 0 auto'
}
},
action: {
width: '100%',
paddingTop: theme.methods.space.value(2, 'px')
},
slider: {
width: '100%'
}
}), { name: 'amaui-ImageEdit' });
const ImageEdit = react_1.default.forwardRef((props_, ref) => {
var _a, _b;
const theme = (0, style_react_1.useAmauiTheme)();
const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.amauiImageEdit) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]);
const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]);
const Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]);
const Surface = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Surface) || Surface_1.default; }, [theme]);
const IconButton = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.IconButton) || IconButton_1.default; }, [theme]);
const Tooltip = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Tooltip) || Tooltip_1.default; }, [theme]);
const Expand = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Expand) || Expand_1.default; }, [theme]);
const Divider = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Divider) || Divider_1.default; }, [theme]);
const Slider = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Slider) || Slider_1.default; }, [theme]);
const NumericTextField = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.NumericTextField) || NumericTextField_1.default; }, [theme]);
const ImageCrop = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.ImageCrop) || ImageCrop_1.default; }, [theme]);
const Chip = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Chip) || Chip_1.default; }, [theme]);
const { tonal = true, color = 'primary', image, name = 'amaui-image.jpg', type = 'image/jpeg', openDefault, openedOptionDefault, valueDefault, value: value_, valueCopyDefault, valueCopy: valueCopy_, onChange: onChange_, onChangeCopy: onChangeCopy_, onlyFilters, filters: filters_, meta = true, filtersOption = true, cropOption = true, resizeOption = true, qualityOption = true, downloadOption = true, resizeAspectRatio = true, renderOption, renderOptionClear, renderSave, renderCancel, renderSlider, renderDownload, renderInput, IconBrightness = IconMaterialWbSunnyW100_1.default, IconContrast = IconMaterialFlakyW100_1.default, IconSaturation = IconMaterialWaterDropW100_1.default, IconFade = IconMaterialCloudW100_1.default, IconInvert = IconMaterialTonalityW100_1.default, IconOldPhoto = IconMaterialNightlightW100_1.default, IconSave = IconMaterialDoneW100_1.default, IconCancel = IconMaterialCloseW100_1.default, IconClear = IconMaterialClearAllW100_1.default, IconCrop = IconMaterialCropW100_1.default, IconFilters = IconMaterialTuneW100_1.default, IconResize = IconMaterialAspectRatioW100_1.default, IconQuality = IconMaterialHighQualityW100_1.default, IconDownload = IconMaterialDownloadW100_1.default, ChipProps: ChipProps_, SliderProps: SliderProps_, TooltipProps: TooltipProps_, ImageCropProps: ImageCropProps_, IconButtonProps: IconButtonProps_, className, children } = props, other = __rest(props, ["tonal", "color", "image", "name", "type", "openDefault", "openedOptionDefault", "valueDefault", "value", "valueCopyDefault", "valueCopy", "onChange", "onChangeCopy", "onlyFilters", "filters", "meta", "filtersOption", "cropOption", "resizeOption", "qualityOption", "downloadOption", "resizeAspectRatio", "renderOption", "renderOptionClear", "renderSave", "renderCancel", "renderSlider", "renderDownload", "renderInput", "IconBrightness", "IconContrast", "IconSaturation", "IconFade", "IconInvert", "IconOldPhoto", "IconSave", "IconCancel", "IconClear", "IconCrop", "IconFilters", "IconResize", "IconQuality", "IconDownload", "ChipProps", "SliderProps", "TooltipProps", "ImageCropProps", "IconButtonProps", "className", "children"]);
const [init, setInit] = react_1.default.useState(false);
const [value, setValue] = react_1.default.useState(valueDefault !== undefined ? valueDefault : value_);
const [valueCopy, setValueCopy] = react_1.default.useState(valueCopyDefault !== undefined ? valueCopyDefault : valueCopy_);
const [open, setOpen] = react_1.default.useState(openDefault);
const [openedOption, setOpenedOption] = react_1.default.useState(openedOptionDefault);
const [quality, setQuality] = react_1.default.useState(100);
const [filterValues, setFilterValues] = react_1.default.useState({});
const [filterValuesCopy, setFilterValuesCopy] = react_1.default.useState({});
const [filter, setFilter] = react_1.default.useState();
const [resize, setResize] = react_1.default.useState();
const [selection, setSelection] = react_1.default.useState();
const [aspectRatio, setAspectRatio] = react_1.default.useState();
const [aspectRatioCustom, setAspectRatioCustom] = react_1.default.useState([1, 1]);
const [size, setSize] = react_1.default.useState('');
const { classes } = useStyle();
const refs = {
root: react_1.default.useRef(undefined),
option: react_1.default.useRef(undefined),
value: react_1.default.useRef(undefined),
valueCopy: react_1.default.useRef(undefined),
canvasMain: react_1.default.useRef(),
open: react_1.default.useRef(),
resizeAspectRatio: react_1.default.useRef(undefined),
filterValues: react_1.default.useRef(undefined),
filterValuesCopy: react_1.default.useRef(undefined)
};
refs.value.current = value;
refs.valueCopy.current = valueCopy;
refs.open.current = open;
refs.resizeAspectRatio.current = resizeAspectRatio;
refs.filterValues.current = filterValues;
refs.filterValuesCopy.current = filterValuesCopy;
const updateSize = (valueNew = refs.canvasMain.current) => {
const uri = valueNew.toDataURL(type);
// Update size
setSize((0, utils_1.to)((0, utils_1.to)(uri, 'byte-size'), 'size-format'));
};
react_1.default.useEffect(() => {
var _a;
const method = (event) => {
if (['Escape'].includes(event.key) ||
(['s', 'S'].includes(event.key) && event.metaKey) ||
(['f', 'F'].includes(event.key) && event.metaKey && event.shiftKey) ||
(['c', 'C'].includes(event.key) && event.metaKey && event.shiftKey) ||
(['d', 'D'].includes(event.key) && (event.metaKey || event.shiftKey)) ||
(['r', 'R'].includes(event.key) && (event.metaKey || event.shiftKey)) ||
(['q', 'Q'].includes(event.key) && event.metaKey && event.shiftKey)) {
event.preventDefault();
}
switch (event.key) {
case 's':
case 'S':
if (refs.open.current && event.metaKey)
onSave();
return;
case 'f':
case 'F':
if (event.metaKey && event.shiftKey)
openOption('filters');
return;
case 'c':
case 'C':
if (event.metaKey && event.shiftKey)
openOption('crop');
return;
case 'd':
case 'D':
if (event.metaKey && event.shiftKey)
onDownload();
return;
case 'r':
case 'R':
if (event.metaKey && !event.shiftKey)
onReset();
if (event.metaKey && event.shiftKey)
openOption('resize');
return;
case 'q':
case 'Q':
if (event.metaKey && event.shiftKey)
openOption('quality');
return;
case 'Escape':
if (refs.open.current)
onCancel();
return;
default:
break;
}
};
if (!refs.value.current) {
if (image instanceof HTMLCanvasElement)
onChange(image);
else if ((0, utils_1.is)('string', image))
makeImage(image);
}
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
rootDocument.addEventListener('keydown', method);
setInit(true);
return () => {
// Clean up
rootDocument.removeEventListener('keydown', method);
};
}, []);
react_1.default.useEffect(() => {
if (image instanceof HTMLCanvasElement)
onChange(image);
else if ((0, utils_1.is)('string', image))
makeImage(image);
}, [image]);
react_1.default.useEffect(() => {
var _a;
const valueToUse = !open ? refs.value.current : refs.valueCopy.current;
if (valueToUse) {
refs.canvasMain.current.width = valueToUse.width;
refs.canvasMain.current.height = valueToUse.height;
(_a = refs.canvasMain.current) === null || _a === void 0 ? void 0 : _a.getContext('2d').drawImage(valueToUse, 0, 0, valueToUse.width, valueToUse.height);
updateSize();
}
}, [value, valueCopy, open]);
react_1.default.useEffect(() => {
if (init) {
if (value_ !== value)
onChange(value_);
}
}, [value_]);
react_1.default.useEffect(() => {
if (init) {
if (valueCopy_ !== valueCopy)
onChangeCopy(valueCopy_);
}
}, [valueCopy_]);
const applyAllFilters = (canvas) => {
let valueCopy__ = refs.valueCopy.current;
// Update filters
Object.keys(refs.filterValuesCopy.current).forEach(item => {
const filterValue_ = filters.find(item_ => item_.value === item);
if (filterValue_) {
const { method } = filterValue_;
if ((0, utils_1.is)('function', method) &&
refs.filterValuesCopy.current[item] !== undefined)
valueCopy__ = method(refs.filterValuesCopy.current[item], canvas, valueCopy__);
}
});
};
const applyAllFiltersDebounced = react_1.default.useCallback((0, utils_1.debounce)(applyAllFilters, 140), []);
react_1.default.useEffect(() => {
applyAllFiltersDebounced(refs.canvasMain.current);
}, [filterValuesCopy]);
const makeImage = async (valueNew = refs.value.current) => {
var _a;
const img = await (0, utils_2.image)(valueNew);
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
const canvas = rootDocument.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
// Image
onChange(canvas);
// Image copy
const copy = rootDocument.createElement('canvas');
copy.width = canvas.width;
copy.height = canvas.height;
copy.getContext('2d').drawImage(canvas, 0, 0, canvas.width, canvas.height);
onChangeCopy(copy);
};
const updateResize = (0, utils_1.debounce)(async (width, height) => {
var _a;
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
// Update value copy
const canvas = rootDocument.createElement('canvas');
if (width > 1 && height > 1) {
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(refs.value.current, 0, 0, width, height);
// Value copy
onChangeCopy(canvas);
// Update the canvas value
refs.canvasMain.current.width = width;
refs.canvasMain.current.height = height;
refs.canvasMain.current.getContext('2d').drawImage(value, 0, 0, width, height);
// Update size
updateSize();
}
}, 140);
const onFilterSliderChange = (valueNew, valueFilter) => {
setFilterValuesCopy(values_ => (Object.assign(Object.assign({}, values_), { [valueFilter]: valueNew })));
};
const onChangeFilter = (valueNew) => {
// If moving to another filter or closing current one
// clean up previous one filter for mainCanvas
if (filter === valueNew)
setFilter('');
else
setFilter(valueNew);
};
const onChangeAspectRatioCustom = (valueNew_, left_ = true) => {
const valueNew = !valueNew_ ? 1 : valueNew_;
let left = (aspectRatioCustom === null || aspectRatioCustom === void 0 ? void 0 : aspectRatioCustom[0]) || 1;
let right = (aspectRatioCustom === null || aspectRatioCustom === void 0 ? void 0 : aspectRatioCustom[1]) || 1;
left_ ? left = valueNew : right = valueNew;
setAspectRatioCustom([left, right]);
onChangeAspectRatio(left / right);
};
const onChangeAspectRatio = (valueNew) => {
if (aspectRatio === valueNew)
setAspectRatio('');
else
setAspectRatio(valueNew);
};
const onChangeResize = async (valueNew, width_ = true) => {
let width;
let height;
if (!refs.resizeAspectRatio.current) {
if (width_) {
width = +valueNew;
height = resize === null || resize === void 0 ? void 0 : resize[1];
}
else {
width = resize === null || resize === void 0 ? void 0 : resize[0];
height = +valueNew;
}
}
else {
const aspectRatio_ = (value === null || value === void 0 ? void 0 : value.width) / (value === null || value === void 0 ? void 0 : value.height);
if (width_) {
width = +valueNew;
height = valueNew / aspectRatio_;
}
else {
height = +valueNew;
width = height * aspectRatio_;
}
}
width = (0, utils_1.clamp)(width, 0);
height = (0, utils_1.clamp)(height, 0);
setResize([width, height]);
await updateResize(width, height);
};
const updateQuality = (0, utils_1.debounce)(async (valueNew) => {
var _a, _b;
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
// Update copy value
const uri = value.toDataURL('image/jpeg', valueNew / 100);
const img = await (0, utils_2.image)(uri);
const canvas = rootDocument.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
onChangeCopy(canvas);
// Update the canvas value
refs.canvasMain.current.width = canvas.width;
refs.canvasMain.current.height = canvas.height;
(_b = refs.canvasMain.current) === null || _b === void 0 ? void 0 : _b.getContext('2d').drawImage(canvas, 0, 0, canvas.width, canvas.height);
// Update size
updateSize();
}, 40);
const onChangeQuality = async (valueNew) => {
setQuality(valueNew);
await updateQuality(valueNew);
};
const onChange = (valueNew) => {
// Update inner or controlled
if (!props.hasOwnProperty('value'))
setValue(valueNew);
if ((0, utils_1.is)('function', onChange_))
onChange_(valueNew);
};
const onChangeCopy = (valueNew) => {
// Update inner or controlled
if (!props.hasOwnProperty('valueCopy'))
setValueCopy(valueNew);
if ((0, utils_1.is)('function', onChangeCopy_))
onChangeCopy_(valueNew);
};
const onReset = (imageReset = true, valueCopyReset = true, resizeReset = true) => {
var _a;
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
setOpen(false);
setQuality(100);
setAspectRatio('');
setAspectRatioCustom([1, 1]);
setSelection('');
setFilter('');
setFilterValuesCopy(Object.assign({}, filterValues));
if (resizeReset)
setResize([value === null || value === void 0 ? void 0 : value.width, value === null || value === void 0 ? void 0 : value.height]);
if (valueCopyReset) {
const canvas = rootDocument.createElement('canvas');
canvas.width = refs.value.current.width;
canvas.height = refs.value.current.height;
canvas.getContext('2d').drawImage(refs.value.current, 0, 0, refs.value.current.width, refs.value.current.height);
onChangeCopy(canvas);
}
if (imageReset) {
setFilterValues({});
setFilterValuesCopy({});
makeImage(image);
}
};
const openOption = (valueNew) => {
setOpenedOption(valueNew);
if (open && openedOption === valueNew) {
setOpen(false);
onReset(false);
}
else if (!open)
setOpen(true);
};
const onSave = () => {
var _a, _b;
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
// Make value copy into value
let canvas = rootDocument.createElement('canvas');
canvas.width = refs.valueCopy.current.width;
canvas.height = refs.valueCopy.current.height;
canvas.getContext('2d').drawImage(refs.valueCopy.current, 0, 0, refs.valueCopy.current.width, refs.valueCopy.current.height);
// Update crop
if (openedOption === 'crop' && selection) {
// Crop the canvas
canvas.width = selection.width;
canvas.height = selection.height;
canvas = (0, utils_1.canvasCrop)(refs.valueCopy.current, selection.left, selection.top, selection.width, selection.height);
}
// Update filters
setFilterValues(Object.assign({}, filterValuesCopy));
applyAllFilters(canvas);
// Update the main canvas value
refs.canvasMain.current.width = canvas.width;
refs.canvasMain.current.height = canvas.height;
(_b = refs.canvasMain.current) === null || _b === void 0 ? void 0 : _b.getContext('2d').drawImage(canvas, 0, 0, canvas.width, canvas.height);
// Update value
onChange(canvas);
const canvasCopy = rootDocument.createElement('canvas');
canvasCopy.width = canvas.width;
canvasCopy.height = canvas.height;
canvasCopy.getContext('2d').drawImage(canvas, 0, 0, canvasCopy.width, canvasCopy.height);
// Update value copy
onChangeCopy(canvasCopy);
// Reset
onReset(false, false, false);
};
const onDownload = () => {
// Download the image from canvas datauri
// of the image type and quality, name
const uri = refs.value.current.toDataURL(type);
(0, utils_1.download)(name, uri, type);
};
const onCancel = () => {
var _a, _b, _c, _d;
const rootDocument = (0, utils_1.isEnvironment)('browser') ? (((_a = refs.root.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window.document) : undefined;
// Reset to unopen
onReset(false);
// Make value copy into value
const canvas = rootDocument.createElement('canvas');
canvas.width = refs.value.current.width;
canvas.height = refs.value.current.height;
canvas.getContext('2d').drawImage(refs.value.current, 0, 0, refs.value.current.width, refs.value.current.height);
onChangeCopy(canvas);
// Update the main canvas value
refs.canvasMain.current.width = (_b = refs.value.current) === null || _b === void 0 ? void 0 : _b.width;
refs.canvasMain.current.height = (_c = refs.value.current) === null || _c === void 0 ? void 0 : _c.height;
(_d = refs.canvasMain.current) === null || _d === void 0 ? void 0 : _d.getContext('2d').drawImage(refs.value.current, 0, 0, refs.value.current.width, refs.value.current.height);
};
let filters = react_1.default.useMemo(() => [
{
label: 'Brightness',
Icon: IconBrightness,
value: 'brightness',
method: utils_2.canvasBrightness,
renderIconButton: (value__, selected_, onChangeFilter_) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ label: 'Brightness' }, TooltipProps, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ version: 'outlined', selected: selected_, onClick: () => onChangeFilter_(value__) }, IconButtonProps, { children: (0, jsx_runtime_1.jsx)(IconBrightness, {}) })) }), value__)),
renderSlider: (value__, filterValuesCopy_, onFilterSliderChange_) => ((0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, value: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, min: -100, max: 100, precision: 1, marks: [
{ value: -100, label: '-100' },
{ value: 0, label: '0' },
{ value: 100, label: '100' }
], labels: true, tooltip: true, onChange: (valueNew) => {
if ((0, utils_1.is)('function', onFilterSliderChange_))
onFilterSliderChange_(valueNew, value__);
} }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) }), value__))
},
{
label: 'Contrast',
Icon: IconContrast,
value: 'contrast',
method: utils_2.canvasContrast,
renderIconButton: (value__, selected_, onChangeFilter_) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ label: 'Contrast' }, TooltipProps, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ version: 'outlined', selected: selected_, onClick: () => onChangeFilter_(value__) }, IconButtonProps, { children: (0, jsx_runtime_1.jsx)(IconContrast, {}) })) }), value__)),
renderSlider: (value__, filterValuesCopy_, onFilterSliderChange_) => ((0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, value: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, min: -100, max: 100, precision: 1, marks: [
{ value: -100, label: '-100' },
{ value: 0, label: '0' },
{ value: 100, label: '100' }
], labels: true, tooltip: true, onChange: (valueNew) => {
if ((0, utils_1.is)('function', onFilterSliderChange_))
onFilterSliderChange_(valueNew, value__);
} }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) }), value__))
},
{
label: 'Saturation',
Icon: IconSaturation,
value: 'saturation',
method: utils_2.canvasSaturation,
renderIconButton: (value__, selected_, onChangeFilter_) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ label: 'Saturation' }, TooltipProps, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ version: 'outlined', selected: selected_, onClick: () => onChangeFilter_(value__) }, IconButtonProps, { children: (0, jsx_runtime_1.jsx)(IconSaturation, {}) })) }), value__)),
renderSlider: (value__, filterValuesCopy_, onFilterSliderChange_) => ((0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, value: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, min: -100, max: 100, precision: 1, marks: [
{ value: -100, label: '-100' },
{ value: 0, label: '0' },
{ value: 100, label: '100' }
], labels: true, tooltip: true, onChange: (valueNew) => {
if ((0, utils_1.is)('function', onFilterSliderChange_))
onFilterSliderChange_(valueNew, value__);
} }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) }), value__))
},
{
label: 'Fade',
Icon: IconFade,
value: 'fade',
method: utils_2.canvasFade,
renderIconButton: (value__, selected_, onChangeFilter_) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ label: 'Fade' }, TooltipProps, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ version: 'outlined', selected: selected_, onClick: () => onChangeFilter_(value__) }, IconButtonProps, { children: (0, jsx_runtime_1.jsx)(IconFade, {}) })) }), value__)),
renderSlider: (value__, filterValuesCopy_, onFilterSliderChange_) => ((0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, value: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, min: 0, max: 100, precision: 1, marks: [
{ value: 0, label: '0' },
{ value: 100, label: '100' }
], labels: true, tooltip: true, onChange: (valueNew) => {
if ((0, utils_1.is)('function', onFilterSliderChange_))
onFilterSliderChange_(valueNew, value__);
} }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) }), value__))
},
{
label: 'Invert',
Icon: IconInvert,
value: 'invert',
method: utils_2.canvasInvert,
renderIconButton: (value__, selected_, onChangeFilter_) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ label: 'Invert' }, TooltipProps, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ version: 'outlined', selected: selected_, onClick: () => onChangeFilter_(value__) }, IconButtonProps, { children: (0, jsx_runtime_1.jsx)(IconInvert, {}) })) }), value__)),
renderSlider: (value__, filterValuesCopy_, onFilterSliderChange_) => ((0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, value: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, min: 0, max: 1, precision: 1, marks: [
{ value: 0, label: 'Not inverted' },
{ value: 1, label: 'Inverted' }
], labels: true, tooltip: true, onChange: (valueNew) => {
if ((0, utils_1.is)('function', onFilterSliderChange_))
onFilterSliderChange_(valueNew, value__);
} }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) }), value__))
},
{
label: 'Old photo',
Icon: IconOldPhoto,
value: 'old_photo',
method: utils_2.canvasOldPhoto,
renderIconButton: (value__, selected_, onChangeFilter_) => ((0, jsx_runtime_1.jsx)(Tooltip, Object.assign({ label: 'Old photo' }, TooltipProps, { children: (0, jsx_runtime_1.jsx)(IconButton, Object.assign({ version: 'outlined', selected: selected_, onClick: () => onChangeFilter_(value__) }, IconButtonProps, { children: (0, jsx_runtime_1.jsx)(IconOldPhoto, {}) })) }), value__)),
renderSlider: (value__, filterValuesCopy_, onFilterSliderChange_) => ((0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, value: (filterValuesCopy_ === null || filterValuesCopy_ === void 0 ? void 0 : filterValuesCopy_[value__]) || 0, min: -40, max: 40, precision: 1, marks: [
{ value: -40, label: '-40' },
{ value: 0, label: 'No filter' },
{ value: 40, label: '40' }
], labels: true, tooltip: true, onChange: (valueNew) => {
if ((0, utils_1.is)('function', onFilterSliderChange_))
onFilterSliderChange_(valueNew, value__);
} }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) }), value__))
},
...(filters_ || [])
], [filters_]);
// Only filters
if ((0, utils_1.is)('array', onlyFilters))
filters = filters.filter(item => onlyFilters.includes(item.value));
const ImageCropProps = Object.assign({ gridLines: true }, ImageCropProps_);
const TooltipProps = Object.assign({ position: 'bottom', interactive: false }, TooltipProps_);
const IconButtonProps = Object.assign({ tonal, color: 'inherit' }, IconButtonProps_);
const SliderProps = Object.assign({ tonal: false, color: 'default' }, SliderProps_);
const ChipProps = Object.assign({ size: 'small' }, ChipProps_);
const chips = [
{ label: '1:1', value: 1 / 1 },
{ label: '4:3', value: 4 / 3 },
{ label: '16:9', value: 16 / 9 }
];
const options = [
filtersOption && { label: 'Filters', value: 'filters', Icon: IconFilters },
cropOption && { label: 'Crop', value: 'crop', Icon: IconCrop },
resizeOption && { label: 'Resize', value: 'resize', Icon: IconResize },
qualityOption && { label: 'Quality', value: 'quality', Icon: IconQuality }
]
.filter(Boolean);
const MetaTypeProps = {
version: 'b3'
};
const filterValue = filters.find(item_ => item_.value === filter);
return ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ ref: item => {
if (ref) {
if ((0, utils_1.is)('function', ref))
ref(item);
else if (ref === null || ref === void 0 ? void 0 : ref.current)
ref.current = item;
}
refs.root.current = item;
}, tonal: tonal, color: color, gap: 0, direction: 'column', Component: Surface, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-root',
`amaui-ImageEdit-size-${size}`
],
className,
classes.root
]) }, other, { children: [(0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 0, direction: 'column', align: 'center', justify: 'center', className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-image-wrapper'
],
classes.imageWrapper
]) }, { children: (0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-canvas-wrapper'
],
classes.canvasWrapper
]) }, { children: [(0, jsx_runtime_1.jsx)("canvas", { ref: refs.canvasMain, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-canvas',
'amaui-ImageEdit-canvas-main'
],
classes.canvas,
classes.canvas_main
]) }), open && openedOption === 'crop' && ((0, jsx_runtime_1.jsx)(ImageCrop, Object.assign({ image: valueCopy, aspectRatio: aspectRatio ? aspectRatio : undefined, onSelectorChange: (selector) => setSelection(selector) }, ImageCropProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-image-crop'
],
ImageCropProps.className,
classes.imageCrop
]), style: {
width: valueCopy === null || valueCopy === void 0 ? void 0 : valueCopy.width,
height: valueCopy === null || valueCopy === void 0 ? void 0 : valueCopy.height
} })))] })) })), (filtersOption || cropOption || resizeOption || qualityOption) && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(Expand, Object.assign({ in: !!open, parent: refs.root.current, style: {
width: '100%'
} }, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0, ref: refs.option, direction: 'column', className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-option'
],
classes.option
]) }, { children: [openedOption === 'filters' && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Expand, Object.assign({ in: !!filterValue, parent: refs.option.current, style: {
width: '100%'
} }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ style: {
paddingInline: theme.methods.space.value(5, 'px'),
paddingBottom: theme.methods.space.value(5, 'px')
} }, { children: (0, utils_1.is)('function', filterValue === null || filterValue === void 0 ? void 0 : filterValue.renderSlider) && (filterValue === null || filterValue === void 0 ? void 0 : filterValue.renderSlider(filterValue.value, refs.filterValuesCopy.current, onFilterSliderChange)) })) })), (0, jsx_runtime_1.jsx)(Line, Object.assign({ gap: 1, direction: 'row', align: 'center', justify: 'flex-start', className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-filters'
],
classes.filters
]) }, { children: filters.map((item) => ((0, utils_1.is)('function', item.renderIconButton) && item.renderIconButton(item.value, item.value === filter, onChangeFilter))) }))] }), openedOption === 'crop' && ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 1, direction: 'row', align: 'center', justify: 'center', style: {
width: '100%'
} }, { children: [chips.map((item, index) => ((0, jsx_runtime_1.jsx)(Chip, Object.assign({ selected: aspectRatio === item.value, onClick: () => onChangeAspectRatio(item.value) }, ChipProps, { children: item.label }), index))), (0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0, direction: 'row', align: 'center', justify: 'center' }, { children: [(0, utils_1.is)('function', renderInput) ? renderInput(value, valueCopy, aspectRatioCustom, onChangeAspectRatioCustom, 'left') : ((0, jsx_runtime_1.jsx)(NumericTextField, { tonal: tonal, color: 'default', version: 'text', size: 'small', min: 1, value: aspectRatioCustom === null || aspectRatioCustom === void 0 ? void 0 : aspectRatioCustom[0], onChange: (valueNew) => onChangeAspectRatioCustom(+valueNew), increment: false, decrement: false, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-option-input'
],
classes.optionInput
]), style: {
width: 24
} })), (0, jsx_runtime_1.jsx)(Type, { children: ":" }), (0, utils_1.is)('function', renderInput) ? renderInput(value, valueCopy, aspectRatioCustom, onChangeAspectRatioCustom, 'right') : ((0, jsx_runtime_1.jsx)(NumericTextField, { tonal: tonal, color: 'default', version: 'text', size: 'small', min: 1, value: aspectRatioCustom === null || aspectRatioCustom === void 0 ? void 0 : aspectRatioCustom[1], onChange: (valueNew) => onChangeAspectRatioCustom(+valueNew, false), increment: false, decrement: false, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-option-input'
],
classes.optionInput
]), style: {
width: 24
} }))] }))] }))), openedOption === 'resize' && ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ direction: 'row', align: 'center', justify: 'center', className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-inputs'
],
classes.inputs
]) }, { children: [(0, utils_1.is)('function', renderInput) ? renderInput(value, valueCopy, resize, onChangeResize, 'width') : ((0, jsx_runtime_1.jsx)(NumericTextField, { tonal: tonal, label: 'Width', color: 'default', version: 'text', size: 'small', min: 1, max: value === null || value === void 0 ? void 0 : value.width, valueDefault: value === null || value === void 0 ? void 0 : value.width, value: resize === null || resize === void 0 ? void 0 : resize[0], onChange: (valueNew) => onChangeResize(valueNew) })), (0, utils_1.is)('function', renderInput) ? renderInput(value, valueCopy, resize, onChangeResize, 'height') : ((0, jsx_runtime_1.jsx)(NumericTextField, { tonal: tonal, label: 'Height', color: 'default', version: 'text', size: 'small', min: 1, max: value === null || value === void 0 ? void 0 : value.height, valueDefault: value === null || value === void 0 ? void 0 : value.height, value: resize === null || resize === void 0 ? void 0 : resize[1], onChange: (valueNew) => onChangeResize(valueNew, false) }))] }))), openedOption === 'quality' && ((0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 3, direction: 'row', align: 'center', style: {
width: '100%'
} }, { children: [(0, jsx_runtime_1.jsx)(Slider, Object.assign({ valueDefault: quality, value: quality, min: 1, max: 100, precision: 1, marks: [
{ value: 1 },
{ value: 50 },
{ value: 100 }
], tooltip: true, onChange: onChangeQuality }, SliderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-slider'
],
SliderProps.className,
classes.slider
]) })), (0, jsx_runtime_1.jsx)(NumericTextField, { tonal: tonal, color: 'default', version: 'text', size: 'small', min: 1, max: 100, value: quality, increment: false, decrement: false, onChange: (valueNew) => onChangeQuality(+valueNew), className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('ImageEdit', theme) && [
'amaui-ImageEdit-option-input'
],
classes.optionInput