asterui 0.12.60 → 0.12.62

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.
Files changed (89) hide show
  1. package/dist/components/Affix.d.ts +2 -0
  2. package/dist/components/Affix.js.map +1 -1
  3. package/dist/components/Alert.d.ts +2 -0
  4. package/dist/components/Alert.js.map +1 -1
  5. package/dist/components/Avatar.d.ts +4 -0
  6. package/dist/components/Avatar.js.map +1 -1
  7. package/dist/components/Breadcrumb.js +22 -22
  8. package/dist/components/Breadcrumb.js.map +1 -1
  9. package/dist/components/Browser.d.ts +2 -0
  10. package/dist/components/Browser.js.map +1 -1
  11. package/dist/components/Chat.js +35 -26
  12. package/dist/components/Chat.js.map +1 -1
  13. package/dist/components/Code.d.ts +2 -0
  14. package/dist/components/Code.js.map +1 -1
  15. package/dist/components/Container.d.ts +2 -0
  16. package/dist/components/Container.js.map +1 -1
  17. package/dist/components/ContextMenu.js +100 -84
  18. package/dist/components/ContextMenu.js.map +1 -1
  19. package/dist/components/CopyButton.d.ts +2 -0
  20. package/dist/components/CopyButton.js +9 -8
  21. package/dist/components/CopyButton.js.map +1 -1
  22. package/dist/components/Countdown.d.ts +3 -3
  23. package/dist/components/Countdown.js +49 -47
  24. package/dist/components/Countdown.js.map +1 -1
  25. package/dist/components/Diff.d.ts +3 -3
  26. package/dist/components/Diff.js +14 -10
  27. package/dist/components/Diff.js.map +1 -1
  28. package/dist/components/Divider.d.ts +2 -0
  29. package/dist/components/Divider.js.map +1 -1
  30. package/dist/components/Dock.d.ts +4 -0
  31. package/dist/components/Dock.js +38 -25
  32. package/dist/components/Dock.js.map +1 -1
  33. package/dist/components/Dropdown.js +110 -110
  34. package/dist/components/Dropdown.js.map +1 -1
  35. package/dist/components/Fieldset.d.ts +2 -0
  36. package/dist/components/Fieldset.js.map +1 -1
  37. package/dist/components/FloatButton.d.ts +6 -0
  38. package/dist/components/FloatButton.js +122 -98
  39. package/dist/components/FloatButton.js.map +1 -1
  40. package/dist/components/Footer.d.ts +2 -0
  41. package/dist/components/Footer.js.map +1 -1
  42. package/dist/components/Grid.d.ts +4 -0
  43. package/dist/components/Grid.js.map +1 -1
  44. package/dist/components/Hero.d.ts +2 -0
  45. package/dist/components/Hero.js.map +1 -1
  46. package/dist/components/HoverGallery.d.ts +3 -3
  47. package/dist/components/HoverGallery.js +12 -10
  48. package/dist/components/HoverGallery.js.map +1 -1
  49. package/dist/components/Join.d.ts +2 -0
  50. package/dist/components/Join.js.map +1 -1
  51. package/dist/components/Kbd.d.ts +2 -0
  52. package/dist/components/Kbd.js.map +1 -1
  53. package/dist/components/Loading.d.ts +2 -0
  54. package/dist/components/Loading.js +51 -31
  55. package/dist/components/Loading.js.map +1 -1
  56. package/dist/components/Mask.d.ts +2 -2
  57. package/dist/components/Mask.js.map +1 -1
  58. package/dist/components/Navbar.d.ts +2 -0
  59. package/dist/components/Navbar.js.map +1 -1
  60. package/dist/components/Notification.js +32 -18
  61. package/dist/components/Notification.js.map +1 -1
  62. package/dist/components/Phone.d.ts +3 -2
  63. package/dist/components/Phone.js +10 -8
  64. package/dist/components/Phone.js.map +1 -1
  65. package/dist/components/Popconfirm.js +110 -92
  66. package/dist/components/Popconfirm.js.map +1 -1
  67. package/dist/components/Popover.d.ts +2 -0
  68. package/dist/components/Popover.js.map +1 -1
  69. package/dist/components/Progress.d.ts +2 -0
  70. package/dist/components/Progress.js.map +1 -1
  71. package/dist/components/Radio.d.ts +6 -3
  72. package/dist/components/Radio.js +9 -9
  73. package/dist/components/Radio.js.map +1 -1
  74. package/dist/components/Skeleton.d.ts +2 -0
  75. package/dist/components/Skeleton.js.map +1 -1
  76. package/dist/components/Space.d.ts +2 -0
  77. package/dist/components/Space.js.map +1 -1
  78. package/dist/components/Status.d.ts +3 -3
  79. package/dist/components/Status.js +27 -25
  80. package/dist/components/Status.js.map +1 -1
  81. package/dist/components/Toggle.d.ts +2 -0
  82. package/dist/components/Toggle.js.map +1 -1
  83. package/dist/components/Tooltip.d.ts +2 -0
  84. package/dist/components/Tooltip.js +38 -32
  85. package/dist/components/Tooltip.js.map +1 -1
  86. package/dist/components/Window.d.ts +3 -2
  87. package/dist/components/Window.js +9 -7
  88. package/dist/components/Window.js.map +1 -1
  89. package/package.json +5 -3
