@sparkstudio/common-ui 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -298,11 +298,15 @@ var Modal = ({
298
298
  onConfirm,
299
299
  confirmText = "OK",
300
300
  disableBackdropClose = false,
301
+ disableAllButtons = false,
302
+ showHeaderClose = true,
303
+ showCloseButton = true,
304
+ showConfirmButton = true,
301
305
  children
302
306
  }) => {
303
307
  if (!isOpen) return null;
304
308
  const handleBackdropClick = () => {
305
- if (disableBackdropClose) return;
309
+ if (disableBackdropClose || disableAllButtons) return;
306
310
  onClose();
307
311
  };
308
312
  const handleContentClick = (e) => {
@@ -325,49 +329,44 @@ var Modal = ({
325
329
  role: "dialog",
326
330
  style: { zIndex: 1050 },
327
331
  onClick: handleBackdropClick,
328
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
329
- "div",
330
- {
331
- className: "modal-dialog modal-dialog-centered",
332
- role: "document",
333
- onClick: handleContentClick,
334
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "modal-content shadow", children: [
335
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "modal-header", children: [
336
- title && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h5", { className: "modal-title", children: title }),
337
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
338
- "button",
339
- {
340
- type: "button",
341
- className: "btn-close",
342
- "aria-label": "Close",
343
- onClick: onClose
344
- }
345
- )
346
- ] }),
347
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "modal-body", children }),
348
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "modal-footer", children: [
349
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
350
- "button",
351
- {
352
- type: "button",
353
- className: "btn btn-secondary",
354
- onClick: onClose,
355
- children: "Close"
356
- }
357
- ),
358
- onConfirm && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
359
- "button",
360
- {
361
- type: "button",
362
- className: "btn btn-primary",
363
- onClick: onConfirm,
364
- children: confirmText
365
- }
366
- )
367
- ] })
368
- ] })
369
- }
370
- )
332
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "modal-dialog modal-dialog-centered", role: "document", onClick: handleContentClick, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "modal-content shadow", children: [
333
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "modal-header", children: [
334
+ title && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h5", { className: "modal-title", children: title }),
335
+ showHeaderClose && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
336
+ "button",
337
+ {
338
+ type: "button",
339
+ className: "btn-close",
340
+ "aria-label": "Close",
341
+ onClick: onClose,
342
+ disabled: disableAllButtons
343
+ }
344
+ )
345
+ ] }),
346
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "modal-body", children }),
347
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "modal-footer", children: [
348
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
349
+ "button",
350
+ {
351
+ type: "button",
352
+ className: "btn btn-secondary",
353
+ onClick: onClose,
354
+ disabled: disableAllButtons,
355
+ children: "Close"
356
+ }
357
+ ),
358
+ onConfirm && showConfirmButton && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
359
+ "button",
360
+ {
361
+ type: "button",
362
+ className: "btn btn-primary",
363
+ onClick: onConfirm,
364
+ disabled: disableAllButtons,
365
+ children: confirmText
366
+ }
367
+ )
368
+ ] })
369
+ ] }) })
371
370
  }
372
371
  )
373
372
  ] });
@@ -381,14 +380,11 @@ function ModalProvider({ children }) {
381
380
  const [isOpen, setIsOpen] = (0, import_react4.useState)(false);
382
381
  const [content, setContent] = (0, import_react4.useState)(null);
383
382
  const [options, setOptions] = (0, import_react4.useState)({});
384
- const openModal = (0, import_react4.useCallback)(
385
- (content2, options2) => {
386
- setContent(content2);
387
- setOptions(options2 ?? {});
388
- setIsOpen(true);
389
- },
390
- []
391
- );
383
+ const openModal = (0, import_react4.useCallback)((content2, options2) => {
384
+ setContent(content2);
385
+ setOptions(options2 ?? {});
386
+ setIsOpen(true);
387
+ }, []);
392
388
  const closeModal = (0, import_react4.useCallback)(() => {
393
389
  setIsOpen(false);
394
390
  }, []);
@@ -401,8 +397,12 @@ function ModalProvider({ children }) {
401
397
  title: options.title,
402
398
  confirmText: options.confirmText,
403
399
  disableBackdropClose: options.disableBackdropClose,
400
+ disableAllButtons: options.disableAllButtons,
401
+ showHeaderClose: options.showHeaderClose,
402
+ showCloseButton: options.showCloseButton,
403
+ showConfirmButton: options.showConfirmButton,
404
404
  onClose: closeModal,
405
- onConfirm: options?.onConfirm,
405
+ onConfirm: options.onConfirm,
406
406
  children: content
407
407
  }
408
408
  )
@@ -410,7 +410,7 @@ function ModalProvider({ children }) {
410
410
  }
411
411
  function UseModal() {
412
412
  const ctx = (0, import_react4.useContext)(ModalContext);
413
- if (!ctx) throw new Error("useModal must be used within ModalProvider");
413
+ if (!ctx) throw new Error("UseModal must be used within ModalProvider");
414
414
  return ctx;
415
415
  }
