UNPKG

@yamada-ui/notice

Version:

Yamada UI notice component

270 lines (269 loc) • 8.93 kB
"use client" "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/notice.tsx var notice_exports = {}; __export(notice_exports, { noticeStore: () => noticeStore, useNotice: () => useNotice }); module.exports = __toCommonJS(notice_exports); var import_alert = require("@yamada-ui/alert"); var import_close_button = require("@yamada-ui/close-button"); var import_core = require("@yamada-ui/core"); var import_utils = require("@yamada-ui/utils"); var import_react = require("react"); var import_jsx_runtime = require("react/jsx-runtime"); var findId = (options, id) => options.find((notice) => notice.id === id); var findNotice = (state, id) => { const placement = getNoticePlacement(state, id); const index = placement ? state[placement].findIndex((notice) => notice.id === id) : -1; return { index, placement }; }; var getNoticePlacement = (state, id) => { for (const [placement, values] of Object.entries(state)) { if (findId(values, id)) return placement; } }; var counter = 0; var createNotice = (message, { id, style, duration, placement = "top", status, onCloseComplete }) => { counter += 1; id != null ? id : id = counter; return { id, style, duration, isDelete: false, message, placement, status, onCloseComplete, onDelete: () => noticeStore.remove(String(id), placement) }; }; var createRender = (options) => { const { component } = options; const Render = (props) => { if (typeof component === "function") { return component({ ...props, ...options }); } else { return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Notice, { ...props, ...options }); } }; return Render; }; var createNoticeFunc = (defaultOptions, theme) => { var _a, _b, _c; const themeOptions = (_c = (_b = (_a = theme.__config) == null ? void 0 : _a.notice) == null ? void 0 : _b.options) != null ? _c : {}; const computedOptions = (options) => (0, import_utils.merge)(themeOptions, (0, import_utils.merge)(defaultOptions, options)); const notice = (options = {}) => { options = computedOptions(options); const message = createRender(options); return noticeStore.create(message, options); }; notice.update = (id, options) => { options = computedOptions(options); noticeStore.update(id, options); }; notice.closeAll = noticeStore.closeAll; notice.close = noticeStore.close; notice.isActive = noticeStore.isActive; return notice; }; var useNotice = (defaultOptions) => { const { theme } = (0, import_core.useTheme)(); return (0, import_react.useMemo)( () => createNoticeFunc(defaultOptions != null ? defaultOptions : {}, theme), [defaultOptions, theme] ); }; var initialState = { bottom: [], "bottom-left": [], "bottom-right": [], top: [], "top-left": [], "top-right": [] }; var createNoticeStore = (initialState2) => { let state = initialState2; const storeChangeCache = /* @__PURE__ */ new Set(); const setState = (setStateFunc) => { state = setStateFunc(state); storeChangeCache.forEach((onStoreChange) => onStoreChange()); }; return { close: (id) => { setState((prev) => { const placement = getNoticePlacement(prev, id); if (!placement) return prev; return { ...prev, [placement]: prev[placement].map( (notice) => notice.id == id ? { ...notice, isDelete: true } : notice ) }; }); }, closeAll: ({ placement } = {}) => { setState((prev) => { let placements = [ "bottom", "bottom-right", "bottom-left", "top", "top-left", "top-right" ]; if (placement) placements = placement; return placements.reduce( (acc, placement2) => { acc[placement2] = prev[placement2].map((notice) => ({ ...notice, isDelete: true })); return acc; }, { ...prev } ); }); }, create: (message, options) => { const limit = options.limit; const notice = createNotice(message, options); const { id, placement } = notice; setState((prev) => { let prevNotices = prev[placement]; if (limit !== void 0 && limit > 0 && prevNotices.length > limit - 1) { const n = prevNotices.length - (limit - 1); const notices2 = placement.includes("top") ? prevNotices.slice(n * -1) : prevNotices.slice(0, n); const ids = notices2.map(({ id: id2 }) => id2); prevNotices = prevNotices.map( (notice2) => ids.includes(notice2.id) ? { ...notice2, isDelete: true } : notice2 ); } const notices = placement.includes("top") ? [notice, ...prevNotices] : [...prevNotices, notice]; return { ...prev, [placement]: notices }; }); return id; }, getSnapshot: () => state, isActive: (id) => Boolean(findNotice(noticeStore.getSnapshot(), id).placement), remove: (id, placement) => { setState((prevState) => ({ ...prevState, [placement]: prevState[placement].filter((notice) => notice.id != id) })); }, subscribe: (onStoreChange) => { storeChangeCache.add(onStoreChange); return () => { setState(() => initialState2); storeChangeCache.delete(onStoreChange); }; }, update: (id, options) => { setState((prev) => { const next = { ...prev }; const { index, placement } = findNotice(next, id); if (placement && index !== -1 && next[placement][index]) { next[placement][index] = { ...next[placement][index], ...options, message: createRender(options) }; } return next; }); } }; }; var noticeStore = createNoticeStore(initialState); var Notice = ({ className, colorScheme, variant = "basic", closeStrategy = "button", description, icon, isClosable, status, title, onClose }) => { const isButtonClosable = isClosable && (closeStrategy === "button" || closeStrategy === "both"); const isElementClosable = isClosable && (closeStrategy === "element" || closeStrategy === "both"); return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( import_alert.Alert, { className: (0, import_utils.cx)("ui-notice", className), colorScheme, variant, alignItems: "start", boxShadow: "fallback(lg, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05))", pe: isButtonClosable ? 8 : void 0, status, onClick: isElementClosable ? onClose : void 0, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_alert.AlertIcon, { className: "ui-notice__icon", variant: icon == null ? void 0 : icon.variant, ...(icon == null ? void 0 : icon.color) ? { color: icon.color } : {}, children: icon == null ? void 0 : icon.children } ), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_core.ui.div, { flex: "1", children: [ title ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertTitle, { className: "ui-notice__title", lineClamp: 1, children: title }) : null, description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_alert.AlertDescription, { className: "ui-notice__desc", lineClamp: 3, children: description }) : null ] }), isButtonClosable ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_close_button.CloseButton, { className: "ui-notice__close-button", size: "sm", position: "absolute", right: 2, top: 2, onClick: (ev) => { ev.stopPropagation(); onClose == null ? void 0 : onClose(); } } ) : null ] } ); }; Notice.displayName = "Notice"; Notice.__ui__ = "Notice"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { noticeStore, useNotice }); //# sourceMappingURL=notice.js.map