@@ -1 +1 @@
1
- {"version":3,"file":"Navbar.js","sources":["../../src/components/Navbar.tsx"],"sourcesContent":["import React from 'react'\n\n// DaisyUI classes\nconst dNavbar = 'navbar'\nconst dNavbarStart = 'navbar-start'\nconst dNavbarCenter = 'navbar-center'\nconst dNavbarEnd = 'navbar-end'\n\nexport type NavbarColor = 'base' | 'neutral' | 'primary' | 'secondary' | 'accent'\nexport type NavbarShadow = 'none' | 'sm' | 'md' | 'lg' | 'xl'\nexport type NavbarRounded = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'\n\nexport interface NavbarProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color'> {\n children?: React.ReactNode\n /** Content for the start section of the navbar (typically logo/brand) */\n start?: React.ReactNode\n /** Content for the center section of the navbar */\n center?: React.ReactNode\n /** Content for the end section of the navbar (typically actions/menu) */\n end?: React.ReactNode\n /** Background color variant */\n color?: NavbarColor\n /** Make navbar sticky at the top */\n sticky?: boolean\n /** Shadow depth */\n shadow?: NavbarShadow\n /** Border radius */\n rounded?: NavbarRounded\n}\n\nconst colorClasses: Record<NavbarColor, string> = {\n base: 'bg-base-100',\n neutral: 'bg-neutral text-neutral-content',\n primary: 'bg-primary text-primary-content',\n secondary: 'bg-secondary text-secondary-content',\n accent: 'bg-accent text-accent-content',\n}\n\nconst shadowClasses: Record<NavbarShadow, string> = {\n none: '',\n sm: 'shadow-sm',\n md: 'shadow-md',\n lg: 'shadow-lg',\n xl: 'shadow-xl',\n}\n\nconst roundedClasses: Record<NavbarRounded, string> = {\n none: '',\n sm: 'rounded-sm',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n}\n\nexport const Navbar: React.FC<NavbarProps> = ({\n children,\n start,\n center,\n end,\n color = 'base',\n sticky = false,\n shadow = 'none',\n rounded = 'none',\n className = '',\n ...rest\n}) => {\n const navbarClasses = [\n dNavbar,\n colorClasses[color],\n sticky && 'sticky top-0 z-50',\n shadowClasses[shadow],\n roundedClasses[rounded],\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n if (children) {\n return <nav className={navbarClasses} {...rest}>{children}</nav>\n }\n\n return (\n <nav className={navbarClasses} {...rest}>\n {start && <div className={dNavbarStart}>{start}</div>}\n {center && <div className={dNavbarCenter}>{center}</div>}\n {end && <div className={dNavbarEnd}>{end}</div>}\n </nav>\n )\n}\n"],"names":["dNavbar","dNavbarStart","dNavbarCenter","dNavbarEnd","colorClasses","shadowClasses","roundedClasses","Navbar","children","start","center","end","color","sticky","shadow","rounded","className","rest","navbarClasses","jsxs","jsx"],"mappings":";AAGA,MAAMA,IAAU,UACVC,IAAe,gBACfC,IAAgB,iBAChBC,IAAa,cAwBbC,IAA4C;AAAA,EAChD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ;AACV,GAEMC,IAA8C;AAAA,EAClD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAAgD;AAAA,EACpD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR,GAEaC,IAAgC,CAAC;AAAA,EAC5C,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,KAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,QAAAC,IAAS;AAAA,EACT,SAAAC,IAAU;AAAA,EACV,WAAAC,IAAY;AAAA,EACZ,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAgB;AAAA,IACpBlB;AAAA,IACAI,EAAaQ,CAAK;AAAA,IAClBC,KAAU;AAAA,IACVR,EAAcS,CAAM;AAAA,IACpBR,EAAeS,CAAO;AAAA,IACtBC;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SAAIR,sBACM,OAAA,EAAI,WAAWU,GAAgB,GAAGD,GAAO,UAAAT,GAAS,IAI1D,gBAAAW,EAAC,OAAA,EAAI,WAAWD,GAAgB,GAAGD,GAChC,UAAA;AAAA,IAAAR,KAAS,gBAAAW,EAAC,OAAA,EAAI,WAAWnB,GAAe,UAAAQ,GAAM;AAAA,IAC9CC,KAAU,gBAAAU,EAAC,OAAA,EAAI,WAAWlB,GAAgB,UAAAQ,GAAO;AAAA,IACjDC,KAAO,gBAAAS,EAAC,OAAA,EAAI,WAAWjB,GAAa,UAAAQ,EAAA,CAAI;AAAA,EAAA,GAC3C;AAEJ;"}
1
+ {"version":3,"file":"Navbar.js","sources":["../../src/components/Navbar.tsx"],"sourcesContent":["import React from 'react'\n\n// DaisyUI classes\nconst dNavbar = 'navbar'\nconst dNavbarStart = 'navbar-start'\nconst dNavbarCenter = 'navbar-center'\nconst dNavbarEnd = 'navbar-end'\n\nexport type NavbarColor = 'base' | 'neutral' | 'primary' | 'secondary' | 'accent'\nexport type NavbarShadow = 'none' | 'sm' | 'md' | 'lg' | 'xl'\nexport type NavbarRounded = 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'\n\nexport interface NavbarProps extends Omit<React.HTMLAttributes<HTMLElement>, 'color'> {\n children?: React.ReactNode\n /** Content for the start section of the navbar (typically logo/brand) */\n start?: React.ReactNode\n /** Content for the center section of the navbar */\n center?: React.ReactNode\n /** Content for the end section of the navbar (typically actions/menu) */\n end?: React.ReactNode\n /** Background color variant */\n color?: NavbarColor\n /** Make navbar sticky at the top */\n sticky?: boolean\n /** Shadow depth */\n shadow?: NavbarShadow\n /** Border radius */\n rounded?: NavbarRounded\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nconst colorClasses: Record<NavbarColor, string> = {\n base: 'bg-base-100',\n neutral: 'bg-neutral text-neutral-content',\n primary: 'bg-primary text-primary-content',\n secondary: 'bg-secondary text-secondary-content',\n accent: 'bg-accent text-accent-content',\n}\n\nconst shadowClasses: Record<NavbarShadow, string> = {\n none: '',\n sm: 'shadow-sm',\n md: 'shadow-md',\n lg: 'shadow-lg',\n xl: 'shadow-xl',\n}\n\nconst roundedClasses: Record<NavbarRounded, string> = {\n none: '',\n sm: 'rounded-sm',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n full: 'rounded-full',\n}\n\nexport const Navbar: React.FC<NavbarProps> = ({\n children,\n start,\n center,\n end,\n color = 'base',\n sticky = false,\n shadow = 'none',\n rounded = 'none',\n className = '',\n ...rest\n}) => {\n const navbarClasses = [\n dNavbar,\n colorClasses[color],\n sticky && 'sticky top-0 z-50',\n shadowClasses[shadow],\n roundedClasses[rounded],\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n if (children) {\n return <nav className={navbarClasses} {...rest}>{children}</nav>\n }\n\n return (\n <nav className={navbarClasses} {...rest}>\n {start && <div className={dNavbarStart}>{start}</div>}\n {center && <div className={dNavbarCenter}>{center}</div>}\n {end && <div className={dNavbarEnd}>{end}</div>}\n </nav>\n )\n}\n"],"names":["dNavbar","dNavbarStart","dNavbarCenter","dNavbarEnd","colorClasses","shadowClasses","roundedClasses","Navbar","children","start","center","end","color","sticky","shadow","rounded","className","rest","navbarClasses","jsxs","jsx"],"mappings":";AAGA,MAAMA,IAAU,UACVC,IAAe,gBACfC,IAAgB,iBAChBC,IAAa,cA0BbC,IAA4C;AAAA,EAChD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,WAAW;AAAA,EACX,QAAQ;AACV,GAEMC,IAA8C;AAAA,EAClD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,GAEMC,IAAgD;AAAA,EACpD,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM;AACR,GAEaC,IAAgC,CAAC;AAAA,EAC5C,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,KAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,QAAAC,IAAS;AAAA,EACT,SAAAC,IAAU;AAAA,EACV,WAAAC,IAAY;AAAA,EACZ,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAgB;AAAA,IACpBlB;AAAA,IACAI,EAAaQ,CAAK;AAAA,IAClBC,KAAU;AAAA,IACVR,EAAcS,CAAM;AAAA,IACpBR,EAAeS,CAAO;AAAA,IACtBC;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,SAAIR,sBACM,OAAA,EAAI,WAAWU,GAAgB,GAAGD,GAAO,UAAAT,GAAS,IAI1D,gBAAAW,EAAC,OAAA,EAAI,WAAWD,GAAgB,GAAGD,GAChC,UAAA;AAAA,IAAAR,KAAS,gBAAAW,EAAC,OAAA,EAAI,WAAWnB,GAAe,UAAAQ,GAAM;AAAA,IAC9CC,KAAU,gBAAAU,EAAC,OAAA,EAAI,WAAWlB,GAAgB,UAAAQ,GAAO;AAAA,IACjDC,KAAO,gBAAAS,EAAC,OAAA,EAAI,WAAWjB,GAAa,UAAAQ,EAAA,CAAI;AAAA,EAAA,GAC3C;AAEJ;"}
@@ -1,7 +1,7 @@
1
- import { jsx as s, Fragment as f, jsxs as d } from "react/jsx-runtime";
2
- import { useState as $, useEffect as C } from "react";
3
- import g from "react-dom/client";
4
- const l = "toast", h = "toast-top", p = "toast-bottom", u = "toast-start", m = "toast-end", v = "toast-center", w = "alert", b = "alert-success", x = "alert-error", N = "alert-info", y = "alert-warning", z = "btn", R = "btn-xs", B = "btn-ghost", L = "btn-circle";
1
+ import { jsx as s, Fragment as w, jsxs as d } from "react/jsx-runtime";
2
+ import { useState as b, useEffect as C } from "react";
3
+ import $ from "react-dom/client";
4
+ const l = "toast", h = "toast-top", p = "toast-bottom", u = "toast-start", m = "toast-end", v = "toast-center", f = "alert", g = "alert-success", N = "alert-error", x = "alert-info", y = "alert-warning", z = "btn", R = "btn-xs", B = "btn-ghost", L = "btn-circle";
5
5
  class M {
6
6
  notifications = [];
7
7
  listeners = [];
@@ -20,7 +20,7 @@ class M {
20
20
  this.listeners.forEach((e) => e());
21
21
  }
22
22
  ensureContainer() {
23
- this.container || (this.container = document.createElement("div"), document.body.appendChild(this.container), this.root = g.createRoot(this.container), this.root.render(/* @__PURE__ */ s(T, { manager: this })));
23
+ this.container || (this.container = document.createElement("div"), document.body.appendChild(this.container), this.root = $.createRoot(this.container), this.root.render(/* @__PURE__ */ s(T, { manager: this })));
24
24
  }
25
25
  open(e) {
26
26
  this.ensureContainer();
@@ -59,7 +59,7 @@ class M {
59
59
  }
60
60
  }
61
61
  function T({ manager: t }) {
62
- const [, e] = $({});
62
+ const [, e] = b({});
63
63
  C(() => t.subscribe(() => {
64
64
  e({});
65
65
  }), [t]);
@@ -82,20 +82,30 @@ function T({ manager: t }) {
82
82
  bottomLeft: `${l} ${p} ${u} z-[9999]`,
83
83
  bottomCenter: `${l} ${p} ${v} z-[9999]`
84
84
  };
85
- return /* @__PURE__ */ s(f, { children: Object.entries(n).map(([r, a]) => a.length === 0 ? null : /* @__PURE__ */ s("div", { className: i[r], children: a.map((c) => /* @__PURE__ */ s(
86
- k,
85
+ return /* @__PURE__ */ s(w, { children: Object.entries(n).map(([r, a]) => a.length === 0 ? null : /* @__PURE__ */ s(
86
+ "div",
87
87
  {
88
- notification: c,
89
- onClose: () => t.close(c.id)
88
+ className: i[r],
89
+ role: "region",
90
+ "aria-live": "polite",
91
+ "aria-label": "Notifications",
92
+ children: a.map((c) => /* @__PURE__ */ s(
93
+ k,
94
+ {
95
+ notification: c,
96
+ onClose: () => t.close(c.id)
97
+ },
98
+ c.id
99
+ ))
90
100
  },
91
- c.id
92
- )) }, r)) });
101
+ r
102
+ )) });
93
103
  }
94
104
  function k({ notification: t, onClose: e }) {
95
105
  const o = t.variant === "compact", n = {
96
- success: b,
97
- error: x,
98
- info: N,
106
+ success: g,
107
+ error: N,
108
+ info: x,
99
109
  warning: y
100
110
  }, i = {
101
111
  success: /* @__PURE__ */ s("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ s("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }),
@@ -108,22 +118,24 @@ function k({ notification: t, onClose: e }) {
108
118
  return o ? /* @__PURE__ */ s(
109
119
  "div",
110
120
  {
111
- className: `${w} ${n[t.type]} shadow-md py-2 px-4 cursor-pointer${t.className ? ` ${t.className}` : ""}`,
121
+ className: `${f} ${n[t.type]} shadow-md py-2 px-4 cursor-pointer${t.className ? ` ${t.className}` : ""}`,
112
122
  style: t.style,
113
123
  "data-testid": t["data-testid"],
114
124
  onClick: r,
125
+ role: "alert",
115
126
  children: /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
116
- a,
127
+ /* @__PURE__ */ s("span", { "aria-hidden": "true", children: a }),
117
128
  /* @__PURE__ */ s("span", { children: t.message })
118
129
  ] })
119
130
  }
120
131
  ) : /* @__PURE__ */ d(
121
132
  "div",
122
133
  {
123
- className: `${w} ${n[t.type]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${t.className ? ` ${t.className}` : ""}`,
134
+ className: `${f} ${n[t.type]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${t.className ? ` ${t.className}` : ""}`,
124
135
  style: t.style,
125
136
  "data-testid": t["data-testid"],
126
137
  onClick: r,
138
+ role: "alert",
127
139
  children: [
128
140
  /* @__PURE__ */ d("div", { className: t.closable ? "pr-8" : "", children: [
129
141
  t.message && /* @__PURE__ */ s("div", { className: "font-bold", children: t.message }),
@@ -132,10 +144,12 @@ function k({ notification: t, onClose: e }) {
132
144
  t.closable && /* @__PURE__ */ s(
133
145
  "button",
134
146
  {
147
+ type: "button",
135
148
  className: `${z} ${R} ${B} ${L} absolute top-2 right-2`,
136
149
  onClick: (c) => {
137
150
  c.stopPropagation(), e();
138
151
  },
152
+ "aria-label": "Close notification",
139
153
  children: "✕"
140
154
  }
141
155
  )
@@ -1 +1 @@
1
- {"version":3,"file":"Notification.js","sources":["../../src/components/Notification.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\nimport ReactDOM from 'react-dom/client'\n\n// DaisyUI classes\nconst dToast = 'toast'\nconst dToastTop = 'toast-top'\nconst dToastBottom = 'toast-bottom'\nconst dToastStart = 'toast-start'\nconst dToastEnd = 'toast-end'\nconst dToastCenter = 'toast-center'\nconst dAlert = 'alert'\nconst dAlertSuccess = 'alert-success'\nconst dAlertError = 'alert-error'\nconst dAlertInfo = 'alert-info'\nconst dAlertWarning = 'alert-warning'\nconst dBtn = 'btn'\nconst dBtnXs = 'btn-xs'\nconst dBtnGhost = 'btn-ghost'\nconst dBtnCircle = 'btn-circle'\n\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error'\nexport type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'topCenter' | 'bottomCenter'\nexport type NotificationVariant = 'default' | 'compact'\n\nexport interface NotificationConfig {\n message: React.ReactNode\n description?: React.ReactNode\n type?: NotificationType\n duration?: number // in seconds, 0 = no auto close\n placement?: NotificationPlacement\n variant?: NotificationVariant\n closable?: boolean\n icon?: React.ReactNode\n key?: string\n className?: string\n style?: React.CSSProperties\n 'data-testid'?: string\n onClick?: () => void\n onClose?: () => void\n}\n\ninterface NotificationItem extends NotificationConfig {\n id: string\n createdAt: number\n}\n\ntype Listener = () => void\n\nclass NotificationManager {\n private notifications: NotificationItem[] = []\n private listeners: Listener[] = []\n private container: HTMLDivElement | null = null\n private root: ReactDOM.Root | null = null\n private idCounter = 0\n\n subscribe(listener: Listener) {\n this.listeners.push(listener)\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n }\n\n getNotifications() {\n return this.notifications\n }\n\n private emit() {\n this.listeners.forEach((listener) => listener())\n }\n\n private ensureContainer() {\n if (!this.container) {\n this.container = document.createElement('div')\n document.body.appendChild(this.container)\n this.root = ReactDOM.createRoot(this.container)\n this.root.render(<NotificationContainer manager={this} />)\n }\n }\n\n open(config: NotificationConfig) {\n this.ensureContainer()\n\n const id = config.key ?? `notification-${++this.idCounter}`\n const isCompact = config.variant === 'compact'\n const notificationItem: NotificationItem = {\n ...config,\n id,\n createdAt: Date.now(),\n duration: config.duration ?? (isCompact ? 3 : 4.5),\n placement: config.placement ?? (isCompact ? 'topCenter' : 'topRight'),\n variant: config.variant ?? 'default',\n closable: config.closable ?? !isCompact,\n type: config.type ?? 'info',\n }\n\n // If key exists, update the existing notification\n const existingIndex = this.notifications.findIndex((n) => n.id === id)\n if (existingIndex !== -1) {\n this.notifications[existingIndex] = notificationItem\n } else {\n this.notifications.push(notificationItem)\n }\n this.emit()\n\n // Auto-dismiss\n if (notificationItem.duration && notificationItem.duration > 0) {\n setTimeout(() => {\n this.close(id)\n }, notificationItem.duration * 1000)\n }\n\n return id\n }\n\n close(id: string) {\n const notification = this.notifications.find((n) => n.id === id)\n this.notifications = this.notifications.filter((n) => n.id !== id)\n this.emit()\n\n if (notification?.onClose) {\n notification.onClose()\n }\n }\n\n success(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'success' })\n }\n\n error(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'error' })\n }\n\n info(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'info' })\n }\n\n warning(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'warning' })\n }\n\n destroy() {\n this.notifications = []\n this.emit()\n }\n}\n\ninterface NotificationContainerProps {\n manager: NotificationManager\n}\n\nfunction NotificationContainer({ manager }: NotificationContainerProps) {\n const [, forceUpdate] = useState({})\n\n useEffect(() => {\n const unsubscribe = manager.subscribe(() => {\n forceUpdate({})\n })\n return unsubscribe\n }, [manager])\n\n const notifications = manager.getNotifications()\n\n // Group by placement\n const grouped: Record<NotificationPlacement, NotificationItem[]> = {\n topLeft: [],\n topRight: [],\n topCenter: [],\n bottomLeft: [],\n bottomRight: [],\n bottomCenter: [],\n }\n\n notifications.forEach((notification) => {\n grouped[notification.placement!].push(notification)\n })\n\n const placementClasses: Record<NotificationPlacement, string> = {\n topRight: `${dToast} ${dToastTop} ${dToastEnd} z-[9999]`,\n topLeft: `${dToast} ${dToastTop} ${dToastStart} z-[9999]`,\n topCenter: `${dToast} ${dToastTop} ${dToastCenter} z-[9999]`,\n bottomRight: `${dToast} ${dToastBottom} ${dToastEnd} z-[9999]`,\n bottomLeft: `${dToast} ${dToastBottom} ${dToastStart} z-[9999]`,\n bottomCenter: `${dToast} ${dToastBottom} ${dToastCenter} z-[9999]`,\n }\n\n return (\n <>\n {Object.entries(grouped).map(([placement, items]) => {\n if (items.length === 0) return null\n\n return (\n <div key={placement} className={placementClasses[placement as NotificationPlacement]}>\n {items.map((notification) => (\n <NotificationItem\n key={notification.id}\n notification={notification}\n onClose={() => manager.close(notification.id)}\n />\n ))}\n </div>\n )\n })}\n </>\n )\n}\n\ninterface NotificationItemProps {\n notification: NotificationItem\n onClose: () => void\n}\n\nfunction NotificationItem({ notification, onClose }: NotificationItemProps) {\n const isCompact = notification.variant === 'compact'\n\n const alertTypeClasses: Record<NotificationType, string> = {\n success: dAlertSuccess,\n error: dAlertError,\n info: dAlertInfo,\n warning: dAlertWarning,\n }\n\n const typeIcons: Record<NotificationType, React.ReactNode> = {\n success: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clipRule=\"evenodd\" /></svg>,\n error: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\" /></svg>,\n info: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clipRule=\"evenodd\" /></svg>,\n warning: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clipRule=\"evenodd\" /></svg>,\n }\n\n const handleClick = () => {\n if (notification.onClick) {\n notification.onClick()\n }\n }\n\n const icon = notification.icon ?? typeIcons[notification.type!]\n\n if (isCompact) {\n return (\n <div\n className={`${dAlert} ${alertTypeClasses[notification.type!]} shadow-md py-2 px-4 cursor-pointer${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n >\n <div className=\"flex items-center gap-2\">\n {icon}\n <span>{notification.message}</span>\n </div>\n </div>\n )\n }\n\n return (\n <div\n className={`${dAlert} ${alertTypeClasses[notification.type!]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n >\n <div className={notification.closable ? 'pr-8' : ''}>\n {notification.message && <div className=\"font-bold\">{notification.message}</div>}\n {notification.description && <div className=\"text-sm\">{notification.description}</div>}\n </div>\n {notification.closable && (\n <button\n className={`${dBtn} ${dBtnXs} ${dBtnGhost} ${dBtnCircle} absolute top-2 right-2`}\n onClick={(e) => {\n e.stopPropagation()\n onClose()\n }}\n >\n ✕\n </button>\n )}\n </div>\n )\n}\n\nexport const notification = new NotificationManager()\n"],"names":["dToast","dToastTop","dToastBottom","dToastStart","dToastEnd","dToastCenter","dAlert","dAlertSuccess","dAlertError","dAlertInfo","dAlertWarning","dBtn","dBtnXs","dBtnGhost","dBtnCircle","NotificationManager","listener","l","ReactDOM","jsx","NotificationContainer","config","id","isCompact","notificationItem","existingIndex","n","notification","manager","forceUpdate","useState","useEffect","notifications","grouped","placementClasses","Fragment","placement","items","NotificationItem","onClose","alertTypeClasses","typeIcons","handleClick","icon","jsxs","e"],"mappings":"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"}
1
+ {"version":3,"file":"Notification.js","sources":["../../src/components/Notification.tsx"],"sourcesContent":["import React, { useEffect, useState } from 'react'\nimport ReactDOM from 'react-dom/client'\n\n// DaisyUI classes\nconst dToast = 'toast'\nconst dToastTop = 'toast-top'\nconst dToastBottom = 'toast-bottom'\nconst dToastStart = 'toast-start'\nconst dToastEnd = 'toast-end'\nconst dToastCenter = 'toast-center'\nconst dAlert = 'alert'\nconst dAlertSuccess = 'alert-success'\nconst dAlertError = 'alert-error'\nconst dAlertInfo = 'alert-info'\nconst dAlertWarning = 'alert-warning'\nconst dBtn = 'btn'\nconst dBtnXs = 'btn-xs'\nconst dBtnGhost = 'btn-ghost'\nconst dBtnCircle = 'btn-circle'\n\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error'\nexport type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'topCenter' | 'bottomCenter'\nexport type NotificationVariant = 'default' | 'compact'\n\nexport interface NotificationConfig {\n message: React.ReactNode\n description?: React.ReactNode\n type?: NotificationType\n duration?: number // in seconds, 0 = no auto close\n placement?: NotificationPlacement\n variant?: NotificationVariant\n closable?: boolean\n icon?: React.ReactNode\n key?: string\n className?: string\n style?: React.CSSProperties\n 'data-testid'?: string\n onClick?: () => void\n onClose?: () => void\n}\n\ninterface NotificationItem extends NotificationConfig {\n id: string\n createdAt: number\n}\n\ntype Listener = () => void\n\nclass NotificationManager {\n private notifications: NotificationItem[] = []\n private listeners: Listener[] = []\n private container: HTMLDivElement | null = null\n private root: ReactDOM.Root | null = null\n private idCounter = 0\n\n subscribe(listener: Listener) {\n this.listeners.push(listener)\n return () => {\n this.listeners = this.listeners.filter((l) => l !== listener)\n }\n }\n\n getNotifications() {\n return this.notifications\n }\n\n private emit() {\n this.listeners.forEach((listener) => listener())\n }\n\n private ensureContainer() {\n if (!this.container) {\n this.container = document.createElement('div')\n document.body.appendChild(this.container)\n this.root = ReactDOM.createRoot(this.container)\n this.root.render(<NotificationContainer manager={this} />)\n }\n }\n\n open(config: NotificationConfig) {\n this.ensureContainer()\n\n const id = config.key ?? `notification-${++this.idCounter}`\n const isCompact = config.variant === 'compact'\n const notificationItem: NotificationItem = {\n ...config,\n id,\n createdAt: Date.now(),\n duration: config.duration ?? (isCompact ? 3 : 4.5),\n placement: config.placement ?? (isCompact ? 'topCenter' : 'topRight'),\n variant: config.variant ?? 'default',\n closable: config.closable ?? !isCompact,\n type: config.type ?? 'info',\n }\n\n // If key exists, update the existing notification\n const existingIndex = this.notifications.findIndex((n) => n.id === id)\n if (existingIndex !== -1) {\n this.notifications[existingIndex] = notificationItem\n } else {\n this.notifications.push(notificationItem)\n }\n this.emit()\n\n // Auto-dismiss\n if (notificationItem.duration && notificationItem.duration > 0) {\n setTimeout(() => {\n this.close(id)\n }, notificationItem.duration * 1000)\n }\n\n return id\n }\n\n close(id: string) {\n const notification = this.notifications.find((n) => n.id === id)\n this.notifications = this.notifications.filter((n) => n.id !== id)\n this.emit()\n\n if (notification?.onClose) {\n notification.onClose()\n }\n }\n\n success(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'success' })\n }\n\n error(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'error' })\n }\n\n info(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'info' })\n }\n\n warning(config: Omit<NotificationConfig, 'type'>) {\n return this.open({ ...config, type: 'warning' })\n }\n\n destroy() {\n this.notifications = []\n this.emit()\n }\n}\n\ninterface NotificationContainerProps {\n manager: NotificationManager\n}\n\nfunction NotificationContainer({ manager }: NotificationContainerProps) {\n const [, forceUpdate] = useState({})\n\n useEffect(() => {\n const unsubscribe = manager.subscribe(() => {\n forceUpdate({})\n })\n return unsubscribe\n }, [manager])\n\n const notifications = manager.getNotifications()\n\n // Group by placement\n const grouped: Record<NotificationPlacement, NotificationItem[]> = {\n topLeft: [],\n topRight: [],\n topCenter: [],\n bottomLeft: [],\n bottomRight: [],\n bottomCenter: [],\n }\n\n notifications.forEach((notification) => {\n grouped[notification.placement!].push(notification)\n })\n\n const placementClasses: Record<NotificationPlacement, string> = {\n topRight: `${dToast} ${dToastTop} ${dToastEnd} z-[9999]`,\n topLeft: `${dToast} ${dToastTop} ${dToastStart} z-[9999]`,\n topCenter: `${dToast} ${dToastTop} ${dToastCenter} z-[9999]`,\n bottomRight: `${dToast} ${dToastBottom} ${dToastEnd} z-[9999]`,\n bottomLeft: `${dToast} ${dToastBottom} ${dToastStart} z-[9999]`,\n bottomCenter: `${dToast} ${dToastBottom} ${dToastCenter} z-[9999]`,\n }\n\n return (\n <>\n {Object.entries(grouped).map(([placement, items]) => {\n if (items.length === 0) return null\n\n return (\n <div\n key={placement}\n className={placementClasses[placement as NotificationPlacement]}\n role=\"region\"\n aria-live=\"polite\"\n aria-label=\"Notifications\"\n >\n {items.map((notification) => (\n <NotificationItem\n key={notification.id}\n notification={notification}\n onClose={() => manager.close(notification.id)}\n />\n ))}\n </div>\n )\n })}\n </>\n )\n}\n\ninterface NotificationItemProps {\n notification: NotificationItem\n onClose: () => void\n}\n\nfunction NotificationItem({ notification, onClose }: NotificationItemProps) {\n const isCompact = notification.variant === 'compact'\n\n const alertTypeClasses: Record<NotificationType, string> = {\n success: dAlertSuccess,\n error: dAlertError,\n info: dAlertInfo,\n warning: dAlertWarning,\n }\n\n const typeIcons: Record<NotificationType, React.ReactNode> = {\n success: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clipRule=\"evenodd\" /></svg>,\n error: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clipRule=\"evenodd\" /></svg>,\n info: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clipRule=\"evenodd\" /></svg>,\n warning: <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fillRule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clipRule=\"evenodd\" /></svg>,\n }\n\n const handleClick = () => {\n if (notification.onClick) {\n notification.onClick()\n }\n }\n\n const icon = notification.icon ?? typeIcons[notification.type!]\n\n if (isCompact) {\n return (\n <div\n className={`${dAlert} ${alertTypeClasses[notification.type!]} shadow-md py-2 px-4 cursor-pointer${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n role=\"alert\"\n >\n <div className=\"flex items-center gap-2\">\n <span aria-hidden=\"true\">{icon}</span>\n <span>{notification.message}</span>\n </div>\n </div>\n )\n }\n\n return (\n <div\n className={`${dAlert} ${alertTypeClasses[notification.type!]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${notification.className ? ` ${notification.className}` : ''}`}\n style={notification.style}\n data-testid={notification['data-testid']}\n onClick={handleClick}\n role=\"alert\"\n >\n <div className={notification.closable ? 'pr-8' : ''}>\n {notification.message && <div className=\"font-bold\">{notification.message}</div>}\n {notification.description && <div className=\"text-sm\">{notification.description}</div>}\n </div>\n {notification.closable && (\n <button\n type=\"button\"\n className={`${dBtn} ${dBtnXs} ${dBtnGhost} ${dBtnCircle} absolute top-2 right-2`}\n onClick={(e) => {\n e.stopPropagation()\n onClose()\n }}\n aria-label=\"Close notification\"\n >\n ✕\n </button>\n )}\n </div>\n )\n}\n\nexport const notification = new NotificationManager()\n"],"names":["dToast","dToastTop","dToastBottom","dToastStart","dToastEnd","dToastCenter","dAlert","dAlertSuccess","dAlertError","dAlertInfo","dAlertWarning","dBtn","dBtnXs","dBtnGhost","dBtnCircle","NotificationManager","listener","l","ReactDOM","jsx","NotificationContainer","config","id","isCompact","notificationItem","existingIndex","n","notification","manager","forceUpdate","useState","useEffect","notifications","grouped","placementClasses","Fragment","placement","items","NotificationItem","onClose","alertTypeClasses","typeIcons","handleClick","icon","jsxs","e"],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { default as React } from 'react';
2
- export interface PhoneProps {
2
+ export interface PhoneProps extends React.HTMLAttributes<HTMLDivElement> {
3
3
  children: React.ReactNode;
4
4
  color?: string;
5
- className?: string;
6
5
  displayClassName?: string;
6
+ /** Test ID for testing */
7
+ 'data-testid'?: string;
7
8
  }
8
9
  export declare const Phone: React.FC<PhoneProps>;
@@ -1,17 +1,19 @@
1
- import { jsxs as a, jsx as e } from "react/jsx-runtime";
2
- const m = "mockup-phone", r = "mockup-phone-camera", d = "mockup-phone-display", h = ({
1
+ import { jsxs as p, jsx as e } from "react/jsx-runtime";
2
+ const m = "mockup-phone", r = "mockup-phone-camera", i = "mockup-phone-display", l = ({
3
3
  children: s,
4
4
  color: o,
5
- className: c = "",
6
- displayClassName: n = ""
5
+ className: a = "",
6
+ displayClassName: c = "",
7
+ "data-testid": t,
8
+ ...n
7
9
  }) => {
8
- const p = o ? { borderColor: o } : {};
9
- return /* @__PURE__ */ a("div", { className: `${m} ${c}`, style: p, children: [
10
+ const d = o ? { borderColor: o } : {};
11
+ return /* @__PURE__ */ p("div", { className: `${m} ${a}`, style: d, "data-testid": t, ...n, children: [
10
12
  /* @__PURE__ */ e("div", { className: r }),
11
- /* @__PURE__ */ e("div", { className: `${d} ${n}`, children: s })
13
+ /* @__PURE__ */ e("div", { className: `${i} ${c}`, children: s })
12
14
  ] });
13
15
  };
14
16
  export {
15
- h as Phone
17
+ l as Phone
16
18
  };
17
19
  //# sourceMappingURL=Phone.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Phone.js","sources":["../../src/components/Phone.tsx"],"sourcesContent":["import React from 'react'\n\n// DaisyUI classes\nconst dMockupPhone = 'mockup-phone'\nconst dMockupPhoneCamera = 'mockup-phone-camera'\nconst dMockupPhoneDisplay = 'mockup-phone-display'\n\nexport interface PhoneProps {\n children: React.ReactNode\n color?: string\n className?: string\n displayClassName?: string\n}\n\nexport const Phone: React.FC<PhoneProps> = ({\n children,\n color,\n className = '',\n displayClassName = '',\n}) => {\n const style: React.CSSProperties = color ? { borderColor: color } : {}\n\n return (\n <div className={`${dMockupPhone} ${className}`} style={style}>\n <div className={dMockupPhoneCamera}></div>\n <div className={`${dMockupPhoneDisplay} ${displayClassName}`}>\n {children}\n </div>\n </div>\n )\n}\n"],"names":["dMockupPhone","dMockupPhoneCamera","dMockupPhoneDisplay","Phone","children","color","className","displayClassName","style","jsxs","jsx"],"mappings":";AAGA,MAAMA,IAAe,gBACfC,IAAqB,uBACrBC,IAAsB,wBASfC,IAA8B,CAAC;AAAA,EAC1C,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,kBAAAC,IAAmB;AACrB,MAAM;AACJ,QAAMC,IAA6BH,IAAQ,EAAE,aAAaA,EAAA,IAAU,CAAA;AAEpE,SACE,gBAAAI,EAAC,SAAI,WAAW,GAAGT,CAAY,IAAIM,CAAS,IAAI,OAAAE,GAC9C,UAAA;AAAA,IAAA,gBAAAE,EAAC,OAAA,EAAI,WAAWT,EAAA,CAAoB;AAAA,IACpC,gBAAAS,EAAC,SAAI,WAAW,GAAGR,CAAmB,IAAIK,CAAgB,IACvD,UAAAH,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
1
+ {"version":3,"file":"Phone.js","sources":["../../src/components/Phone.tsx"],"sourcesContent":["import React from 'react'\n\n// DaisyUI classes\nconst dMockupPhone = 'mockup-phone'\nconst dMockupPhoneCamera = 'mockup-phone-camera'\nconst dMockupPhoneDisplay = 'mockup-phone-display'\n\nexport interface PhoneProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n color?: string\n displayClassName?: string\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport const Phone: React.FC<PhoneProps> = ({\n children,\n color,\n className = '',\n displayClassName = '',\n 'data-testid': testId,\n ...rest\n}) => {\n const style: React.CSSProperties = color ? { borderColor: color } : {}\n\n return (\n <div className={`${dMockupPhone} ${className}`} style={style} data-testid={testId} {...rest}>\n <div className={dMockupPhoneCamera}></div>\n <div className={`${dMockupPhoneDisplay} ${displayClassName}`}>\n {children}\n </div>\n </div>\n )\n}\n"],"names":["dMockupPhone","dMockupPhoneCamera","dMockupPhoneDisplay","Phone","children","color","className","displayClassName","testId","rest","style","jsxs","jsx"],"mappings":";AAGA,MAAMA,IAAe,gBACfC,IAAqB,uBACrBC,IAAsB,wBAUfC,IAA8B,CAAC;AAAA,EAC1C,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,kBAAAC,IAAmB;AAAA,EACnB,eAAeC;AAAA,EACf,GAAGC;AACL,MAAM;AACJ,QAAMC,IAA6BL,IAAQ,EAAE,aAAaA,EAAA,IAAU,CAAA;AAEpE,SACE,gBAAAM,EAAC,OAAA,EAAI,WAAW,GAAGX,CAAY,IAAIM,CAAS,IAAI,OAAAI,GAAc,eAAaF,GAAS,GAAGC,GACrF,UAAA;AAAA,IAAA,gBAAAG,EAAC,OAAA,EAAI,WAAWX,EAAA,CAAoB;AAAA,IACpC,gBAAAW,EAAC,SAAI,WAAW,GAAGV,CAAmB,IAAIK,CAAgB,IACvD,UAAAH,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
@@ -1,73 +1,77 @@
1
- import { jsxs as s, jsx as n } from "react/jsx-runtime";
2
- import D, { forwardRef as F, useState as v, useRef as C, useEffect as H } from "react";
3
- import { useConfig as J } from "../providers/ConfigProvider.js";
4
- const k = "btn", w = "btn-sm", Q = "btn-primary", U = "btn-secondary", V = "btn-accent", Y = "btn-success", Z = "btn-warning", _ = "btn-error", tt = "btn-info", nt = "btn-ghost", et = "loading", st = "loading-spinner", ot = "loading-xs", it = F(function({
5
- children: f,
6
- title: y,
7
- description: p,
8
- onConfirm: m,
9
- onCancel: $,
10
- okText: N,
11
- cancelText: B,
12
- okType: L = "primary",
13
- cancelType: P = "ghost",
14
- placement: u = "top",
15
- disabled: O = !1,
16
- icon: g,
17
- showCancel: T = !0,
18
- "data-testid": l,
19
- className: E,
20
- ...R
21
- }, S) {
22
- const { locale: b } = J(), [o, a] = v(!1), [c, h] = v(!1), i = C(null), j = N ?? b.Popconfirm?.okText ?? "OK", z = B ?? b.Popconfirm?.cancelText ?? "Cancel", r = (t) => l ? `${l}-${t}` : void 0, d = C(null);
23
- H(() => {
24
- const t = (e) => {
25
- i.current && !i.current.contains(e.target) && d.current && !d.current.contains(e.target) && a(!1);
1
+ import { jsxs as o, jsx as e } from "react/jsx-runtime";
2
+ import U, { forwardRef as V, useState as N, useRef as p, useId as B, useCallback as Y, useEffect as Z } from "react";
3
+ import { useConfig as _ } from "../providers/ConfigProvider.js";
4
+ const L = "btn", E = "btn-sm", tt = "btn-primary", et = "btn-secondary", nt = "btn-accent", st = "btn-success", ot = "btn-warning", at = "btn-error", rt = "btn-info", it = "btn-ghost", lt = "loading", ct = "loading-spinner", dt = "loading-xs", bt = V(function({
5
+ children: b,
6
+ title: P,
7
+ description: i,
8
+ onConfirm: g,
9
+ onCancel: l,
10
+ okText: T,
11
+ cancelText: O,
12
+ okType: R = "primary",
13
+ cancelType: I = "ghost",
14
+ placement: h = "top",
15
+ disabled: S = !1,
16
+ icon: x,
17
+ showCancel: j = !0,
18
+ "data-testid": c,
19
+ className: z,
20
+ ...A
21
+ }, K) {
22
+ const { locale: v } = _(), [a, n] = N(!1), [d, y] = N(!1), u = p(null), k = B(), w = B(), W = T ?? v.Popconfirm?.okText ?? "OK", D = O ?? v.Popconfirm?.cancelText ?? "Cancel", r = (t) => c ? `${c}-${t}` : void 0, f = p(null), C = p(null), m = Y((t) => {
23
+ t.key === "Escape" && (n(!1), l?.());
24
+ }, [l]);
25
+ Z(() => {
26
+ const t = (s) => {
27
+ u.current && !u.current.contains(s.target) && f.current && !f.current.contains(s.target) && n(!1);
26
28
  };
27
- if (o)
28
- return document.addEventListener("mousedown", t), () => document.removeEventListener("mousedown", t);
29
- }, [o]);
30
- const A = (t) => {
31
- O || (t.stopPropagation(), a(!o));
32
- }, I = async () => {
33
- if (m) {
34
- h(!0);
29
+ if (a)
30
+ return document.addEventListener("mousedown", t), document.addEventListener("keydown", m), setTimeout(() => C.current?.focus(), 0), () => {
31
+ document.removeEventListener("mousedown", t), document.removeEventListener("keydown", m);
32
+ };
33
+ }, [a, m]);
34
+ const G = (t) => {
35
+ S || (t.stopPropagation(), n(!a));
36
+ }, M = async () => {
37
+ if (g) {
38
+ y(!0);
35
39
  try {
36
- await m(), a(!1);
40
+ await g(), n(!1);
37
41
  } finally {
38
- h(!1);
42
+ y(!1);
39
43
  }
40
44
  } else
41
- a(!1);
42
- }, W = () => {
43
- $?.(), a(!1);
44
- }, G = () => `absolute z-50 ${{
45
+ n(!1);
46
+ }, X = () => {
47
+ l?.(), n(!1);
48
+ }, q = () => `absolute z-50 ${{
45
49
  top: "bottom-full left-1/2 -translate-x-1/2 mb-3",
46
50
  bottom: "top-full left-1/2 -translate-x-1/2 mt-3",
47
51
  left: "right-full top-1/2 -translate-y-1/2 mr-3",
48
52
  right: "left-full top-1/2 -translate-y-1/2 ml-3"
49
- }[u]}`, K = () => "bg-base-100 rounded-lg p-4 min-w-[200px] max-w-[300px] shadow-lg", M = () => `absolute w-2.5 h-2.5 bg-base-100 rotate-45 shadow-lg ${{
53
+ }[h]}`, F = () => "bg-base-100 rounded-lg p-4 min-w-[200px] max-w-[300px] shadow-lg", H = () => `absolute w-2.5 h-2.5 bg-base-100 rotate-45 shadow-lg ${{
50
54
  top: "bottom-[-5px] left-1/2 -translate-x-1/2",
51
55
  bottom: "top-[-5px] left-1/2 -translate-x-1/2",
52
56
  left: "right-[-5px] top-1/2 -translate-y-1/2",
53
57
  right: "left-[-5px] top-1/2 -translate-y-1/2"
54
- }[u]}`, X = {
55
- primary: Q,
56
- secondary: U,
57
- accent: V,
58
- success: Y,
59
- warning: Z,
60
- error: _,
61
- info: tt,
62
- ghost: nt
63
- }, x = (t) => X[t], q = /* @__PURE__ */ n(
58
+ }[h]}`, J = {
59
+ primary: tt,
60
+ secondary: et,
61
+ accent: nt,
62
+ success: st,
63
+ warning: ot,
64
+ error: at,
65
+ info: rt,
66
+ ghost: it
67
+ }, $ = (t) => J[t], Q = /* @__PURE__ */ e(
64
68
  "svg",
65
69
  {
66
70
  className: "w-5 h-5 text-warning",
67
71
  fill: "none",
68
72
  stroke: "currentColor",
69
73
  viewBox: "0 0 24 24",
70
- children: /* @__PURE__ */ n(
74
+ children: /* @__PURE__ */ e(
71
75
  "path",
72
76
  {
73
77
  strokeLinecap: "round",
@@ -78,52 +82,66 @@ const k = "btn", w = "btn-sm", Q = "btn-primary", U = "btn-secondary", V = "btn-
78
82
  )
79
83
  }
80
84
  );
81
- return /* @__PURE__ */ s("div", { ref: S || i, className: `relative inline-block ${E || ""}`, "data-state": o ? "open" : "closed", "data-testid": l, ...R, children: [
82
- D.cloneElement(f, {
85
+ return /* @__PURE__ */ o("div", { ref: K || u, className: `relative inline-block ${z || ""}`, "data-state": a ? "open" : "closed", "data-testid": c, ...A, children: [
86
+ U.cloneElement(b, {
83
87
  onClick: (t) => {
84
- A(t);
85
- const e = f.props?.onClick;
86
- e && e(t);
88
+ G(t);
89
+ const s = b.props?.onClick;
90
+ s && s(t);
87
91
  }
88
92
  }),
89
- o && /* @__PURE__ */ n("div", { className: G(), "data-testid": r("popup"), children: /* @__PURE__ */ s("div", { ref: d, className: K(), children: [
90
- /* @__PURE__ */ s("div", { className: "flex gap-3 relative z-10", children: [
91
- /* @__PURE__ */ n("div", { className: "flex-shrink-0 mt-0.5", children: g !== void 0 ? g : q }),
92
- /* @__PURE__ */ s("div", { className: "flex-1", children: [
93
- /* @__PURE__ */ n("div", { className: "font-semibold text-base-content mb-1", "data-testid": r("title"), children: y }),
94
- p && /* @__PURE__ */ n("div", { className: "text-sm text-base-content/70 mb-3", "data-testid": r("description"), children: p }),
95
- /* @__PURE__ */ s("div", { className: "flex justify-end gap-2 mt-3", children: [
96
- T && /* @__PURE__ */ n(
97
- "button",
98
- {
99
- className: `${k} ${w} ${x(P)}`,
100
- onClick: W,
101
- disabled: c,
102
- "data-testid": r("cancel-button"),
103
- children: z
104
- }
105
- ),
106
- /* @__PURE__ */ s(
107
- "button",
108
- {
109
- className: `${k} ${w} ${x(L)}`,
110
- onClick: I,
111
- disabled: c,
112
- "data-testid": r("ok-button"),
113
- children: [
114
- c && /* @__PURE__ */ n("span", { className: `${et} ${st} ${ot}` }),
115
- j
116
- ]
117
- }
118
- )
119
- ] })
120
- ] })
121
- ] }),
122
- /* @__PURE__ */ n("div", { className: M() })
123
- ] }) })
93
+ a && /* @__PURE__ */ e("div", { className: q(), "data-testid": r("popup"), children: /* @__PURE__ */ o(
94
+ "div",
95
+ {
96
+ ref: f,
97
+ className: F(),
98
+ role: "dialog",
99
+ "aria-modal": "true",
100
+ "aria-labelledby": k,
101
+ "aria-describedby": i ? w : void 0,
102
+ children: [
103
+ /* @__PURE__ */ o("div", { className: "flex gap-3 relative z-10", children: [
104
+ /* @__PURE__ */ e("div", { className: "flex-shrink-0 mt-0.5", "aria-hidden": "true", children: x !== void 0 ? x : Q }),
105
+ /* @__PURE__ */ o("div", { className: "flex-1", children: [
106
+ /* @__PURE__ */ e("div", { id: k, className: "font-semibold text-base-content mb-1", "data-testid": r("title"), children: P }),
107
+ i && /* @__PURE__ */ e("div", { id: w, className: "text-sm text-base-content/70 mb-3", "data-testid": r("description"), children: i }),
108
+ /* @__PURE__ */ o("div", { className: "flex justify-end gap-2 mt-3", children: [
109
+ j && /* @__PURE__ */ e(
110
+ "button",
111
+ {
112
+ type: "button",
113
+ className: `${L} ${E} ${$(I)}`,
114
+ onClick: X,
115
+ disabled: d,
116
+ "data-testid": r("cancel-button"),
117
+ children: D
118
+ }
119
+ ),
120
+ /* @__PURE__ */ o(
121
+ "button",
122
+ {
123
+ ref: C,
124
+ type: "button",
125
+ className: `${L} ${E} ${$(R)}`,
126
+ onClick: M,
127
+ disabled: d,
128
+ "data-testid": r("ok-button"),
129
+ children: [
130
+ d && /* @__PURE__ */ e("span", { className: `${lt} ${ct} ${dt}`, "aria-hidden": "true" }),
131
+ W
132
+ ]
133
+ }
134
+ )
135
+ ] })
136
+ ] })
137
+ ] }),
138
+ /* @__PURE__ */ e("div", { className: H() })
139
+ ]
140
+ }
141
+ ) })
124
142
  ] });
125
143
  });
126
144
  export {
127
- it as Popconfirm
145
+ bt as Popconfirm
128
146
  };
129
147
  //# sourceMappingURL=Popconfirm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Popconfirm.js","sources":["../../src/components/Popconfirm.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, forwardRef } from 'react'\nimport { useConfig } from '../providers/ConfigProvider'\n\n// DaisyUI classes\nconst dBtn = 'btn'\nconst dBtnSm = 'btn-sm'\nconst dBtnPrimary = 'btn-primary'\nconst dBtnSecondary = 'btn-secondary'\nconst dBtnAccent = 'btn-accent'\nconst dBtnSuccess = 'btn-success'\nconst dBtnWarning = 'btn-warning'\nconst dBtnError = 'btn-error'\nconst dBtnInfo = 'btn-info'\nconst dBtnGhost = 'btn-ghost'\nconst dLoading = 'loading'\nconst dLoadingSpinner = 'loading-spinner'\nconst dLoadingXs = 'loading-xs'\n\nexport interface PopconfirmProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n children: React.ReactElement\n title: React.ReactNode\n description?: React.ReactNode\n onConfirm?: () => void | Promise<void>\n onCancel?: () => void\n okText?: string\n cancelText?: string\n okType?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info'\n cancelType?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info' | 'ghost'\n placement?: 'top' | 'bottom' | 'left' | 'right'\n disabled?: boolean\n icon?: React.ReactNode\n showCancel?: boolean\n /** Test ID prefix for child elements */\n 'data-testid'?: string\n}\n\nexport const Popconfirm = forwardRef<HTMLDivElement, PopconfirmProps>(function Popconfirm(\n {\n children,\n title,\n description,\n onConfirm,\n onCancel,\n okText,\n cancelText,\n okType = 'primary',\n cancelType = 'ghost',\n placement = 'top',\n disabled = false,\n icon,\n showCancel = true,\n 'data-testid': testId,\n className,\n ...rest\n },\n ref\n) {\n const { locale } = useConfig()\n const [isOpen, setIsOpen] = useState(false)\n const [loading, setLoading] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Resolve locale strings\n const resolvedOkText = okText ?? locale.Popconfirm?.okText ?? 'OK'\n const resolvedCancelText = cancelText ?? locale.Popconfirm?.cancelText ?? 'Cancel'\n\n // Helper for test IDs\n const getTestId = (suffix: string) => (testId ? `${testId}-${suffix}` : undefined)\n const popupRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node) &&\n popupRef.current &&\n !popupRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n return () => document.removeEventListener('mousedown', handleClickOutside)\n }\n }, [isOpen])\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n if (disabled) return\n e.stopPropagation()\n setIsOpen(!isOpen)\n }\n\n const handleConfirm = async () => {\n if (onConfirm) {\n setLoading(true)\n try {\n await onConfirm()\n setIsOpen(false)\n } finally {\n setLoading(false)\n }\n } else {\n setIsOpen(false)\n }\n }\n\n const handleCancel = () => {\n onCancel?.()\n setIsOpen(false)\n }\n\n const getPopupContainerClasses = () => {\n const positions = {\n top: 'bottom-full left-1/2 -translate-x-1/2 mb-3',\n bottom: 'top-full left-1/2 -translate-x-1/2 mt-3',\n left: 'right-full top-1/2 -translate-y-1/2 mr-3',\n right: 'left-full top-1/2 -translate-y-1/2 ml-3',\n }\n\n return `absolute z-50 ${positions[placement]}`\n }\n\n const getPopupClasses = () => {\n return 'bg-base-100 rounded-lg p-4 min-w-[200px] max-w-[300px] shadow-lg'\n }\n\n const getArrowClasses = () => {\n const base = 'absolute w-2.5 h-2.5 bg-base-100 rotate-45 shadow-lg'\n\n const positions = {\n top: 'bottom-[-5px] left-1/2 -translate-x-1/2',\n bottom: 'top-[-5px] left-1/2 -translate-x-1/2',\n left: 'right-[-5px] top-1/2 -translate-y-1/2',\n right: 'left-[-5px] top-1/2 -translate-y-1/2',\n }\n\n return `${base} ${positions[placement]}`\n }\n\n const buttonClasses = {\n primary: dBtnPrimary,\n secondary: dBtnSecondary,\n accent: dBtnAccent,\n success: dBtnSuccess,\n warning: dBtnWarning,\n error: dBtnError,\n info: dBtnInfo,\n ghost: dBtnGhost,\n } as const\n\n const getButtonClass = (type: keyof typeof buttonClasses) => {\n return buttonClasses[type]\n }\n\n const defaultIcon = (\n <svg\n className=\"w-5 h-5 text-warning\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n )\n\n return (\n <div ref={ref || containerRef} className={`relative inline-block ${className || ''}`} data-state={isOpen ? 'open' : 'closed'} data-testid={testId} {...rest}>\n {React.cloneElement(children, {\n onClick: (e: React.MouseEvent) => {\n handleTriggerClick(e)\n const originalOnClick = (children.props as any)?.onClick\n if (originalOnClick) {\n originalOnClick(e)\n }\n },\n } as any)}\n\n {isOpen && (\n <div className={getPopupContainerClasses()} data-testid={getTestId('popup')}>\n <div ref={popupRef} className={getPopupClasses()}>\n <div className=\"flex gap-3 relative z-10\">\n <div className=\"flex-shrink-0 mt-0.5\">\n {icon !== undefined ? icon : defaultIcon}\n </div>\n <div className=\"flex-1\">\n <div className=\"font-semibold text-base-content mb-1\" data-testid={getTestId('title')}>{title}</div>\n {description && (\n <div className=\"text-sm text-base-content/70 mb-3\" data-testid={getTestId('description')}>{description}</div>\n )}\n <div className=\"flex justify-end gap-2 mt-3\">\n {showCancel && (\n <button\n className={`${dBtn} ${dBtnSm} ${getButtonClass(cancelType)}`}\n onClick={handleCancel}\n disabled={loading}\n data-testid={getTestId('cancel-button')}\n >\n {resolvedCancelText}\n </button>\n )}\n <button\n className={`${dBtn} ${dBtnSm} ${getButtonClass(okType)}`}\n onClick={handleConfirm}\n disabled={loading}\n data-testid={getTestId('ok-button')}\n >\n {loading && <span className={`${dLoading} ${dLoadingSpinner} ${dLoadingXs}`}></span>}\n {resolvedOkText}\n </button>\n </div>\n </div>\n </div>\n <div className={getArrowClasses()} />\n </div>\n </div>\n )}\n </div>\n )\n})\n"],"names":["dBtn","dBtnSm","dBtnPrimary","dBtnSecondary","dBtnAccent","dBtnSuccess","dBtnWarning","dBtnError","dBtnInfo","dBtnGhost","dLoading","dLoadingSpinner","dLoadingXs","Popconfirm","forwardRef","children","title","description","onConfirm","onCancel","okText","cancelText","okType","cancelType","placement","disabled","icon","showCancel","testId","className","rest","ref","locale","useConfig","isOpen","setIsOpen","useState","loading","setLoading","containerRef","useRef","resolvedOkText","resolvedCancelText","getTestId","suffix","popupRef","useEffect","handleClickOutside","event","handleTriggerClick","e","handleConfirm","handleCancel","getPopupContainerClasses","getPopupClasses","getArrowClasses","buttonClasses","getButtonClass","type","defaultIcon","jsx","React","originalOnClick","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"Popconfirm.js","sources":["../../src/components/Popconfirm.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, forwardRef, useId, useCallback } from 'react'\nimport { useConfig } from '../providers/ConfigProvider'\n\n// DaisyUI classes\nconst dBtn = 'btn'\nconst dBtnSm = 'btn-sm'\nconst dBtnPrimary = 'btn-primary'\nconst dBtnSecondary = 'btn-secondary'\nconst dBtnAccent = 'btn-accent'\nconst dBtnSuccess = 'btn-success'\nconst dBtnWarning = 'btn-warning'\nconst dBtnError = 'btn-error'\nconst dBtnInfo = 'btn-info'\nconst dBtnGhost = 'btn-ghost'\nconst dLoading = 'loading'\nconst dLoadingSpinner = 'loading-spinner'\nconst dLoadingXs = 'loading-xs'\n\nexport interface PopconfirmProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {\n children: React.ReactElement\n title: React.ReactNode\n description?: React.ReactNode\n onConfirm?: () => void | Promise<void>\n onCancel?: () => void\n okText?: string\n cancelText?: string\n okType?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info'\n cancelType?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info' | 'ghost'\n placement?: 'top' | 'bottom' | 'left' | 'right'\n disabled?: boolean\n icon?: React.ReactNode\n showCancel?: boolean\n /** Test ID prefix for child elements */\n 'data-testid'?: string\n}\n\nexport const Popconfirm = forwardRef<HTMLDivElement, PopconfirmProps>(function Popconfirm(\n {\n children,\n title,\n description,\n onConfirm,\n onCancel,\n okText,\n cancelText,\n okType = 'primary',\n cancelType = 'ghost',\n placement = 'top',\n disabled = false,\n icon,\n showCancel = true,\n 'data-testid': testId,\n className,\n ...rest\n },\n ref\n) {\n const { locale } = useConfig()\n const [isOpen, setIsOpen] = useState(false)\n const [loading, setLoading] = useState(false)\n const containerRef = useRef<HTMLDivElement>(null)\n const titleId = useId()\n const descriptionId = useId()\n\n // Resolve locale strings\n const resolvedOkText = okText ?? locale.Popconfirm?.okText ?? 'OK'\n const resolvedCancelText = cancelText ?? locale.Popconfirm?.cancelText ?? 'Cancel'\n\n // Helper for test IDs\n const getTestId = (suffix: string) => (testId ? `${testId}-${suffix}` : undefined)\n const popupRef = useRef<HTMLDivElement>(null)\n const confirmButtonRef = useRef<HTMLButtonElement>(null)\n\n // Handle ESC key to close\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n setIsOpen(false)\n onCancel?.()\n }\n }, [onCancel])\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target as Node) &&\n popupRef.current &&\n !popupRef.current.contains(event.target as Node)\n ) {\n setIsOpen(false)\n }\n }\n\n if (isOpen) {\n document.addEventListener('mousedown', handleClickOutside)\n document.addEventListener('keydown', handleKeyDown)\n // Focus the confirm button when dialog opens\n setTimeout(() => confirmButtonRef.current?.focus(), 0)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n document.removeEventListener('keydown', handleKeyDown)\n }\n }\n }, [isOpen, handleKeyDown])\n\n const handleTriggerClick = (e: React.MouseEvent) => {\n if (disabled) return\n e.stopPropagation()\n setIsOpen(!isOpen)\n }\n\n const handleConfirm = async () => {\n if (onConfirm) {\n setLoading(true)\n try {\n await onConfirm()\n setIsOpen(false)\n } finally {\n setLoading(false)\n }\n } else {\n setIsOpen(false)\n }\n }\n\n const handleCancel = () => {\n onCancel?.()\n setIsOpen(false)\n }\n\n const getPopupContainerClasses = () => {\n const positions = {\n top: 'bottom-full left-1/2 -translate-x-1/2 mb-3',\n bottom: 'top-full left-1/2 -translate-x-1/2 mt-3',\n left: 'right-full top-1/2 -translate-y-1/2 mr-3',\n right: 'left-full top-1/2 -translate-y-1/2 ml-3',\n }\n\n return `absolute z-50 ${positions[placement]}`\n }\n\n const getPopupClasses = () => {\n return 'bg-base-100 rounded-lg p-4 min-w-[200px] max-w-[300px] shadow-lg'\n }\n\n const getArrowClasses = () => {\n const base = 'absolute w-2.5 h-2.5 bg-base-100 rotate-45 shadow-lg'\n\n const positions = {\n top: 'bottom-[-5px] left-1/2 -translate-x-1/2',\n bottom: 'top-[-5px] left-1/2 -translate-x-1/2',\n left: 'right-[-5px] top-1/2 -translate-y-1/2',\n right: 'left-[-5px] top-1/2 -translate-y-1/2',\n }\n\n return `${base} ${positions[placement]}`\n }\n\n const buttonClasses = {\n primary: dBtnPrimary,\n secondary: dBtnSecondary,\n accent: dBtnAccent,\n success: dBtnSuccess,\n warning: dBtnWarning,\n error: dBtnError,\n info: dBtnInfo,\n ghost: dBtnGhost,\n } as const\n\n const getButtonClass = (type: keyof typeof buttonClasses) => {\n return buttonClasses[type]\n }\n\n const defaultIcon = (\n <svg\n className=\"w-5 h-5 text-warning\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n )\n\n return (\n <div ref={ref || containerRef} className={`relative inline-block ${className || ''}`} data-state={isOpen ? 'open' : 'closed'} data-testid={testId} {...rest}>\n {React.cloneElement(children, {\n onClick: (e: React.MouseEvent) => {\n handleTriggerClick(e)\n const originalOnClick = (children.props as any)?.onClick\n if (originalOnClick) {\n originalOnClick(e)\n }\n },\n } as any)}\n\n {isOpen && (\n <div className={getPopupContainerClasses()} data-testid={getTestId('popup')}>\n <div\n ref={popupRef}\n className={getPopupClasses()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={description ? descriptionId : undefined}\n >\n <div className=\"flex gap-3 relative z-10\">\n <div className=\"flex-shrink-0 mt-0.5\" aria-hidden=\"true\">\n {icon !== undefined ? icon : defaultIcon}\n </div>\n <div className=\"flex-1\">\n <div id={titleId} className=\"font-semibold text-base-content mb-1\" data-testid={getTestId('title')}>{title}</div>\n {description && (\n <div id={descriptionId} className=\"text-sm text-base-content/70 mb-3\" data-testid={getTestId('description')}>{description}</div>\n )}\n <div className=\"flex justify-end gap-2 mt-3\">\n {showCancel && (\n <button\n type=\"button\"\n className={`${dBtn} ${dBtnSm} ${getButtonClass(cancelType)}`}\n onClick={handleCancel}\n disabled={loading}\n data-testid={getTestId('cancel-button')}\n >\n {resolvedCancelText}\n </button>\n )}\n <button\n ref={confirmButtonRef}\n type=\"button\"\n className={`${dBtn} ${dBtnSm} ${getButtonClass(okType)}`}\n onClick={handleConfirm}\n disabled={loading}\n data-testid={getTestId('ok-button')}\n >\n {loading && <span className={`${dLoading} ${dLoadingSpinner} ${dLoadingXs}`} aria-hidden=\"true\"></span>}\n {resolvedOkText}\n </button>\n </div>\n </div>\n </div>\n <div className={getArrowClasses()} />\n </div>\n </div>\n )}\n </div>\n )\n})\n"],"names":["dBtn","dBtnSm","dBtnPrimary","dBtnSecondary","dBtnAccent","dBtnSuccess","dBtnWarning","dBtnError","dBtnInfo","dBtnGhost","dLoading","dLoadingSpinner","dLoadingXs","Popconfirm","forwardRef","children","title","description","onConfirm","onCancel","okText","cancelText","okType","cancelType","placement","disabled","icon","showCancel","testId","className","rest","ref","locale","useConfig","isOpen","setIsOpen","useState","loading","setLoading","containerRef","useRef","titleId","useId","descriptionId","resolvedOkText","resolvedCancelText","getTestId","suffix","popupRef","confirmButtonRef","handleKeyDown","useCallback","event","useEffect","handleClickOutside","handleTriggerClick","e","handleConfirm","handleCancel","getPopupContainerClasses","getPopupClasses","getArrowClasses","buttonClasses","getButtonClass","type","defaultIcon","jsx","React","originalOnClick","jsxs"],"mappings":";;;AAIA,MAAMA,IAAO,OACPC,IAAS,UACTC,KAAc,eACdC,KAAgB,iBAChBC,KAAa,cACbC,KAAc,eACdC,KAAc,eACdC,KAAY,aACZC,KAAW,YACXC,KAAY,aACZC,KAAW,WACXC,KAAkB,mBAClBC,KAAa,cAoBNC,KAAaC,EAA4C,SACpE;AAAA,EACE,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,QAAAC,IAAS;AAAA,EACT,YAAAC,IAAa;AAAA,EACb,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,MAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,eAAeC;AAAA,EACf,WAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAM,EAAE,QAAAC,EAAA,IAAWC,EAAA,GACb,CAACC,GAAQC,CAAS,IAAIC,EAAS,EAAK,GACpC,CAACC,GAASC,CAAU,IAAIF,EAAS,EAAK,GACtCG,IAAeC,EAAuB,IAAI,GAC1CC,IAAUC,EAAA,GACVC,IAAgBD,EAAA,GAGhBE,IAAiBxB,KAAUY,EAAO,YAAY,UAAU,MACxDa,IAAqBxB,KAAcW,EAAO,YAAY,cAAc,UAGpEc,IAAY,CAACC,MAAoBnB,IAAS,GAAGA,CAAM,IAAImB,CAAM,KAAK,QAClEC,IAAWR,EAAuB,IAAI,GACtCS,IAAmBT,EAA0B,IAAI,GAGjDU,IAAgBC,EAAY,CAACC,MAAyB;AAC1D,IAAIA,EAAM,QAAQ,aAChBjB,EAAU,EAAK,GACfhB,IAAA;AAAA,EAEJ,GAAG,CAACA,CAAQ,CAAC;AAEb,EAAAkC,EAAU,MAAM;AACd,UAAMC,IAAqB,CAACF,MAAsB;AAChD,MACEb,EAAa,WACb,CAACA,EAAa,QAAQ,SAASa,EAAM,MAAc,KACnDJ,EAAS,WACT,CAACA,EAAS,QAAQ,SAASI,EAAM,MAAc,KAE/CjB,EAAU,EAAK;AAAA,IAEnB;AAEA,QAAID;AACF,sBAAS,iBAAiB,aAAaoB,CAAkB,GACzD,SAAS,iBAAiB,WAAWJ,CAAa,GAElD,WAAW,MAAMD,EAAiB,SAAS,MAAA,GAAS,CAAC,GAC9C,MAAM;AACX,iBAAS,oBAAoB,aAAaK,CAAkB,GAC5D,SAAS,oBAAoB,WAAWJ,CAAa;AAAA,MACvD;AAAA,EAEJ,GAAG,CAAChB,GAAQgB,CAAa,CAAC;AAE1B,QAAMK,IAAqB,CAACC,MAAwB;AAClD,IAAI/B,MACJ+B,EAAE,gBAAA,GACFrB,EAAU,CAACD,CAAM;AAAA,EACnB,GAEMuB,IAAgB,YAAY;AAChC,QAAIvC,GAAW;AACb,MAAAoB,EAAW,EAAI;AACf,UAAI;AACF,cAAMpB,EAAA,GACNiB,EAAU,EAAK;AAAA,MACjB,UAAA;AACE,QAAAG,EAAW,EAAK;AAAA,MAClB;AAAA,IACF;AACE,MAAAH,EAAU,EAAK;AAAA,EAEnB,GAEMuB,IAAe,MAAM;AACzB,IAAAvC,IAAA,GACAgB,EAAU,EAAK;AAAA,EACjB,GAEMwB,IAA2B,MAQxB,iBAPW;AAAA,IAChB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,EAAA,EAGyBnC,CAAS,CAAC,IAGxCoC,IAAkB,MACf,oEAGHC,IAAkB,MAUf,wDAPW;AAAA,IAChB,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,EAAA,EAGmBrC,CAAS,CAAC,IAGlCsC,IAAgB;AAAA,IACpB,SAAS5D;AAAA,IACT,WAAWC;AAAA,IACX,QAAQC;AAAA,IACR,SAASC;AAAA,IACT,SAASC;AAAA,IACT,OAAOC;AAAA,IACP,MAAMC;AAAA,IACN,OAAOC;AAAA,EAAA,GAGHsD,IAAiB,CAACC,MACfF,EAAcE,CAAI,GAGrBC,IACJ,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAK;AAAA,MACL,QAAO;AAAA,MACP,SAAQ;AAAA,MAER,UAAA,gBAAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAc;AAAA,UACd,gBAAe;AAAA,UACf,aAAa;AAAA,UACb,GAAE;AAAA,QAAA;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA;AAIJ,2BACG,OAAA,EAAI,KAAKnC,KAAOQ,GAAc,WAAW,yBAAyBV,KAAa,EAAE,IAAI,cAAYK,IAAS,SAAS,UAAU,eAAaN,GAAS,GAAGE,GACpJ,UAAA;AAAA,IAAAqC,EAAM,aAAapD,GAAU;AAAA,MAC5B,SAAS,CAACyC,MAAwB;AAChC,QAAAD,EAAmBC,CAAC;AACpB,cAAMY,IAAmBrD,EAAS,OAAe;AACjD,QAAIqD,KACFA,EAAgBZ,CAAC;AAAA,MAErB;AAAA,IAAA,CACM;AAAA,IAEPtB,uBACE,OAAA,EAAI,WAAWyB,KAA4B,eAAab,EAAU,OAAO,GACxE,UAAA,gBAAAuB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAKrB;AAAA,QACL,WAAWY,EAAA;AAAA,QACX,MAAK;AAAA,QACL,cAAW;AAAA,QACX,mBAAiBnB;AAAA,QACjB,oBAAkBxB,IAAc0B,IAAgB;AAAA,QAEhD,UAAA;AAAA,UAAA,gBAAA0B,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA;AAAA,YAAA,gBAAAH,EAAC,OAAA,EAAI,WAAU,wBAAuB,eAAY,QAC/C,UAAAxC,MAAS,SAAYA,IAAOuC,EAAA,CAC/B;AAAA,YACA,gBAAAI,EAAC,OAAA,EAAI,WAAU,UACb,UAAA;AAAA,cAAA,gBAAAH,EAAC,OAAA,EAAI,IAAIzB,GAAS,WAAU,wCAAuC,eAAaK,EAAU,OAAO,GAAI,UAAA9B,EAAA,CAAM;AAAA,cAC1GC,KACC,gBAAAiD,EAAC,OAAA,EAAI,IAAIvB,GAAe,WAAU,qCAAoC,eAAaG,EAAU,aAAa,GAAI,UAAA7B,EAAA,CAAY;AAAA,cAE5H,gBAAAoD,EAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,gBAAA1C,KACC,gBAAAuC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAK;AAAA,oBACL,WAAW,GAAGlE,CAAI,IAAIC,CAAM,IAAI8D,EAAexC,CAAU,CAAC;AAAA,oBAC1D,SAASmC;AAAA,oBACT,UAAUrB;AAAA,oBACV,eAAaS,EAAU,eAAe;AAAA,oBAErC,UAAAD;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGL,gBAAAwB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,KAAKpB;AAAA,oBACL,MAAK;AAAA,oBACL,WAAW,GAAGjD,CAAI,IAAIC,CAAM,IAAI8D,EAAezC,CAAM,CAAC;AAAA,oBACtD,SAASmC;AAAA,oBACT,UAAUpB;AAAA,oBACV,eAAaS,EAAU,WAAW;AAAA,oBAEjC,UAAA;AAAA,sBAAAT,KAAW,gBAAA6B,EAAC,QAAA,EAAK,WAAW,GAAGxD,EAAQ,IAAIC,EAAe,IAAIC,EAAU,IAAI,eAAY,OAAA,CAAO;AAAA,sBAC/FgC;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACH,EAAA,CACF;AAAA,YAAA,EAAA,CACF;AAAA,UAAA,GACF;AAAA,UACA,gBAAAsB,EAAC,OAAA,EAAI,WAAWL,EAAA,EAAgB,CAAG;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,EACrC,CACF;AAAA,EAAA,GAEJ;AAEJ,CAAC;"}
@@ -10,6 +10,8 @@ export interface PopoverProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
10
10
  open?: boolean;
11
11
  onOpenChange?: (open: boolean) => void;
12
12
  overlayClassName?: string;
13
+ /** Test ID for testing */
14
+ 'data-testid'?: string;
13
15
  }
14
16
  export declare const Popover: React.FC<PopoverProps>;
15
17
  export default Popover;