416
416
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/components/Body.tsx","../src/components/Button.tsx","../src/components/Footer.tsx","../src/components/Header.tsx","../src/components/HeaderText.tsx","../src/components/NpmBadge.tsx","../src/components/navigation/Navigation.tsx","../src/components/navigation/NavigationItem.tsx","../src/components/notifications/Notifications.tsx","../src/components/notifications/NotificationsProvider.tsx","../src/components/wrappers/ContentContainer.tsx","../src/components/wrappers/ContentRow.tsx","../src/components/wrappers/LayoutWrapper.tsx","../src/modal/Modal.tsx","../src/modal/ModalProvider.tsx"],"sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./components/Body\";\nexport * from \"./components/Button\";\nexport * from \"./components/Footer\";\nexport * from \"./components/Header\";\nexport * from \"./components/HeaderText\";\nexport * from \"./components/NpmBadge\";\nexport * from \"./components/navigation/Navigation\";\nexport * from \"./components/navigation/NavigationItem\";\nexport * from \"./components/notifications/Notifications\";\nexport * from \"./components/notifications/NotificationsProvider\";\nexport * from \"./components/wrappers/ContentContainer\";\nexport * from \"./components/wrappers/ContentRow\";\nexport * from \"./components/wrappers/LayoutWrapper\";\nexport * from \"./modal/Modal\";\nexport * from \"./modal/ModalProvider\";\n","import type { ReactNode } from \"react\";\r\n\r\ninterface BodyProps {\r\n title: ReactNode;\r\n description?: ReactNode;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Body({ title, description, children }: BodyProps) {\r\n return (\r\n\r\n <main className=\"col p-4\">\r\n <h2>{title}</h2>\r\n\r\n {description && <p>{description}</p>}\r\n {children}\r\n </main>\r\n );\r\n}\r\n","import { useState, type ReactNode, type MouseEvent } from \"react\";\r\n\r\nexport interface ButtonProps {\r\n buttonClassName?: string;\r\n type?: \"button\" | \"submit\" | \"reset\";\r\n disabled?: boolean;\r\n\r\n onAction?: () => Promise<unknown>;\r\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\r\n onDone?: (result: unknown) => void;\r\n onError?: (error: unknown) => void;\r\n onFinally?: () => void;\r\n\r\n children?: ReactNode;\r\n loadingChildren?: ReactNode;\r\n\r\n renderContent?: () => ReactNode;\r\n renderLoading?: () => ReactNode;\r\n\r\n loadingText?: string;\r\n showSpinner?: boolean;\r\n}\r\n\r\nexport function Button({\r\n buttonClassName = \"btn btn-primary btn-lg\",\r\n type = \"button\",\r\n disabled = false,\r\n\r\n onAction,\r\n onClick,\r\n onDone,\r\n onError,\r\n onFinally,\r\n\r\n children = \"Click me\",\r\n\r\n loadingChildren,\r\n renderContent,\r\n renderLoading,\r\n\r\n loadingText = \"Loading...\",\r\n showSpinner = true,\r\n}: ButtonProps) {\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleClick = async (event: MouseEvent<HTMLButtonElement>) => {\r\n if (loading) return;\r\n\r\n onClick?.(event);\r\n if (event.defaultPrevented) return;\r\n if (!onAction) return;\r\n\r\n try {\r\n setLoading(true);\r\n const result = await onAction();\r\n onDone?.(result);\r\n } catch (error) {\r\n onError?.(error);\r\n } finally {\r\n setLoading(false);\r\n onFinally?.();\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n type={type}\r\n className={`${buttonClassName} ${loading ? \"async-btn--loading\" : \"\"}`}\r\n onClick={handleClick}\r\n disabled={disabled || loading}\r\n >\r\n {loading ? (\r\n renderLoading?.() ??\r\n loadingChildren ?? (\r\n <>\r\n {showSpinner && (\r\n <span\r\n className=\"spinner-border spinner-border-sm me-2 async-btn__spinner\"\r\n role=\"status\"\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n {loadingText}\r\n </>\r\n )\r\n ) : (\r\n renderContent?.() ?? children\r\n )}\r\n </button>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface FooterProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Footer({ children }: FooterProps) {\r\n return (\r\n <footer className=\"bg-dark text-white text-center py-2 mt-auto\">\r\n {children ?? \"© 2025 Your Site — All rights reserved\"}\r\n </footer>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Header({ children }: HeaderProps) {\r\n return (\r\n <nav className=\"navbar navbar-dark bg-dark px-3 sticky-top\">\r\n {children ?? (\r\n <span className=\"navbar-brand mb-0 h4\">My Website</span>\r\n )}\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderBrandProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function HeaderText({ children }: HeaderBrandProps) {\r\n return (\r\n <span className=\"navbar-brand mb-0 h4\">\r\n {children}\r\n </span>\r\n );\r\n}\r\n","// components/NpmBadge.tsx\r\ninterface NpmBadgeProps {\r\n packageLabel: string;\r\n packageName: string;\r\n packageUrl: string; // e.g. \"@sparkstudio/authentication-ui\"\r\n color?: string; // optional (default black)\r\n height?: number; // optional (default 22)\r\n}\r\n\r\nexport function NpmBadge({ packageName, packageLabel, packageUrl, color = \"black\", height = 22 }: NpmBadgeProps) {\r\n const encodedLabel = encodeURIComponent(packageLabel);\r\n const badgeUrl = `https://img.shields.io/npm/v/${packageName}?logo=npm&label=${encodedLabel}&color=${color}`;\r\n const npmUrl = packageUrl;\r\n\r\n return (\r\n <a href={npmUrl} target=\"_blank\" rel=\"noopener noreferrer\">\r\n <img src={badgeUrl} alt={`${packageName} version`} style={{ height }} />\r\n </a>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationProps {\r\n title?: ReactNode;\r\n children: ReactNode;\r\n}\r\n\r\nexport function Navigation({ title = \"Navigation\", children }: NavigationProps) {\r\n return (\r\n <nav className=\"col-auto p-3 h-100 d-flex flex-column\">\r\n <h6 className=\"text-muted text-uppercase\">{title}</h6>\r\n\r\n <ul className=\"nav nav-pills flex-column gap-2 mt-3\">\r\n {children}\r\n </ul>\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationItemProps {\r\n title: ReactNode;\r\n type: string;\r\n active?: boolean;\r\n onClick?: (type: string) => void;\r\n}\r\n\r\nexport function NavigationItem({ title, type, active, onClick }: NavigationItemProps) {\r\n return (\r\n <li className=\"nav-item\">\r\n <button\r\n type=\"button\"\r\n className={`nav-link text-start w-100 ${active ? \"active\" : \"\"}`}\r\n onClick={() => onClick?.(type)}\r\n >\r\n {title}\r\n </button>\r\n </li>\r\n );\r\n}\r\n","import { useEffect } from \"react\";\r\n\r\nexport type NotificationType = \"success\" | \"info\" | \"warning\" | \"danger\";\r\n\r\nexport interface Notification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsProps {\r\n notifications: Notification[];\r\n onClose: (id: string) => void;\r\n}\r\n\r\nexport function Notifications({ notifications, onClose }: NotificationsProps) {\r\n useEffect(() => {\r\n notifications.forEach((n) => {\r\n if (!n.autoCloseMs) return;\r\n\r\n const timer = setTimeout(() => onClose(n.id), n.autoCloseMs);\r\n return () => clearTimeout(timer);\r\n });\r\n }, [notifications, onClose]);\r\n\r\n return (\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => onClose(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport type { NotificationType } from \"./Notifications\";\r\n\r\n// Rename to avoid conflict with browser Notification type\r\nexport interface AppNotification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsContextValue {\r\n push: (message: string, type?: NotificationType, autoCloseMs?: number) => void;\r\n}\r\n\r\nconst NotificationsContext = createContext<NotificationsContextValue | undefined>(\r\n undefined\r\n);\r\n\r\ninterface NotificationsProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function NotificationsProvider({ children }: NotificationsProviderProps) {\r\n const [notifications, setNotifications] = useState<AppNotification[]>([]);\r\n\r\n const push = useCallback(\r\n (message: string, type: NotificationType = \"info\", autoCloseMs = 4000) => {\r\n setNotifications((prev) => [\r\n ...prev,\r\n {\r\n id: crypto.randomUUID(),\r\n message,\r\n type,\r\n autoCloseMs,\r\n },\r\n ]);\r\n },\r\n []\r\n );\r\n\r\n const close = useCallback((id: string) => {\r\n setNotifications((list) => list.filter((n) => n.id !== id));\r\n }, []);\r\n\r\n // Handle auto close timers\r\n useEffect(() => {\r\n const timers = notifications.map((n) => {\r\n if (!n.autoCloseMs) return null;\r\n return setTimeout(() => close(n.id), n.autoCloseMs);\r\n });\r\n\r\n return () => {\r\n timers.forEach((t) => t && clearTimeout(t));\r\n };\r\n }, [notifications, close]);\r\n\r\n return (\r\n <NotificationsContext.Provider value={{ push }}>\r\n {/* overlay renderer */}\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => close(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {children}\r\n </NotificationsContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseNotifications(): NotificationsContextValue {\r\n const ctx = useContext(NotificationsContext);\r\n if (!ctx) {\r\n throw new Error(\"useNotifications must be used within a NotificationsProvider\");\r\n }\r\n return ctx;\r\n}\r\n","export function ContentContainer({ children }: React.PropsWithChildren) {\r\n return <div className=\"container-fluid flex-grow-1\">{children}</div>;\r\n}\r\n","export function ContentRow({ children }: React.PropsWithChildren) {\r\n return <div className=\"row h-100 flex-nowrap\">{children}</div>;\r\n}\r\n","\r\nexport function LayoutWrapper({ children }: React.PropsWithChildren) {\r\n return (\r\n\r\n <div className=\"d-flex flex-column min-vh-100\">{children}</div>\r\n );\r\n}\r\n","// components/Modal.tsx\r\nimport React from \"react\";\r\n\r\nexport interface ModalProps {\r\n /** Title shown in the header */\r\n title?: string;\r\n\r\n /** Whether the modal is visible */\r\n isOpen: boolean;\r\n\r\n /** Called when the user clicks the X or the backdrop */\r\n onClose: () => void;\r\n\r\n /** Optional confirm button handler */\r\n onConfirm?: () => void;\r\n\r\n /** Text for the confirm button (if onConfirm is provided) */\r\n confirmText?: string;\r\n\r\n /** Optional: disable closing by clicking backdrop */\r\n disableBackdropClose?: boolean;\r\n\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport const Modal: React.FC<ModalProps> = ({\r\n title,\r\n isOpen,\r\n onClose,\r\n onConfirm,\r\n confirmText = \"OK\",\r\n disableBackdropClose = false,\r\n children,\r\n}) => {\r\n if (!isOpen) return null;\r\n\r\n const handleBackdropClick = () => {\r\n if (disableBackdropClose) return;\r\n onClose();\r\n };\r\n\r\n const handleContentClick: React.MouseEventHandler<HTMLDivElement> = (e) => {\r\n // Prevent clicks inside the dialog from closing it\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <>\r\n {/* Backdrop */}\r\n <div\r\n className=\"modal-backdrop fade show\"\r\n style={{ zIndex: 1040 }}\r\n onClick={handleBackdropClick}\r\n />\r\n\r\n {/* Modal dialog */}\r\n <div\r\n className=\"modal fade show d-block\"\r\n tabIndex={-1}\r\n role=\"dialog\"\r\n style={{ zIndex: 1050 }}\r\n onClick={handleBackdropClick}\r\n >\r\n <div\r\n className=\"modal-dialog modal-dialog-centered\"\r\n role=\"document\"\r\n onClick={handleContentClick}\r\n >\r\n <div className=\"modal-content shadow\">\r\n {/* Header */}\r\n <div className=\"modal-header\">\r\n {title && <h5 className=\"modal-title\">{title}</h5>}\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={onClose}\r\n />\r\n </div>\r\n\r\n {/* Body */}\r\n <div className=\"modal-body\">{children}</div>\r\n\r\n {/* Footer */}\r\n <div className=\"modal-footer\">\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-secondary\"\r\n onClick={onClose}\r\n >\r\n Close\r\n </button>\r\n\r\n {onConfirm && (\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-primary\"\r\n onClick={onConfirm}\r\n >\r\n {confirmText}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </>\r\n );\r\n};\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport { Modal } from \"./Modal\";\r\n\r\ninterface ModalOptions {\r\n title?: string;\r\n confirmText?: string;\r\n disableBackdropClose?: boolean;\r\n onConfirm?: () => void;\r\n}\r\n\r\ninterface ModalContextValue {\r\n openModal: (\r\n content: ReactNode,\r\n options?: ModalOptions\r\n ) => void;\r\n\r\n closeModal: () => void;\r\n}\r\n\r\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\r\n\r\nexport function ModalProvider({ children }: { children: ReactNode }) {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [content, setContent] = useState<ReactNode>(null);\r\n const [options, setOptions] = useState<ModalOptions>({});\r\n\r\n const openModal = useCallback(\r\n (content: ReactNode, options?: ModalOptions) => {\r\n setContent(content);\r\n setOptions(options ?? {});\r\n setIsOpen(true);\r\n },\r\n []\r\n );\r\n\r\n const closeModal = useCallback(() => {\r\n setIsOpen(false);\r\n }, []);\r\n\r\n return (\r\n <ModalContext.Provider value={{ openModal, closeModal }}>\r\n {children}\r\n\r\n <Modal\r\n isOpen={isOpen}\r\n title={options.title}\r\n confirmText={options.confirmText}\r\n disableBackdropClose={options.disableBackdropClose}\r\n onClose={closeModal}\r\n onConfirm={options?.onConfirm}\r\n >\r\n {content}\r\n </Modal>\r\n </ModalContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseModal() {\r\n const ctx = useContext(ModalContext);\r\n if (!ctx) throw new Error(\"useModal must be used within ModalProvider\");\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","content","options"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/components/Body.tsx","../src/components/Button.tsx","../src/components/Footer.tsx","../src/components/Header.tsx","../src/components/HeaderText.tsx","../src/components/NpmBadge.tsx","../src/components/navigation/Navigation.tsx","../src/components/navigation/NavigationItem.tsx","../src/components/notifications/Notifications.tsx","../src/components/notifications/NotificationsProvider.tsx","../src/components/wrappers/ContentContainer.tsx","../src/components/wrappers/ContentRow.tsx","../src/components/wrappers/LayoutWrapper.tsx","../src/modal/Modal.tsx","../src/modal/ModalProvider.tsx"],"sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from \"./components/Body\";\nexport * from \"./components/Button\";\nexport * from \"./components/Footer\";\nexport * from \"./components/Header\";\nexport * from \"./components/HeaderText\";\nexport * from \"./components/NpmBadge\";\nexport * from \"./components/navigation/Navigation\";\nexport * from \"./components/navigation/NavigationItem\";\nexport * from \"./components/notifications/Notifications\";\nexport * from \"./components/notifications/NotificationsProvider\";\nexport * from \"./components/wrappers/ContentContainer\";\nexport * from \"./components/wrappers/ContentRow\";\nexport * from \"./components/wrappers/LayoutWrapper\";\nexport * from \"./modal/Modal\";\nexport * from \"./modal/ModalProvider\";\n","import type { ReactNode } from \"react\";\r\n\r\ninterface BodyProps {\r\n title: ReactNode;\r\n description?: ReactNode;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Body({ title, description, children }: BodyProps) {\r\n return (\r\n\r\n <main className=\"col p-4\">\r\n <h2>{title}</h2>\r\n\r\n {description && <p>{description}</p>}\r\n {children}\r\n </main>\r\n );\r\n}\r\n","import { useState, type ReactNode, type MouseEvent } from \"react\";\r\n\r\nexport interface ButtonProps {\r\n buttonClassName?: string;\r\n type?: \"button\" | \"submit\" | \"reset\";\r\n disabled?: boolean;\r\n\r\n onAction?: () => Promise<unknown>;\r\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\r\n onDone?: (result: unknown) => void;\r\n onError?: (error: unknown) => void;\r\n onFinally?: () => void;\r\n\r\n children?: ReactNode;\r\n loadingChildren?: ReactNode;\r\n\r\n renderContent?: () => ReactNode;\r\n renderLoading?: () => ReactNode;\r\n\r\n loadingText?: string;\r\n showSpinner?: boolean;\r\n}\r\n\r\nexport function Button({\r\n buttonClassName = \"btn btn-primary btn-lg\",\r\n type = \"button\",\r\n disabled = false,\r\n\r\n onAction,\r\n onClick,\r\n onDone,\r\n onError,\r\n onFinally,\r\n\r\n children = \"Click me\",\r\n\r\n loadingChildren,\r\n renderContent,\r\n renderLoading,\r\n\r\n loadingText = \"Loading...\",\r\n showSpinner = true,\r\n}: ButtonProps) {\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleClick = async (event: MouseEvent<HTMLButtonElement>) => {\r\n if (loading) return;\r\n\r\n onClick?.(event);\r\n if (event.defaultPrevented) return;\r\n if (!onAction) return;\r\n\r\n try {\r\n setLoading(true);\r\n const result = await onAction();\r\n onDone?.(result);\r\n } catch (error) {\r\n onError?.(error);\r\n } finally {\r\n setLoading(false);\r\n onFinally?.();\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n type={type}\r\n className={`${buttonClassName} ${loading ? \"async-btn--loading\" : \"\"}`}\r\n onClick={handleClick}\r\n disabled={disabled || loading}\r\n >\r\n {loading ? (\r\n renderLoading?.() ??\r\n loadingChildren ?? (\r\n <>\r\n {showSpinner && (\r\n <span\r\n className=\"spinner-border spinner-border-sm me-2 async-btn__spinner\"\r\n role=\"status\"\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n {loadingText}\r\n </>\r\n )\r\n ) : (\r\n renderContent?.() ?? children\r\n )}\r\n </button>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface FooterProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Footer({ children }: FooterProps) {\r\n return (\r\n <footer className=\"bg-dark text-white text-center py-2 mt-auto\">\r\n {children ?? \"© 2025 Your Site — All rights reserved\"}\r\n </footer>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Header({ children }: HeaderProps) {\r\n return (\r\n <nav className=\"navbar navbar-dark bg-dark px-3 sticky-top\">\r\n {children ?? (\r\n <span className=\"navbar-brand mb-0 h4\">My Website</span>\r\n )}\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderBrandProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function HeaderText({ children }: HeaderBrandProps) {\r\n return (\r\n <span className=\"navbar-brand mb-0 h4\">\r\n {children}\r\n </span>\r\n );\r\n}\r\n","// components/NpmBadge.tsx\r\ninterface NpmBadgeProps {\r\n packageLabel: string;\r\n packageName: string;\r\n packageUrl: string; // e.g. \"@sparkstudio/authentication-ui\"\r\n color?: string; // optional (default black)\r\n height?: number; // optional (default 22)\r\n}\r\n\r\nexport function NpmBadge({ packageName, packageLabel, packageUrl, color = \"black\", height = 22 }: NpmBadgeProps) {\r\n const encodedLabel = encodeURIComponent(packageLabel);\r\n const badgeUrl = `https://img.shields.io/npm/v/${packageName}?logo=npm&label=${encodedLabel}&color=${color}`;\r\n const npmUrl = packageUrl;\r\n\r\n return (\r\n <a href={npmUrl} target=\"_blank\" rel=\"noopener noreferrer\">\r\n <img src={badgeUrl} alt={`${packageName} version`} style={{ height }} />\r\n </a>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationProps {\r\n title?: ReactNode;\r\n children: ReactNode;\r\n}\r\n\r\nexport function Navigation({ title = \"Navigation\", children }: NavigationProps) {\r\n return (\r\n <nav className=\"col-auto p-3 h-100 d-flex flex-column\">\r\n <h6 className=\"text-muted text-uppercase\">{title}</h6>\r\n\r\n <ul className=\"nav nav-pills flex-column gap-2 mt-3\">\r\n {children}\r\n </ul>\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationItemProps {\r\n title: ReactNode;\r\n type: string;\r\n active?: boolean;\r\n onClick?: (type: string) => void;\r\n}\r\n\r\nexport function NavigationItem({ title, type, active, onClick }: NavigationItemProps) {\r\n return (\r\n <li className=\"nav-item\">\r\n <button\r\n type=\"button\"\r\n className={`nav-link text-start w-100 ${active ? \"active\" : \"\"}`}\r\n onClick={() => onClick?.(type)}\r\n >\r\n {title}\r\n </button>\r\n </li>\r\n );\r\n}\r\n","import { useEffect } from \"react\";\r\n\r\nexport type NotificationType = \"success\" | \"info\" | \"warning\" | \"danger\";\r\n\r\nexport interface Notification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsProps {\r\n notifications: Notification[];\r\n onClose: (id: string) => void;\r\n}\r\n\r\nexport function Notifications({ notifications, onClose }: NotificationsProps) {\r\n useEffect(() => {\r\n notifications.forEach((n) => {\r\n if (!n.autoCloseMs) return;\r\n\r\n const timer = setTimeout(() => onClose(n.id), n.autoCloseMs);\r\n return () => clearTimeout(timer);\r\n });\r\n }, [notifications, onClose]);\r\n\r\n return (\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => onClose(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport type { NotificationType } from \"./Notifications\";\r\n\r\n// Rename to avoid conflict with browser Notification type\r\nexport interface AppNotification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsContextValue {\r\n push: (message: string, type?: NotificationType, autoCloseMs?: number) => void;\r\n}\r\n\r\nconst NotificationsContext = createContext<NotificationsContextValue | undefined>(\r\n undefined\r\n);\r\n\r\ninterface NotificationsProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function NotificationsProvider({ children }: NotificationsProviderProps) {\r\n const [notifications, setNotifications] = useState<AppNotification[]>([]);\r\n\r\n const push = useCallback(\r\n (message: string, type: NotificationType = \"info\", autoCloseMs = 4000) => {\r\n setNotifications((prev) => [\r\n ...prev,\r\n {\r\n id: crypto.randomUUID(),\r\n message,\r\n type,\r\n autoCloseMs,\r\n },\r\n ]);\r\n },\r\n []\r\n );\r\n\r\n const close = useCallback((id: string) => {\r\n setNotifications((list) => list.filter((n) => n.id !== id));\r\n }, []);\r\n\r\n // Handle auto close timers\r\n useEffect(() => {\r\n const timers = notifications.map((n) => {\r\n if (!n.autoCloseMs) return null;\r\n return setTimeout(() => close(n.id), n.autoCloseMs);\r\n });\r\n\r\n return () => {\r\n timers.forEach((t) => t && clearTimeout(t));\r\n };\r\n }, [notifications, close]);\r\n\r\n return (\r\n <NotificationsContext.Provider value={{ push }}>\r\n {/* overlay renderer */}\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => close(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {children}\r\n </NotificationsContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseNotifications(): NotificationsContextValue {\r\n const ctx = useContext(NotificationsContext);\r\n if (!ctx) {\r\n throw new Error(\"useNotifications must be used within a NotificationsProvider\");\r\n }\r\n return ctx;\r\n}\r\n","export function ContentContainer({ children }: React.PropsWithChildren) {\r\n return <div className=\"container-fluid flex-grow-1\">{children}</div>;\r\n}\r\n","export function ContentRow({ children }: React.PropsWithChildren) {\r\n return <div className=\"row h-100 flex-nowrap\">{children}</div>;\r\n}\r\n","\r\nexport function LayoutWrapper({ children }: React.PropsWithChildren) {\r\n return (\r\n\r\n <div className=\"d-flex flex-column min-vh-100\">{children}</div>\r\n );\r\n}\r\n","// components/Modal.tsx\r\nimport React from \"react\";\r\n\r\nexport interface ModalProps {\r\n title?: string;\r\n isOpen: boolean;\r\n onClose: () => void;\r\n onConfirm?: () => void;\r\n confirmText?: string;\r\n\r\n disableBackdropClose?: boolean;\r\n disableAllButtons?: boolean;\r\n\r\n /** NEW: toggle visibility */\r\n showHeaderClose?: boolean;\r\n showCloseButton?: boolean;\r\n showConfirmButton?: boolean;\r\n\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport const Modal: React.FC<ModalProps> = ({\r\n title,\r\n isOpen,\r\n onClose,\r\n onConfirm,\r\n confirmText = \"OK\",\r\n\r\n disableBackdropClose = false,\r\n disableAllButtons = false,\r\n\r\n showHeaderClose = true,\r\n showCloseButton = true,\r\n showConfirmButton = true,\r\n\r\n children,\r\n}) => {\r\n if (!isOpen) return null;\r\n\r\n const handleBackdropClick = () => {\r\n if (disableBackdropClose || disableAllButtons) return;\r\n onClose();\r\n };\r\n\r\n const handleContentClick: React.MouseEventHandler<HTMLDivElement> = (e) => {\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <>\r\n <div\r\n className=\"modal-backdrop fade show\"\r\n style={{ zIndex: 1040 }}\r\n onClick={handleBackdropClick}\r\n />\r\n\r\n <div\r\n className=\"modal fade show d-block\"\r\n tabIndex={-1}\r\n role=\"dialog\"\r\n style={{ zIndex: 1050 }}\r\n onClick={handleBackdropClick}\r\n >\r\n <div className=\"modal-dialog modal-dialog-centered\" role=\"document\" onClick={handleContentClick}>\r\n <div className=\"modal-content shadow\">\r\n {/* Header */}\r\n <div className=\"modal-header\">\r\n {title && <h5 className=\"modal-title\">{title}</h5>}\r\n\r\n {showHeaderClose && (\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={onClose}\r\n disabled={disableAllButtons}\r\n />\r\n )}\r\n </div>\r\n\r\n {/* Body */}\r\n <div className=\"modal-body\">{children}</div>\r\n\r\n {/* Footer */}\r\n <div className=\"modal-footer\">\r\n {showCloseButton && (\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-secondary\"\r\n onClick={onClose}\r\n disabled={disableAllButtons}\r\n >\r\n Close\r\n </button>\r\n )}\r\n\r\n {onConfirm && showConfirmButton && (\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-primary\"\r\n onClick={onConfirm}\r\n disabled={disableAllButtons}\r\n >\r\n {confirmText}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </>\r\n );\r\n};\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport { Modal } from \"./Modal\";\r\n\r\nexport interface ModalOptions {\r\n title?: string;\r\n confirmText?: string;\r\n disableBackdropClose?: boolean;\r\n onConfirm?: () => void;\r\n\r\n /** extra control flags matching Modal.tsx */\r\n disableAllButtons?: boolean;\r\n showHeaderClose?: boolean;\r\n showCloseButton?: boolean;\r\n showConfirmButton?: boolean;\r\n}\r\n\r\ninterface ModalContextValue {\r\n openModal: (content: ReactNode, options?: ModalOptions) => void;\r\n closeModal: () => void;\r\n}\r\n\r\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\r\n\r\nexport function ModalProvider({ children }: { children: ReactNode }) {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [content, setContent] = useState<ReactNode>(null);\r\n const [options, setOptions] = useState<ModalOptions>({});\r\n\r\n const openModal = useCallback((content: ReactNode, options?: ModalOptions) => {\r\n setContent(content);\r\n setOptions(options ?? {});\r\n setIsOpen(true);\r\n }, []);\r\n\r\n const closeModal = useCallback(() => {\r\n setIsOpen(false);\r\n }, []);\r\n\r\n return (\r\n <ModalContext.Provider value={{ openModal, closeModal }}>\r\n {children}\r\n\r\n <Modal\r\n isOpen={isOpen}\r\n title={options.title}\r\n confirmText={options.confirmText}\r\n disableBackdropClose={options.disableBackdropClose}\r\n disableAllButtons={options.disableAllButtons}\r\n showHeaderClose={options.showHeaderClose}\r\n showCloseButton={options.showCloseButton}\r\n showConfirmButton={options.showConfirmButton}\r\n onClose={closeModal}\r\n onConfirm={options.onConfirm}\r\n >\r\n {content}\r\n </Modal>\r\n </ModalContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseModal() {\r\n const ctx = useContext(ModalContext);\r\n if (!ctx) throw new Error(\"UseModal must be used within ModalProvider\");\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","content","options"]}
package/dist/index.d.cts CHANGED
@@ -99,18 +99,17 @@ declare function ContentRow({ children }: React.PropsWithChildren): react_jsx_ru
99
99
  declare function LayoutWrapper({ children }: React.PropsWithChildren): react_jsx_runtime.JSX.Element;
