devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
184 lines (183 loc) • 6.72 kB
JavaScript
/**
* DevExtreme (esm/__internal/ui/notify.js)
* Version: 25.2.3
* Build date: Fri Dec 12 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import $ from "../../core/renderer";
import {
isPlainObject,
isString
} from "../../core/utils/type";
import {
value as viewPort
} from "../../core/utils/view_port";
import {
getWindow
} from "../../core/utils/window";
import Toast from "../../ui/toast";
const window = getWindow();
let $notify = null;
const $containers = {};
const COORDINATE_ALIASES = {
"top left": {
top: 10,
left: 10
},
"top right": {
top: 10,
right: 10
},
"bottom left": {
bottom: 10,
left: 10
},
"bottom right": {
bottom: 10,
right: 10
},
"top center": dimensions => ({
top: 10,
left: Math.round(dimensions.windowWidth / 2 - dimensions.toastWidth / 2)
}),
"left center": dimensions => ({
top: Math.round(dimensions.windowHeight / 2 - dimensions.toastHeight / 2),
left: 10
}),
"right center": dimensions => ({
top: Math.round(dimensions.windowHeight / 2 - dimensions.toastHeight / 2),
right: 10
}),
center: dimensions => ({
top: Math.round(dimensions.windowHeight / 2 - dimensions.toastHeight / 2),
left: Math.round(dimensions.windowWidth / 2 - dimensions.toastWidth / 2)
}),
"bottom center": dimensions => ({
bottom: 10,
left: Math.round(dimensions.windowWidth / 2 - dimensions.toastWidth / 2)
})
};
const POSITION_STYLES_MAP = {
up: (coordinates, dimensions) => ({
bottom: coordinates.bottom ?? dimensions.windowHeight - dimensions.toastHeight - (coordinates.top ?? 0),
top: "",
left: coordinates.left ?? "",
right: coordinates.right ?? ""
}),
down: (coordinates, dimensions) => ({
top: coordinates.top ?? dimensions.windowHeight - dimensions.toastHeight - (coordinates.bottom ?? 0),
bottom: "",
left: coordinates.left ?? "",
right: coordinates.right ?? ""
}),
left: (coordinates, dimensions) => ({
right: coordinates.right ?? dimensions.windowWidth - dimensions.toastWidth - (coordinates.left ?? 0),
left: "",
top: coordinates.top ?? "",
bottom: coordinates.bottom ?? ""
}),
right: (coordinates, dimensions) => ({
left: coordinates.left ?? dimensions.windowWidth - dimensions.toastWidth - (coordinates.right ?? 0),
right: "",
top: coordinates.top ?? "",
bottom: coordinates.bottom ?? ""
})
};
const getDefaultDirection = position => {
const condition = isString(position) && position.includes("top");
return condition ? "down-push" : "up-push"
};
const createStackContainer = key => {
const $container = $("<div>").appendTo(viewPort());
$containers[key] = $container;
return $container
};
const getStackContainer = key => {
const $container = $containers[key];
return $container || createStackContainer(key)
};
const setContainerClasses = (container, direction) => {
const containerClasses = `dx-toast-stack dx-toast-stack-${direction}-direction`;
container.removeAttr("class").addClass(containerClasses)
};
const getNotifyCoordinatesByAlias = (alias, dimensions) => {
const coordinate = alias ? COORDINATE_ALIASES[alias] : COORDINATE_ALIASES["bottom center"];
return "function" === typeof coordinate ? coordinate(dimensions) : coordinate
};
const getPositionStylesByNotifyCoordinates = (direction, coordinates, dimensions) => {
const directionKey = direction.replace(/-push|-stack/g, "");
const styleFunction = POSITION_STYLES_MAP[directionKey];
return styleFunction ? styleFunction(coordinates, dimensions) : {
top: "",
bottom: "",
left: "",
right: ""
}
};
const setContainerStyles = (container, direction, position) => {
const {
offsetWidth: toastWidth,
offsetHeight: toastHeight
} = container.children().first().get(0);
const dimensions = {
toastWidth: toastWidth,
toastHeight: toastHeight,
windowHeight: window.innerHeight,
windowWidth: window.innerWidth
};
const coordinates = isString(position) ? getNotifyCoordinatesByAlias(position, dimensions) : position;
const styles = getPositionStylesByNotifyCoordinates(direction, coordinates, dimensions);
container.css(styles)
};
const getToastOptions = (message, typeOrStack, displayTime) => {
const userOptions = isPlainObject(message) ? message : {
message: message
};
const stack = isPlainObject(typeOrStack) ? typeOrStack : void 0;
const type = isPlainObject(typeOrStack) ? void 0 : typeOrStack;
const {
onHidden: userOnHidden,
onShowing: userOnShowing
} = userOptions;
const defaultConfiguration = {
onHidden: e => {
$(e.element).remove();
null === userOnHidden || void 0 === userOnHidden || userOnHidden(e)
}
};
if (void 0 !== type) {
defaultConfiguration.type = type
}
if (void 0 !== displayTime) {
defaultConfiguration.displayTime = displayTime
}
if (null !== stack && void 0 !== stack && stack.position) {
const {
position: position
} = stack;
const direction = stack.direction || getDefaultDirection(position);
const containerKey = isString(position) ? position : `${position.top}-${position.left}-${position.bottom}-${position.right}`;
const $container = getStackContainer(containerKey);
setContainerClasses($container, direction);
const options = Object.assign({}, userOptions, defaultConfiguration, {
container: $container,
_skipContentPositioning: true,
onShowing: e => {
setContainerStyles($container, direction, position);
null === userOnShowing || void 0 === userOnShowing || userOnShowing(e)
}
});
return options
}
const options = Object.assign({}, userOptions, defaultConfiguration);
return options
};
const notify = (message, typeOrStack, displayTime) => {
const options = getToastOptions(message, typeOrStack, displayTime);
$notify = $("<div>").appendTo(viewPort());
const toast = new Toast($notify, options);
toast.show()
};
export default notify;