100
100
 
101
101
  interface ModalProps {
102
- /** Title shown in the header */
103
102
  title?: string;
104
- /** Whether the modal is visible */
105
103
  isOpen: boolean;
106
- /** Called when the user clicks the X or the backdrop */
107
104
  onClose: () => void;
108
- /** Optional confirm button handler */
109
105
  onConfirm?: () => void;
110
- /** Text for the confirm button (if onConfirm is provided) */
111
106
  confirmText?: string;
112
- /** Optional: disable closing by clicking backdrop */
113
107
  disableBackdropClose?: boolean;
108
+ disableAllButtons?: boolean;
109
+ /** NEW: toggle visibility */
110
+ showHeaderClose?: boolean;
111
+ showCloseButton?: boolean;
112
+ showConfirmButton?: boolean;
114
113
  children?: React$1.ReactNode;
115
114
  }
116
115
  declare const Modal: React$1.FC<ModalProps>;
@@ -120,6 +119,11 @@ interface ModalOptions {
120
119
  confirmText?: string;
121
120
  disableBackdropClose?: boolean;
122
121
  onConfirm?: () => void;
122
+ /** extra control flags matching Modal.tsx */
123
+ disableAllButtons?: boolean;
124
+ showHeaderClose?: boolean;
125
+ showCloseButton?: boolean;
126
+ showConfirmButton?: boolean;
123
127
  }
124
128
  interface ModalContextValue {
125
129
  openModal: (content: ReactNode, options?: ModalOptions) => void;
@@ -130,4 +134,4 @@ declare function ModalProvider({ children }: {
130
134
  }): react_jsx_runtime.JSX.Element;
131
135
  declare function UseModal(): ModalContextValue;
132
136
 
133
- export { type AppNotification, Body, Button, type ButtonProps, ContentContainer, ContentRow, Footer, Header, HeaderText, LayoutWrapper, Modal, type ModalProps, ModalProvider, Navigation, NavigationItem, type Notification, type NotificationType, Notifications, NotificationsProvider, NpmBadge, UseModal, UseNotifications };
137
+ export { type AppNotification, Body, Button, type ButtonProps, ContentContainer, ContentRow, Footer, Header, HeaderText, LayoutWrapper, Modal, type ModalOptions, type ModalProps, ModalProvider, Navigation, NavigationItem, type Notification, type NotificationType, Notifications, NotificationsProvider, NpmBadge, UseModal, UseNotifications };
package/dist/index.d.ts CHANGED
@@ -99,18 +99,17 @@ declare function ContentRow({ children }: React.PropsWithChildren): react_jsx_ru
99
99
  declare function LayoutWrapper({ children }: React.PropsWithChildren): react_jsx_runtime.JSX.Element;
100
100
 
101
101
  interface ModalProps {
102
- /** Title shown in the header */
103
102
  title?: string;
104
- /** Whether the modal is visible */
105
103
  isOpen: boolean;
106
- /** Called when the user clicks the X or the backdrop */
107
104
  onClose: () => void;
108
- /** Optional confirm button handler */
109
105
  onConfirm?: () => void;
110
- /** Text for the confirm button (if onConfirm is provided) */
111
106
  confirmText?: string;
112
- /** Optional: disable closing by clicking backdrop */
113
107
  disableBackdropClose?: boolean;
108
+ disableAllButtons?: boolean;
109
+ /** NEW: toggle visibility */
110
+ showHeaderClose?: boolean;
111
+ showCloseButton?: boolean;
112
+ showConfirmButton?: boolean;
114
113
  children?: React$1.ReactNode;
115
114
  }
116
115
  declare const Modal: React$1.FC<ModalProps>;
@@ -120,6 +119,11 @@ interface ModalOptions {
120
119
  confirmText?: string;
121
120
  disableBackdropClose?: boolean;
122
121
  onConfirm?: () => void;
122
+ /** extra control flags matching Modal.tsx */
123
+ disableAllButtons?: boolean;
124
+ showHeaderClose?: boolean;
125
+ showCloseButton?: boolean;
126
+ showConfirmButton?: boolean;
123
127
  }
124
128
  interface ModalContextValue {
125
129
  openModal: (content: ReactNode, options?: ModalOptions) => void;
@@ -130,4 +134,4 @@ declare function ModalProvider({ children }: {
130
134
  }): react_jsx_runtime.JSX.Element;
131
135
  declare function UseModal(): ModalContextValue;
132
136
 
133
- export { type AppNotification, Body, Button, type ButtonProps, ContentContainer, ContentRow, Footer, Header, HeaderText, LayoutWrapper, Modal, type ModalProps, ModalProvider, Navigation, NavigationItem, type Notification, type NotificationType, Notifications, NotificationsProvider, NpmBadge, UseModal, UseNotifications };
137
+ export { type AppNotification, Body, Button, type ButtonProps, ContentContainer, ContentRow, Footer, Header, HeaderText, LayoutWrapper, Modal, type ModalOptions, type ModalProps, ModalProvider, Navigation, NavigationItem, type Notification, type NotificationType, Notifications, NotificationsProvider, NpmBadge, UseModal, UseNotifications };
package/dist/index.js CHANGED
@@ -262,11 +262,15 @@ var Modal = ({
262
262
  onConfirm,
263
263
  confirmText = "OK",
264
264
  disableBackdropClose = false,
265
+ disableAllButtons = false,
266
+ showHeaderClose = true,
267
+ showCloseButton = true,
268
+ showConfirmButton = true,
265
269
  children
266
270
  }) => {
267
271
  if (!isOpen) return null;
268
272
  const handleBackdropClick = () => {
269
- if (disableBackdropClose) return;
273
+ if (disableBackdropClose || disableAllButtons) return;
270
274
  onClose();
271
275
  };
272
276
  const handleContentClick = (e) => {
@@ -289,49 +293,44 @@ var Modal = ({
289
293
  role: "dialog",
290
294
  style: { zIndex: 1050 },
291
295
  onClick: handleBackdropClick,
292
- children: /* @__PURE__ */ jsx14(
293
- "div",
294
- {
295
- className: "modal-dialog modal-dialog-centered",
296
- role: "document",
297
- onClick: handleContentClick,
298
- children: /* @__PURE__ */ jsxs6("div", { className: "modal-content shadow", children: [
299
- /* @__PURE__ */ jsxs6("div", { className: "modal-header", children: [
300
- title && /* @__PURE__ */ jsx14("h5", { className: "modal-title", children: title }),
301
- /* @__PURE__ */ jsx14(
302
- "button",
303
- {
304
- type: "button",
305
- className: "btn-close",
306
- "aria-label": "Close",
307
- onClick: onClose
308
- }
309
- )
310
- ] }),
311
- /* @__PURE__ */ jsx14("div", { className: "modal-body", children }),
312
- /* @__PURE__ */ jsxs6("div", { className: "modal-footer", children: [
313
- /* @__PURE__ */ jsx14(
314
- "button",
315
- {
316
- type: "button",
317
- className: "btn btn-secondary",
318
- onClick: onClose,
319
- children: "Close"
320
- }
321
- ),
322
- onConfirm && /* @__PURE__ */ jsx14(
323
- "button",
324
- {
325
- type: "button",
326
- className: "btn btn-primary",
327
- onClick: onConfirm,
328
- children: confirmText
329
- }
330
- )
331
- ] })
332
- ] })
333
- }
334
- )
296
+ children: /* @__PURE__ */ jsx14("div", { className: "modal-dialog modal-dialog-centered", role: "document", onClick: handleContentClick, children: /* @__PURE__ */ jsxs6("div", { className: "modal-content shadow", children: [
297
+ /* @__PURE__ */ jsxs6("div", { className: "modal-header", children: [
298
+ title && /* @__PURE__ */ jsx14("h5", { className: "modal-title", children: title }),
299
+ showHeaderClose && /* @__PURE__ */ jsx14(
300
+ "button",
301
+ {
302
+ type: "button",
303
+ className: "btn-close",
304
+ "aria-label": "Close",
305
+ onClick: onClose,
306
+ disabled: disableAllButtons
307
+ }
308
+ )
309
+ ] }),
310
+ /* @__PURE__ */ jsx14("div", { className: "modal-body", children }),
311
+ /* @__PURE__ */ jsxs6("div", { className: "modal-footer", children: [
312
+ showCloseButton && /* @__PURE__ */ jsx14(
313
+ "button",
314
+ {
315
+ type: "button",
316
+ className: "btn btn-secondary",
317
+ onClick: onClose,
318
+ disabled: disableAllButtons,
319
+ children: "Close"
320
+ }
321
+ ),
322
+ onConfirm && showConfirmButton && /* @__PURE__ */ jsx14(
323
+ "button",
324
+ {
325
+ type: "button",
326
+ className: "btn btn-primary",
327
+ onClick: onConfirm,
328
+ disabled: disableAllButtons,
329
+ children: confirmText
330
+ }
331
+ )
332
+ ] })
333
+ ] }) })
335
334
  }
336
335
  )
337
336
  ] });
@@ -350,14 +349,11 @@ function ModalProvider({ children }) {
350
349
  const [isOpen, setIsOpen] = useState3(false);
351
350
  const [content, setContent] = useState3(null);
352
351
  const [options, setOptions] = useState3({});
353
- const openModal = useCallback2(
354
- (content2, options2) => {
355
- setContent(content2);
356
- setOptions(options2 ?? {});
357
- setIsOpen(true);
358
- },
359
- []
360
- );
352
+ const openModal = useCallback2((content2, options2) => {
353
+ setContent(content2);
354
+ setOptions(options2 ?? {});
355
+ setIsOpen(true);
356
+ }, []);
361
357
  const closeModal = useCallback2(() => {
362
358
  setIsOpen(false);
363
359
  }, []);
@@ -370,8 +366,12 @@ function ModalProvider({ children }) {
370
366
  title: options.title,
371
367
  confirmText: options.confirmText,
372
368
  disableBackdropClose: options.disableBackdropClose,
369
+ disableAllButtons: options.disableAllButtons,
370
+ showHeaderClose: options.showHeaderClose,
371
+ showCloseButton: options.showCloseButton,
372
+ showConfirmButton: options.showConfirmButton,
373
373
  onClose: closeModal,
374
- onConfirm: options?.onConfirm,
374
+ onConfirm: options.onConfirm,
375
375
  children: content
376
376
  }
377
377
  )
@@ -379,7 +379,7 @@ function ModalProvider({ children }) {
379
379
  }
380
380
  function UseModal() {
381
381
  const ctx = useContext2(ModalContext);
382
- if (!ctx) throw new Error("useModal must be used within ModalProvider");
382
+ if (!ctx) throw new Error("UseModal must be used within ModalProvider");
383
383
  return ctx;
384
384
  }
385
385
  export {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Body.tsx","../src/components/Button.tsx","../src/components/Footer.tsx","../src/components/Header.tsx","../src/components/HeaderText.tsx","../src/components/NpmBadge.tsx","../src/components/navigation/Navigation.tsx","../src/components/navigation/NavigationItem.tsx","../src/components/notifications/Notifications.tsx","../src/components/notifications/NotificationsProvider.tsx","../src/components/wrappers/ContentContainer.tsx","../src/components/wrappers/ContentRow.tsx","../src/components/wrappers/LayoutWrapper.tsx","../src/modal/Modal.tsx","../src/modal/ModalProvider.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\r\n\r\ninterface BodyProps {\r\n title: ReactNode;\r\n description?: ReactNode;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Body({ title, description, children }: BodyProps) {\r\n return (\r\n\r\n <main className=\"col p-4\">\r\n <h2>{title}</h2>\r\n\r\n {description && <p>{description}</p>}\r\n {children}\r\n </main>\r\n );\r\n}\r\n","import { useState, type ReactNode, type MouseEvent } from \"react\";\r\n\r\nexport interface ButtonProps {\r\n buttonClassName?: string;\r\n type?: \"button\" | \"submit\" | \"reset\";\r\n disabled?: boolean;\r\n\r\n onAction?: () => Promise<unknown>;\r\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\r\n onDone?: (result: unknown) => void;\r\n onError?: (error: unknown) => void;\r\n onFinally?: () => void;\r\n\r\n children?: ReactNode;\r\n loadingChildren?: ReactNode;\r\n\r\n renderContent?: () => ReactNode;\r\n renderLoading?: () => ReactNode;\r\n\r\n loadingText?: string;\r\n showSpinner?: boolean;\r\n}\r\n\r\nexport function Button({\r\n buttonClassName = \"btn btn-primary btn-lg\",\r\n type = \"button\",\r\n disabled = false,\r\n\r\n onAction,\r\n onClick,\r\n onDone,\r\n onError,\r\n onFinally,\r\n\r\n children = \"Click me\",\r\n\r\n loadingChildren,\r\n renderContent,\r\n renderLoading,\r\n\r\n loadingText = \"Loading...\",\r\n showSpinner = true,\r\n}: ButtonProps) {\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleClick = async (event: MouseEvent<HTMLButtonElement>) => {\r\n if (loading) return;\r\n\r\n onClick?.(event);\r\n if (event.defaultPrevented) return;\r\n if (!onAction) return;\r\n\r\n try {\r\n setLoading(true);\r\n const result = await onAction();\r\n onDone?.(result);\r\n } catch (error) {\r\n onError?.(error);\r\n } finally {\r\n setLoading(false);\r\n onFinally?.();\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n type={type}\r\n className={`${buttonClassName} ${loading ? \"async-btn--loading\" : \"\"}`}\r\n onClick={handleClick}\r\n disabled={disabled || loading}\r\n >\r\n {loading ? (\r\n renderLoading?.() ??\r\n loadingChildren ?? (\r\n <>\r\n {showSpinner && (\r\n <span\r\n className=\"spinner-border spinner-border-sm me-2 async-btn__spinner\"\r\n role=\"status\"\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n {loadingText}\r\n </>\r\n )\r\n ) : (\r\n renderContent?.() ?? children\r\n )}\r\n </button>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface FooterProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Footer({ children }: FooterProps) {\r\n return (\r\n <footer className=\"bg-dark text-white text-center py-2 mt-auto\">\r\n {children ?? \"© 2025 Your Site — All rights reserved\"}\r\n </footer>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Header({ children }: HeaderProps) {\r\n return (\r\n <nav className=\"navbar navbar-dark bg-dark px-3 sticky-top\">\r\n {children ?? (\r\n <span className=\"navbar-brand mb-0 h4\">My Website</span>\r\n )}\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderBrandProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function HeaderText({ children }: HeaderBrandProps) {\r\n return (\r\n <span className=\"navbar-brand mb-0 h4\">\r\n {children}\r\n </span>\r\n );\r\n}\r\n","// components/NpmBadge.tsx\r\ninterface NpmBadgeProps {\r\n packageLabel: string;\r\n packageName: string;\r\n packageUrl: string; // e.g. \"@sparkstudio/authentication-ui\"\r\n color?: string; // optional (default black)\r\n height?: number; // optional (default 22)\r\n}\r\n\r\nexport function NpmBadge({ packageName, packageLabel, packageUrl, color = \"black\", height = 22 }: NpmBadgeProps) {\r\n const encodedLabel = encodeURIComponent(packageLabel);\r\n const badgeUrl = `https://img.shields.io/npm/v/${packageName}?logo=npm&label=${encodedLabel}&color=${color}`;\r\n const npmUrl = packageUrl;\r\n\r\n return (\r\n <a href={npmUrl} target=\"_blank\" rel=\"noopener noreferrer\">\r\n <img src={badgeUrl} alt={`${packageName} version`} style={{ height }} />\r\n </a>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationProps {\r\n title?: ReactNode;\r\n children: ReactNode;\r\n}\r\n\r\nexport function Navigation({ title = \"Navigation\", children }: NavigationProps) {\r\n return (\r\n <nav className=\"col-auto p-3 h-100 d-flex flex-column\">\r\n <h6 className=\"text-muted text-uppercase\">{title}</h6>\r\n\r\n <ul className=\"nav nav-pills flex-column gap-2 mt-3\">\r\n {children}\r\n </ul>\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationItemProps {\r\n title: ReactNode;\r\n type: string;\r\n active?: boolean;\r\n onClick?: (type: string) => void;\r\n}\r\n\r\nexport function NavigationItem({ title, type, active, onClick }: NavigationItemProps) {\r\n return (\r\n <li className=\"nav-item\">\r\n <button\r\n type=\"button\"\r\n className={`nav-link text-start w-100 ${active ? \"active\" : \"\"}`}\r\n onClick={() => onClick?.(type)}\r\n >\r\n {title}\r\n </button>\r\n </li>\r\n );\r\n}\r\n","import { useEffect } from \"react\";\r\n\r\nexport type NotificationType = \"success\" | \"info\" | \"warning\" | \"danger\";\r\n\r\nexport interface Notification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsProps {\r\n notifications: Notification[];\r\n onClose: (id: string) => void;\r\n}\r\n\r\nexport function Notifications({ notifications, onClose }: NotificationsProps) {\r\n useEffect(() => {\r\n notifications.forEach((n) => {\r\n if (!n.autoCloseMs) return;\r\n\r\n const timer = setTimeout(() => onClose(n.id), n.autoCloseMs);\r\n return () => clearTimeout(timer);\r\n });\r\n }, [notifications, onClose]);\r\n\r\n return (\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => onClose(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport type { NotificationType } from \"./Notifications\";\r\n\r\n// Rename to avoid conflict with browser Notification type\r\nexport interface AppNotification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsContextValue {\r\n push: (message: string, type?: NotificationType, autoCloseMs?: number) => void;\r\n}\r\n\r\nconst NotificationsContext = createContext<NotificationsContextValue | undefined>(\r\n undefined\r\n);\r\n\r\ninterface NotificationsProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function NotificationsProvider({ children }: NotificationsProviderProps) {\r\n const [notifications, setNotifications] = useState<AppNotification[]>([]);\r\n\r\n const push = useCallback(\r\n (message: string, type: NotificationType = \"info\", autoCloseMs = 4000) => {\r\n setNotifications((prev) => [\r\n ...prev,\r\n {\r\n id: crypto.randomUUID(),\r\n message,\r\n type,\r\n autoCloseMs,\r\n },\r\n ]);\r\n },\r\n []\r\n );\r\n\r\n const close = useCallback((id: string) => {\r\n setNotifications((list) => list.filter((n) => n.id !== id));\r\n }, []);\r\n\r\n // Handle auto close timers\r\n useEffect(() => {\r\n const timers = notifications.map((n) => {\r\n if (!n.autoCloseMs) return null;\r\n return setTimeout(() => close(n.id), n.autoCloseMs);\r\n });\r\n\r\n return () => {\r\n timers.forEach((t) => t && clearTimeout(t));\r\n };\r\n }, [notifications, close]);\r\n\r\n return (\r\n <NotificationsContext.Provider value={{ push }}>\r\n {/* overlay renderer */}\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => close(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {children}\r\n </NotificationsContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseNotifications(): NotificationsContextValue {\r\n const ctx = useContext(NotificationsContext);\r\n if (!ctx) {\r\n throw new Error(\"useNotifications must be used within a NotificationsProvider\");\r\n }\r\n return ctx;\r\n}\r\n","export function ContentContainer({ children }: React.PropsWithChildren) {\r\n return <div className=\"container-fluid flex-grow-1\">{children}</div>;\r\n}\r\n","export function ContentRow({ children }: React.PropsWithChildren) {\r\n return <div className=\"row h-100 flex-nowrap\">{children}</div>;\r\n}\r\n","\r\nexport function LayoutWrapper({ children }: React.PropsWithChildren) {\r\n return (\r\n\r\n <div className=\"d-flex flex-column min-vh-100\">{children}</div>\r\n );\r\n}\r\n","// components/Modal.tsx\r\nimport React from \"react\";\r\n\r\nexport interface ModalProps {\r\n /** Title shown in the header */\r\n title?: string;\r\n\r\n /** Whether the modal is visible */\r\n isOpen: boolean;\r\n\r\n /** Called when the user clicks the X or the backdrop */\r\n onClose: () => void;\r\n\r\n /** Optional confirm button handler */\r\n onConfirm?: () => void;\r\n\r\n /** Text for the confirm button (if onConfirm is provided) */\r\n confirmText?: string;\r\n\r\n /** Optional: disable closing by clicking backdrop */\r\n disableBackdropClose?: boolean;\r\n\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport const Modal: React.FC<ModalProps> = ({\r\n title,\r\n isOpen,\r\n onClose,\r\n onConfirm,\r\n confirmText = \"OK\",\r\n disableBackdropClose = false,\r\n children,\r\n}) => {\r\n if (!isOpen) return null;\r\n\r\n const handleBackdropClick = () => {\r\n if (disableBackdropClose) return;\r\n onClose();\r\n };\r\n\r\n const handleContentClick: React.MouseEventHandler<HTMLDivElement> = (e) => {\r\n // Prevent clicks inside the dialog from closing it\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <>\r\n {/* Backdrop */}\r\n <div\r\n className=\"modal-backdrop fade show\"\r\n style={{ zIndex: 1040 }}\r\n onClick={handleBackdropClick}\r\n />\r\n\r\n {/* Modal dialog */}\r\n <div\r\n className=\"modal fade show d-block\"\r\n tabIndex={-1}\r\n role=\"dialog\"\r\n style={{ zIndex: 1050 }}\r\n onClick={handleBackdropClick}\r\n >\r\n <div\r\n className=\"modal-dialog modal-dialog-centered\"\r\n role=\"document\"\r\n onClick={handleContentClick}\r\n >\r\n <div className=\"modal-content shadow\">\r\n {/* Header */}\r\n <div className=\"modal-header\">\r\n {title && <h5 className=\"modal-title\">{title}</h5>}\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={onClose}\r\n />\r\n </div>\r\n\r\n {/* Body */}\r\n <div className=\"modal-body\">{children}</div>\r\n\r\n {/* Footer */}\r\n <div className=\"modal-footer\">\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-secondary\"\r\n onClick={onClose}\r\n >\r\n Close\r\n </button>\r\n\r\n {onConfirm && (\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-primary\"\r\n onClick={onConfirm}\r\n >\r\n {confirmText}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </>\r\n );\r\n};\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport { Modal } from \"./Modal\";\r\n\r\ninterface ModalOptions {\r\n title?: string;\r\n confirmText?: string;\r\n disableBackdropClose?: boolean;\r\n onConfirm?: () => void;\r\n}\r\n\r\ninterface ModalContextValue {\r\n openModal: (\r\n content: ReactNode,\r\n options?: ModalOptions\r\n ) => void;\r\n\r\n closeModal: () => void;\r\n}\r\n\r\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\r\n\r\nexport function ModalProvider({ children }: { children: ReactNode }) {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [content, setContent] = useState<ReactNode>(null);\r\n const [options, setOptions] = useState<ModalOptions>({});\r\n\r\n const openModal = useCallback(\r\n (content: ReactNode, options?: ModalOptions) => {\r\n setContent(content);\r\n setOptions(options ?? {});\r\n setIsOpen(true);\r\n },\r\n []\r\n );\r\n\r\n const closeModal = useCallback(() => {\r\n setIsOpen(false);\r\n }, []);\r\n\r\n return (\r\n <ModalContext.Provider value={{ openModal, closeModal }}>\r\n {children}\r\n\r\n <Modal\r\n isOpen={isOpen}\r\n title={options.title}\r\n confirmText={options.confirmText}\r\n disableBackdropClose={options.disableBackdropClose}\r\n onClose={closeModal}\r\n onConfirm={options?.onConfirm}\r\n >\r\n {content}\r\n </Modal>\r\n </ModalContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseModal() {\r\n const ctx = useContext(ModalContext);\r\n if (!ctx) throw new Error(\"useModal must be used within ModalProvider\");\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsx","jsx","jsx","jsx","jsxs","jsx","jsx","jsxs","useEffect","useState","jsx","jsxs","jsx","jsx","jsx","Fragment","jsx","jsxs","createContext","useCallback","useContext","useState","jsx","jsxs","createContext","useState","useCallback","content","options","useContext"]}
1
+ {"version":3,"sources":["../src/components/Body.tsx","../src/components/Button.tsx","../src/components/Footer.tsx","../src/components/Header.tsx","../src/components/HeaderText.tsx","../src/components/NpmBadge.tsx","../src/components/navigation/Navigation.tsx","../src/components/navigation/NavigationItem.tsx","../src/components/notifications/Notifications.tsx","../src/components/notifications/NotificationsProvider.tsx","../src/components/wrappers/ContentContainer.tsx","../src/components/wrappers/ContentRow.tsx","../src/components/wrappers/LayoutWrapper.tsx","../src/modal/Modal.tsx","../src/modal/ModalProvider.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\r\n\r\ninterface BodyProps {\r\n title: ReactNode;\r\n description?: ReactNode;\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Body({ title, description, children }: BodyProps) {\r\n return (\r\n\r\n <main className=\"col p-4\">\r\n <h2>{title}</h2>\r\n\r\n {description && <p>{description}</p>}\r\n {children}\r\n </main>\r\n );\r\n}\r\n","import { useState, type ReactNode, type MouseEvent } from \"react\";\r\n\r\nexport interface ButtonProps {\r\n buttonClassName?: string;\r\n type?: \"button\" | \"submit\" | \"reset\";\r\n disabled?: boolean;\r\n\r\n onAction?: () => Promise<unknown>;\r\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\r\n onDone?: (result: unknown) => void;\r\n onError?: (error: unknown) => void;\r\n onFinally?: () => void;\r\n\r\n children?: ReactNode;\r\n loadingChildren?: ReactNode;\r\n\r\n renderContent?: () => ReactNode;\r\n renderLoading?: () => ReactNode;\r\n\r\n loadingText?: string;\r\n showSpinner?: boolean;\r\n}\r\n\r\nexport function Button({\r\n buttonClassName = \"btn btn-primary btn-lg\",\r\n type = \"button\",\r\n disabled = false,\r\n\r\n onAction,\r\n onClick,\r\n onDone,\r\n onError,\r\n onFinally,\r\n\r\n children = \"Click me\",\r\n\r\n loadingChildren,\r\n renderContent,\r\n renderLoading,\r\n\r\n loadingText = \"Loading...\",\r\n showSpinner = true,\r\n}: ButtonProps) {\r\n const [loading, setLoading] = useState(false);\r\n\r\n const handleClick = async (event: MouseEvent<HTMLButtonElement>) => {\r\n if (loading) return;\r\n\r\n onClick?.(event);\r\n if (event.defaultPrevented) return;\r\n if (!onAction) return;\r\n\r\n try {\r\n setLoading(true);\r\n const result = await onAction();\r\n onDone?.(result);\r\n } catch (error) {\r\n onError?.(error);\r\n } finally {\r\n setLoading(false);\r\n onFinally?.();\r\n }\r\n };\r\n\r\n return (\r\n <button\r\n type={type}\r\n className={`${buttonClassName} ${loading ? \"async-btn--loading\" : \"\"}`}\r\n onClick={handleClick}\r\n disabled={disabled || loading}\r\n >\r\n {loading ? (\r\n renderLoading?.() ??\r\n loadingChildren ?? (\r\n <>\r\n {showSpinner && (\r\n <span\r\n className=\"spinner-border spinner-border-sm me-2 async-btn__spinner\"\r\n role=\"status\"\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n {loadingText}\r\n </>\r\n )\r\n ) : (\r\n renderContent?.() ?? children\r\n )}\r\n </button>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface FooterProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Footer({ children }: FooterProps) {\r\n return (\r\n <footer className=\"bg-dark text-white text-center py-2 mt-auto\">\r\n {children ?? \"© 2025 Your Site — All rights reserved\"}\r\n </footer>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderProps {\r\n children?: ReactNode;\r\n}\r\n\r\nexport function Header({ children }: HeaderProps) {\r\n return (\r\n <nav className=\"navbar navbar-dark bg-dark px-3 sticky-top\">\r\n {children ?? (\r\n <span className=\"navbar-brand mb-0 h4\">My Website</span>\r\n )}\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface HeaderBrandProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function HeaderText({ children }: HeaderBrandProps) {\r\n return (\r\n <span className=\"navbar-brand mb-0 h4\">\r\n {children}\r\n </span>\r\n );\r\n}\r\n","// components/NpmBadge.tsx\r\ninterface NpmBadgeProps {\r\n packageLabel: string;\r\n packageName: string;\r\n packageUrl: string; // e.g. \"@sparkstudio/authentication-ui\"\r\n color?: string; // optional (default black)\r\n height?: number; // optional (default 22)\r\n}\r\n\r\nexport function NpmBadge({ packageName, packageLabel, packageUrl, color = \"black\", height = 22 }: NpmBadgeProps) {\r\n const encodedLabel = encodeURIComponent(packageLabel);\r\n const badgeUrl = `https://img.shields.io/npm/v/${packageName}?logo=npm&label=${encodedLabel}&color=${color}`;\r\n const npmUrl = packageUrl;\r\n\r\n return (\r\n <a href={npmUrl} target=\"_blank\" rel=\"noopener noreferrer\">\r\n <img src={badgeUrl} alt={`${packageName} version`} style={{ height }} />\r\n </a>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationProps {\r\n title?: ReactNode;\r\n children: ReactNode;\r\n}\r\n\r\nexport function Navigation({ title = \"Navigation\", children }: NavigationProps) {\r\n return (\r\n <nav className=\"col-auto p-3 h-100 d-flex flex-column\">\r\n <h6 className=\"text-muted text-uppercase\">{title}</h6>\r\n\r\n <ul className=\"nav nav-pills flex-column gap-2 mt-3\">\r\n {children}\r\n </ul>\r\n </nav>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\n\r\ninterface NavigationItemProps {\r\n title: ReactNode;\r\n type: string;\r\n active?: boolean;\r\n onClick?: (type: string) => void;\r\n}\r\n\r\nexport function NavigationItem({ title, type, active, onClick }: NavigationItemProps) {\r\n return (\r\n <li className=\"nav-item\">\r\n <button\r\n type=\"button\"\r\n className={`nav-link text-start w-100 ${active ? \"active\" : \"\"}`}\r\n onClick={() => onClick?.(type)}\r\n >\r\n {title}\r\n </button>\r\n </li>\r\n );\r\n}\r\n","import { useEffect } from \"react\";\r\n\r\nexport type NotificationType = \"success\" | \"info\" | \"warning\" | \"danger\";\r\n\r\nexport interface Notification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsProps {\r\n notifications: Notification[];\r\n onClose: (id: string) => void;\r\n}\r\n\r\nexport function Notifications({ notifications, onClose }: NotificationsProps) {\r\n useEffect(() => {\r\n notifications.forEach((n) => {\r\n if (!n.autoCloseMs) return;\r\n\r\n const timer = setTimeout(() => onClose(n.id), n.autoCloseMs);\r\n return () => clearTimeout(timer);\r\n });\r\n }, [notifications, onClose]);\r\n\r\n return (\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => onClose(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport type { NotificationType } from \"./Notifications\";\r\n\r\n// Rename to avoid conflict with browser Notification type\r\nexport interface AppNotification {\r\n id: string;\r\n message: string;\r\n type?: NotificationType;\r\n autoCloseMs?: number;\r\n}\r\n\r\ninterface NotificationsContextValue {\r\n push: (message: string, type?: NotificationType, autoCloseMs?: number) => void;\r\n}\r\n\r\nconst NotificationsContext = createContext<NotificationsContextValue | undefined>(\r\n undefined\r\n);\r\n\r\ninterface NotificationsProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function NotificationsProvider({ children }: NotificationsProviderProps) {\r\n const [notifications, setNotifications] = useState<AppNotification[]>([]);\r\n\r\n const push = useCallback(\r\n (message: string, type: NotificationType = \"info\", autoCloseMs = 4000) => {\r\n setNotifications((prev) => [\r\n ...prev,\r\n {\r\n id: crypto.randomUUID(),\r\n message,\r\n type,\r\n autoCloseMs,\r\n },\r\n ]);\r\n },\r\n []\r\n );\r\n\r\n const close = useCallback((id: string) => {\r\n setNotifications((list) => list.filter((n) => n.id !== id));\r\n }, []);\r\n\r\n // Handle auto close timers\r\n useEffect(() => {\r\n const timers = notifications.map((n) => {\r\n if (!n.autoCloseMs) return null;\r\n return setTimeout(() => close(n.id), n.autoCloseMs);\r\n });\r\n\r\n return () => {\r\n timers.forEach((t) => t && clearTimeout(t));\r\n };\r\n }, [notifications, close]);\r\n\r\n return (\r\n <NotificationsContext.Provider value={{ push }}>\r\n {/* overlay renderer */}\r\n <div\r\n className=\"position-fixed top-0 end-0 p-3\"\r\n style={{ zIndex: 1080, width: 340 }}\r\n >\r\n {notifications.map((n) => (\r\n <div\r\n key={n.id}\r\n className={`alert alert-${n.type ?? \"info\"} alert-dismissible fade show shadow-sm mb-2`}\r\n role=\"alert\"\r\n >\r\n {n.message}\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={() => close(n.id)}\r\n />\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {children}\r\n </NotificationsContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseNotifications(): NotificationsContextValue {\r\n const ctx = useContext(NotificationsContext);\r\n if (!ctx) {\r\n throw new Error(\"useNotifications must be used within a NotificationsProvider\");\r\n }\r\n return ctx;\r\n}\r\n","export function ContentContainer({ children }: React.PropsWithChildren) {\r\n return <div className=\"container-fluid flex-grow-1\">{children}</div>;\r\n}\r\n","export function ContentRow({ children }: React.PropsWithChildren) {\r\n return <div className=\"row h-100 flex-nowrap\">{children}</div>;\r\n}\r\n","\r\nexport function LayoutWrapper({ children }: React.PropsWithChildren) {\r\n return (\r\n\r\n <div className=\"d-flex flex-column min-vh-100\">{children}</div>\r\n );\r\n}\r\n","// components/Modal.tsx\r\nimport React from \"react\";\r\n\r\nexport interface ModalProps {\r\n title?: string;\r\n isOpen: boolean;\r\n onClose: () => void;\r\n onConfirm?: () => void;\r\n confirmText?: string;\r\n\r\n disableBackdropClose?: boolean;\r\n disableAllButtons?: boolean;\r\n\r\n /** NEW: toggle visibility */\r\n showHeaderClose?: boolean;\r\n showCloseButton?: boolean;\r\n showConfirmButton?: boolean;\r\n\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport const Modal: React.FC<ModalProps> = ({\r\n title,\r\n isOpen,\r\n onClose,\r\n onConfirm,\r\n confirmText = \"OK\",\r\n\r\n disableBackdropClose = false,\r\n disableAllButtons = false,\r\n\r\n showHeaderClose = true,\r\n showCloseButton = true,\r\n showConfirmButton = true,\r\n\r\n children,\r\n}) => {\r\n if (!isOpen) return null;\r\n\r\n const handleBackdropClick = () => {\r\n if (disableBackdropClose || disableAllButtons) return;\r\n onClose();\r\n };\r\n\r\n const handleContentClick: React.MouseEventHandler<HTMLDivElement> = (e) => {\r\n e.stopPropagation();\r\n };\r\n\r\n return (\r\n <>\r\n <div\r\n className=\"modal-backdrop fade show\"\r\n style={{ zIndex: 1040 }}\r\n onClick={handleBackdropClick}\r\n />\r\n\r\n <div\r\n className=\"modal fade show d-block\"\r\n tabIndex={-1}\r\n role=\"dialog\"\r\n style={{ zIndex: 1050 }}\r\n onClick={handleBackdropClick}\r\n >\r\n <div className=\"modal-dialog modal-dialog-centered\" role=\"document\" onClick={handleContentClick}>\r\n <div className=\"modal-content shadow\">\r\n {/* Header */}\r\n <div className=\"modal-header\">\r\n {title && <h5 className=\"modal-title\">{title}</h5>}\r\n\r\n {showHeaderClose && (\r\n <button\r\n type=\"button\"\r\n className=\"btn-close\"\r\n aria-label=\"Close\"\r\n onClick={onClose}\r\n disabled={disableAllButtons}\r\n />\r\n )}\r\n </div>\r\n\r\n {/* Body */}\r\n <div className=\"modal-body\">{children}</div>\r\n\r\n {/* Footer */}\r\n <div className=\"modal-footer\">\r\n {showCloseButton && (\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-secondary\"\r\n onClick={onClose}\r\n disabled={disableAllButtons}\r\n >\r\n Close\r\n </button>\r\n )}\r\n\r\n {onConfirm && showConfirmButton && (\r\n <button\r\n type=\"button\"\r\n className=\"btn btn-primary\"\r\n onClick={onConfirm}\r\n disabled={disableAllButtons}\r\n >\r\n {confirmText}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </>\r\n );\r\n};\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useState,\r\n type ReactNode,\r\n} from \"react\";\r\nimport { Modal } from \"./Modal\";\r\n\r\nexport interface ModalOptions {\r\n title?: string;\r\n confirmText?: string;\r\n disableBackdropClose?: boolean;\r\n onConfirm?: () => void;\r\n\r\n /** extra control flags matching Modal.tsx */\r\n disableAllButtons?: boolean;\r\n showHeaderClose?: boolean;\r\n showCloseButton?: boolean;\r\n showConfirmButton?: boolean;\r\n}\r\n\r\ninterface ModalContextValue {\r\n openModal: (content: ReactNode, options?: ModalOptions) => void;\r\n closeModal: () => void;\r\n}\r\n\r\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\r\n\r\nexport function ModalProvider({ children }: { children: ReactNode }) {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [content, setContent] = useState<ReactNode>(null);\r\n const [options, setOptions] = useState<ModalOptions>({});\r\n\r\n const openModal = useCallback((content: ReactNode, options?: ModalOptions) => {\r\n setContent(content);\r\n setOptions(options ?? {});\r\n setIsOpen(true);\r\n }, []);\r\n\r\n const closeModal = useCallback(() => {\r\n setIsOpen(false);\r\n }, []);\r\n\r\n return (\r\n <ModalContext.Provider value={{ openModal, closeModal }}>\r\n {children}\r\n\r\n <Modal\r\n isOpen={isOpen}\r\n title={options.title}\r\n confirmText={options.confirmText}\r\n disableBackdropClose={options.disableBackdropClose}\r\n disableAllButtons={options.disableAllButtons}\r\n showHeaderClose={options.showHeaderClose}\r\n showCloseButton={options.showCloseButton}\r\n showConfirmButton={options.showConfirmButton}\r\n onClose={closeModal}\r\n onConfirm={options.onConfirm}\r\n >\r\n {content}\r\n </Modal>\r\n </ModalContext.Provider>\r\n );\r\n}\r\n\r\nexport function UseModal() {\r\n const ctx = useContext(ModalContext);\r\n if (!ctx) throw new Error(\"UseModal must be used within ModalProvider\");\r\n return ctx;\r\n}\r\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsx","jsx","jsx","jsx","jsxs","jsx","jsx","jsxs","useEffect","useState","jsx","jsxs","jsx","jsx","jsx","Fragment","jsx","jsxs","createContext","useCallback","useContext","useState","jsx","jsxs","createContext","useState","useCallback","content","options","useContext"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkstudio/common-ui",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",