asterui 0.12.63 → 0.12.64

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.
@@ -1,8 +1,8 @@
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
- class M {
1
+ import { jsx as s, Fragment as C, jsxs as p } from "react/jsx-runtime";
2
+ import { useState as $, useEffect as y } from "react";
3
+ import x from "react-dom/client";
4
+ const c = "toast", h = "toast-top", u = "toast-bottom", v = "toast-start", f = "toast-end", w = "toast-center", b = "alert", N = "alert-success", z = "alert-error", R = "alert-info", k = "alert-warning", L = "btn", B = "btn-xs", M = "btn-ghost", T = "btn-circle";
5
+ class I {
6
6
  notifications = [];
7
7
  listeners = [];
8
8
  container = null;
@@ -20,11 +20,11 @@ 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 = $.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 = x.createRoot(this.container), this.root.render(/* @__PURE__ */ s(E, { manager: this })));
24
24
  }
25
25
  open(e) {
26
26
  this.ensureContainer();
27
- const o = e.key ?? `notification-${++this.idCounter}`, n = e.variant === "compact", i = {
27
+ const o = e.key ?? `notification-${++this.idCounter}`, n = e.variant === "compact", a = {
28
28
  ...e,
29
29
  id: o,
30
30
  createdAt: Date.now(),
@@ -33,10 +33,10 @@ class M {
33
33
  variant: e.variant ?? "default",
34
34
  closable: e.closable ?? !n,
35
35
  type: e.type ?? "info"
36
- }, r = this.notifications.findIndex((a) => a.id === o);
37
- return r !== -1 ? this.notifications[r] = i : this.notifications.push(i), this.emit(), i.duration && i.duration > 0 && setTimeout(() => {
36
+ }, r = this.notifications.findIndex((i) => i.id === o);
37
+ return r !== -1 ? this.notifications[r] = a : this.notifications.push(a), this.emit(), a.duration && a.duration > 0 && setTimeout(() => {
38
38
  this.close(o);
39
- }, i.duration * 1e3), o;
39
+ }, a.duration * 1e3), o;
40
40
  }
41
41
  close(e) {
42
42
  const o = this.notifications.find((n) => n.id === e);
@@ -58,9 +58,9 @@ class M {
58
58
  this.notifications = [], this.emit();
59
59
  }
60
60
  }
61
- function T({ manager: t }) {
62
- const [, e] = b({});
63
- C(() => t.subscribe(() => {
61
+ function E({ manager: t }) {
62
+ const [, e] = $({});
63
+ y(() => t.subscribe(() => {
64
64
  e({});
65
65
  }), [t]);
66
66
  const o = t.getNotifications(), n = {
@@ -74,70 +74,78 @@ function T({ manager: t }) {
74
74
  o.forEach((r) => {
75
75
  n[r.placement].push(r);
76
76
  });
77
- const i = {
78
- topRight: `${l} ${h} ${m} z-[9999]`,
79
- topLeft: `${l} ${h} ${u} z-[9999]`,
80
- topCenter: `${l} ${h} ${v} z-[9999]`,
81
- bottomRight: `${l} ${p} ${m} z-[9999]`,
82
- bottomLeft: `${l} ${p} ${u} z-[9999]`,
83
- bottomCenter: `${l} ${p} ${v} z-[9999]`
77
+ const a = {
78
+ topRight: `${c} ${h} ${f} z-[9999]`,
79
+ topLeft: `${c} ${h} ${v} z-[9999]`,
80
+ topCenter: `${c} ${h} ${w} z-[9999]`,
81
+ bottomRight: `${c} ${u} ${f} z-[9999]`,
82
+ bottomLeft: `${c} ${u} ${v} z-[9999]`,
83
+ bottomCenter: `${c} ${u} ${w} z-[9999]`
84
84
  };
85
- return /* @__PURE__ */ s(w, { children: Object.entries(n).map(([r, a]) => a.length === 0 ? null : /* @__PURE__ */ s(
85
+ return /* @__PURE__ */ s(C, { children: Object.entries(n).map(([r, i]) => i.length === 0 ? null : /* @__PURE__ */ s(
86
86
  "div",
87
87
  {
88
- className: i[r],
88
+ className: a[r],
89
89
  role: "region",
90
90
  "aria-live": "polite",
91
91
  "aria-label": "Notifications",
92
- children: a.map((c) => /* @__PURE__ */ s(
93
- k,
92
+ children: i.map((l) => /* @__PURE__ */ s(
93
+ A,
94
94
  {
95
- notification: c,
96
- onClose: () => t.close(c.id)
95
+ notification: l,
96
+ onClose: () => t.close(l.id)
97
97
  },
98
- c.id
98
+ l.id
99
99
  ))
100
100
  },
101
101
  r
102
102
  )) });
103
103
  }
104
- function k({ notification: t, onClose: e }) {
104
+ function A({ notification: t, onClose: e }) {
105
105
  const o = t.variant === "compact", n = {
106
- success: g,
107
- error: N,
108
- info: x,
109
- warning: y
110
- }, i = {
106
+ success: N,
107
+ error: z,
108
+ info: R,
109
+ warning: k
110
+ }, a = {
111
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" }) }),
112
112
  error: /* @__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 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" }) }),
113
113
  info: /* @__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: "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" }) }),
114
114
  warning: /* @__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: "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" }) })
115
115
  }, r = () => {
116
116
  t.onClick && t.onClick();
117
- }, a = t.icon ?? i[t.type];
117
+ }, i = typeof t.onClick == "function", l = i ? typeof t.message == "string" ? t.message : "Notification" : void 0, m = (d) => {
118
+ i && (d.key === "Enter" || d.key === " ") && (d.preventDefault(), r());
119
+ }, g = t.icon ?? a[t.type];
118
120
  return o ? /* @__PURE__ */ s(
119
121
  "div",
120
122
  {
121
- className: `${f} ${n[t.type]} shadow-md py-2 px-4 cursor-pointer${t.className ? ` ${t.className}` : ""}`,
123
+ className: `${b} ${n[t.type]} shadow-md py-2 px-4 cursor-pointer${t.className ? ` ${t.className}` : ""}`,
122
124
  style: t.style,
123
125
  "data-testid": t["data-testid"],
124
126
  onClick: r,
127
+ onKeyDown: m,
128
+ tabIndex: i ? 0 : void 0,
129
+ "aria-label": l,
125
130
  role: "alert",
126
- children: /* @__PURE__ */ d("div", { className: "flex items-center gap-2", children: [
127
- /* @__PURE__ */ s("span", { "aria-hidden": "true", children: a }),
131
+ children: /* @__PURE__ */ p("div", { className: "flex items-center gap-2", children: [
132
+ /* @__PURE__ */ s("span", { "aria-hidden": "true", children: g }),
128
133
  /* @__PURE__ */ s("span", { children: t.message })
129
134
  ] })
130
135
  }
131
- ) : /* @__PURE__ */ d(
136
+ ) : /* @__PURE__ */ p(
132
137
  "div",
133
138
  {
134
- className: `${f} ${n[t.type]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${t.className ? ` ${t.className}` : ""}`,
139
+ className: `${b} ${n[t.type]} shadow-lg cursor-pointer min-w-[300px] max-w-[400px] relative${t.className ? ` ${t.className}` : ""}`,
135
140
  style: t.style,
136
141
  "data-testid": t["data-testid"],
137
142
  onClick: r,
143
+ onKeyDown: m,
144
+ tabIndex: i ? 0 : void 0,
145
+ "aria-label": l,
138
146
  role: "alert",
139
147
  children: [
140
- /* @__PURE__ */ d("div", { className: t.closable ? "pr-8" : "", children: [
148
+ /* @__PURE__ */ p("div", { className: t.closable ? "pr-8" : "", children: [
141
149
  t.message && /* @__PURE__ */ s("div", { className: "font-bold", children: t.message }),
142
150
  t.description && /* @__PURE__ */ s("div", { className: "text-sm", children: t.description })
143
151
  ] }),
@@ -145,9 +153,9 @@ function k({ notification: t, onClose: e }) {
145
153
  "button",
146
154
  {
147
155
  type: "button",
148
- className: `${z} ${R} ${B} ${L} absolute top-2 right-2`,
149
- onClick: (c) => {
150
- c.stopPropagation(), e();
156
+ className: `${L} ${B} ${M} ${T} absolute top-2 right-2`,
157
+ onClick: (d) => {
158
+ d.stopPropagation(), e();
151
159
  },
152
160
  "aria-label": "Close notification",
153
161
  children: "✕"
@@ -157,8 +165,8 @@ function k({ notification: t, onClose: e }) {
157
165
  }
158
166
  );
159
167
  }
160
- const j = new M();
168
+ const S = new I();
161
169
  export {
162
- j as notification
170
+ S as notification
163
171
  };
164
172
  //# sourceMappingURL=Notification.js.map
@@ -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\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
+ {"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 isClickable = typeof notification.onClick === 'function'\n const ariaLabel = isClickable\n ? (typeof notification.message === 'string' ? notification.message : 'Notification')\n : undefined\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (!isClickable) return\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n handleClick()\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 onKeyDown={handleKeyDown}\n tabIndex={isClickable ? 0 : undefined}\n aria-label={ariaLabel}\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 onKeyDown={handleKeyDown}\n tabIndex={isClickable ? 0 : undefined}\n aria-label={ariaLabel}\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","isClickable","ariaLabel","handleKeyDown","e","icon","jsxs"],"mappings":"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"}
@@ -1,65 +1,67 @@
1
- import { jsx as s, jsxs as d, Fragment as b } from "react/jsx-runtime";
2
- import h, { forwardRef as $, useState as X } from "react";
3
- import { useConfig as w } from "../providers/ConfigProvider.js";
4
- const D = "tabs", E = "tabs-box", F = "tabs-border", K = "tabs-lift", M = "tabs-xs", O = "tabs-sm", V = "tabs-md", q = "tabs-lg", G = "tabs-xl", H = "tab", I = "tab-active", J = "tab-disabled", Q = {
5
- box: E,
6
- border: F,
7
- lift: K
8
- }, U = {
9
- xs: M,
10
- sm: O,
11
- md: V,
12
- lg: q,
13
- xl: G
14
- }, W = $(function({
15
- children: x,
16
- items: a,
17
- activeKey: e,
18
- defaultActiveKey: g,
19
- onChange: p,
20
- variant: r,
21
- size: _,
22
- position: f = "top",
23
- "data-testid": n,
1
+ import { jsx as s, jsxs as l, Fragment as r } from "react/jsx-runtime";
2
+ import u, { forwardRef as w, useState as D, useId as E } from "react";
3
+ import { useConfig as F } from "../providers/ConfigProvider.js";
4
+ const K = "tabs", M = "tabs-box", O = "tabs-border", V = "tabs-lift", q = "tabs-xs", G = "tabs-sm", H = "tabs-md", J = "tabs-lg", Q = "tabs-xl", U = "tab", W = "tab-active", Y = "tab-disabled", Z = {
5
+ box: M,
6
+ border: O,
7
+ lift: V
8
+ }, tt = {
9
+ xs: q,
10
+ sm: G,
11
+ md: H,
12
+ lg: J,
13
+ xl: Q
14
+ }, st = w(function({
15
+ children: h,
16
+ items: n,
17
+ activeKey: o,
18
+ defaultActiveKey: x,
19
+ onChange: g,
20
+ variant: m,
21
+ size: p,
22
+ position: y = "top",
23
+ "data-testid": c,
24
24
  className: C = "",
25
25
  ...A
26
26
  }, j) {
27
- const { componentSize: S } = w(), m = _ ?? S, o = (t) => n ? `${n}-${t}` : void 0, B = h.Children.toArray(x).filter(
28
- (t) => h.isValidElement(t) && t.type === u
27
+ const { componentSize: S } = F(), T = p ?? S, d = (t) => c ? `${c}-${t}` : void 0, B = u.Children.toArray(h).filter(
28
+ (t) => u.isValidElement(t) && t.type === $
29
29
  ).map((t) => ({
30
30
  ...t.props,
31
31
  _key: t.key != null ? String(t.key) : ""
32
- })), c = a && a.length > 0 ? a.map((t) => ({
32
+ })), i = n && n.length > 0 ? n.map((t) => ({
33
33
  _key: t.key,
34
34
  tab: t.label,
35
35
  children: t.children,
36
36
  disabled: t.disabled,
37
37
  icon: t.icon
38
- })) : B, [N, P] = X(
39
- g || c[0]?._key || ""
40
- ), T = e !== void 0 ? e : N, R = (t) => {
41
- e === void 0 && P(t), p?.(t);
42
- }, z = [
43
- D,
44
- r && Q[r],
45
- m && U[m],
38
+ })) : B, [I, N] = D(
39
+ x || i[0]?._key || ""
40
+ ), k = o !== void 0 ? o : I, P = (t) => {
41
+ o === void 0 && N(t), g?.(t);
42
+ }, R = [
43
+ K,
44
+ m && Z[m],
45
+ T && tt[T],
46
46
  C
47
- ].filter(Boolean).join(" "), v = c.find((t) => t._key === T), y = /* @__PURE__ */ s("div", { role: "tablist", className: z, "data-testid": o("tablist"), children: c.map((t) => {
48
- const i = T === t._key, L = [
49
- H,
50
- i && I,
51
- t.disabled && J
47
+ ].filter(Boolean).join(" "), a = E(), e = i.find((t) => t._key === k), v = /* @__PURE__ */ s("div", { role: "tablist", className: R, "data-testid": d("tablist"), children: i.map((t) => {
48
+ const b = k === t._key, z = `${a}-tab-${t._key}`, L = `${a}-panel-${t._key}`, X = [
49
+ U,
50
+ b && W,
51
+ t.disabled && Y
52
52
  ].filter(Boolean).join(" ");
53
- return /* @__PURE__ */ d(
53
+ return /* @__PURE__ */ l(
54
54
  "button",
55
55
  {
56
56
  role: "tab",
57
- className: L,
58
- onClick: () => !t.disabled && R(t._key),
57
+ id: z,
58
+ className: X,
59
+ onClick: () => !t.disabled && P(t._key),
59
60
  disabled: t.disabled,
60
- "data-state": i ? "active" : "inactive",
61
- "data-testid": o(`tab-${t._key}`),
62
- "aria-selected": i,
61
+ "data-state": b ? "active" : "inactive",
62
+ "data-testid": d(`tab-${t._key}`),
63
+ "aria-selected": b,
64
+ "aria-controls": L,
63
65
  children: [
64
66
  t.icon && /* @__PURE__ */ s("span", { className: "mr-1", children: t.icon }),
65
67
  t.tab
@@ -67,22 +69,32 @@ const D = "tabs", E = "tabs-box", F = "tabs-border", K = "tabs-lift", M = "tabs-
67
69
  },
68
70
  t._key
69
71
  );
70
- }) }), k = v && /* @__PURE__ */ s("div", { className: f === "top" ? "mt-4" : "mb-4", role: "tabpanel", "data-testid": o("tabpanel"), children: v.children });
71
- return /* @__PURE__ */ s("div", { ref: j, "data-testid": n, ...A, children: f === "top" ? /* @__PURE__ */ d(b, { children: [
72
- y,
73
- k
74
- ] }) : /* @__PURE__ */ d(b, { children: [
75
- k,
76
- y
72
+ }) }), _ = e && /* @__PURE__ */ s(
73
+ "div",
74
+ {
75
+ className: y === "top" ? "mt-4" : "mb-4",
76
+ role: "tabpanel",
77
+ id: `${a}-panel-${e._key}`,
78
+ "aria-labelledby": `${a}-tab-${e._key}`,
79
+ "data-testid": d("tabpanel"),
80
+ children: e.children
81
+ }
82
+ );
83
+ return /* @__PURE__ */ s("div", { ref: j, "data-testid": c, ...A, children: y === "top" ? /* @__PURE__ */ l(r, { children: [
84
+ v,
85
+ _
86
+ ] }) : /* @__PURE__ */ l(r, { children: [
87
+ _,
88
+ v
77
89
  ] }) });
78
90
  });
79
- function u({ children: l }) {
80
- return /* @__PURE__ */ s(b, { children: l });
91
+ function $({ children: f }) {
92
+ return /* @__PURE__ */ s(r, { children: f });
81
93
  }
82
- const st = Object.assign(W, {
83
- Panel: u
94
+ const ot = Object.assign(st, {
95
+ Panel: $
84
96
  });
85
97
  export {
86
- st as Tabs
98
+ ot as Tabs
87
99
  };
88
100
  //# sourceMappingURL=Tabs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","sources":["../../src/components/Tabs.tsx"],"sourcesContent":["import React, { useState, forwardRef } from 'react'\nimport { useConfig } from '../providers/ConfigProvider'\n\n// DaisyUI classes\nconst dTabs = 'tabs'\nconst dTabsBox = 'tabs-box'\nconst dTabsBorder = 'tabs-border'\nconst dTabsLift = 'tabs-lift'\nconst dTabsXs = 'tabs-xs'\nconst dTabsSm = 'tabs-sm'\nconst dTabsMd = 'tabs-md'\nconst dTabsLg = 'tabs-lg'\nconst dTabsXl = 'tabs-xl'\nconst dTab = 'tab'\nconst dTabActive = 'tab-active'\nconst dTabDisabled = 'tab-disabled'\n\nexport type TabsVariant = 'box' | 'border' | 'lift'\nexport type TabsSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\nexport type TabsPosition = 'top' | 'bottom'\n\nexport interface TabItem {\n key: string\n label: React.ReactNode\n children?: React.ReactNode\n disabled?: boolean\n icon?: React.ReactNode\n}\n\nexport interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Tab panels (compound pattern) */\n children?: React.ReactNode\n /** Tab items (data-driven pattern) */\n items?: TabItem[]\n /** Current active tab key (controlled) */\n activeKey?: string\n /** Default active tab key (uncontrolled) */\n defaultActiveKey?: string\n /** Callback when tab changes */\n onChange?: (key: string) => void\n /** Visual style variant */\n variant?: TabsVariant\n /** Tab size */\n size?: TabsSize\n /** Tab position relative to content */\n position?: TabsPosition\n /** Test ID prefix for child elements */\n 'data-testid'?: string\n}\n\nexport interface TabPanelProps {\n /** Tab button label */\n tab: React.ReactNode\n /** Disable the tab */\n disabled?: boolean\n /** Tab panel content */\n children?: React.ReactNode\n /** Tab icon */\n icon?: React.ReactNode\n}\n\nconst variantClasses: Record<TabsVariant, string> = {\n box: dTabsBox,\n border: dTabsBorder,\n lift: dTabsLift,\n}\n\nconst sizeClasses: Record<TabsSize, string> = {\n xs: dTabsXs,\n sm: dTabsSm,\n md: dTabsMd,\n lg: dTabsLg,\n xl: dTabsXl,\n}\n\ninterface InternalPanelProps extends TabPanelProps {\n _key: string\n}\n\nconst TabsRoot = forwardRef<HTMLDivElement, TabsProps>(function TabsRoot(\n {\n children,\n items,\n activeKey,\n defaultActiveKey,\n onChange,\n variant,\n size,\n position = 'top',\n 'data-testid': testId,\n className = '',\n ...rest\n },\n ref\n) {\n const { componentSize } = useConfig()\n const effectiveSize = size ?? (componentSize as TabsSize | undefined)\n\n // Helper for test IDs\n const getTestId = (suffix: string) => (testId ? `${testId}-${suffix}` : undefined)\n // Get panels from children (compound pattern), extracting key from React element\n const panels = React.Children.toArray(children)\n .filter((child): child is React.ReactElement<TabPanelProps> =>\n React.isValidElement(child) && child.type === TabPanel\n )\n .map((child) => ({\n ...child.props,\n _key: child.key != null ? String(child.key) : '',\n }))\n\n // Convert items to panel-like structure if using data-driven pattern\n const effectivePanels: InternalPanelProps[] = items && items.length > 0\n ? items.map(item => ({\n _key: item.key,\n tab: item.label,\n children: item.children,\n disabled: item.disabled,\n icon: item.icon,\n }))\n : panels\n\n const [internalActiveKey, setInternalActiveKey] = useState(\n defaultActiveKey || effectivePanels[0]?._key || ''\n )\n const currentActiveKey = activeKey !== undefined ? activeKey : internalActiveKey\n\n const handleTabClick = (key: string) => {\n if (activeKey === undefined) {\n setInternalActiveKey(key)\n }\n onChange?.(key)\n }\n\n const classes = [\n dTabs,\n variant && variantClasses[variant],\n effectiveSize && sizeClasses[effectiveSize],\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const activePanel = effectivePanels.find((panel) => panel._key === currentActiveKey)\n\n const tabList = (\n <div role=\"tablist\" className={classes} data-testid={getTestId('tablist')}>\n {effectivePanels.map((panel) => {\n const isActive = currentActiveKey === panel._key\n const tabClasses = [\n dTab,\n isActive && dTabActive,\n panel.disabled && dTabDisabled,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <button\n key={panel._key}\n role=\"tab\"\n className={tabClasses}\n onClick={() => !panel.disabled && handleTabClick(panel._key)}\n disabled={panel.disabled}\n data-state={isActive ? 'active' : 'inactive'}\n data-testid={getTestId(`tab-${panel._key}`)}\n aria-selected={isActive}\n >\n {panel.icon && <span className=\"mr-1\">{panel.icon}</span>}\n {panel.tab}\n </button>\n )\n })}\n </div>\n )\n\n const content = activePanel && (\n <div className={position === 'top' ? 'mt-4' : 'mb-4'} role=\"tabpanel\" data-testid={getTestId('tabpanel')}>\n {activePanel.children}\n </div>\n )\n\n return (\n <div ref={ref} data-testid={testId} {...rest}>\n {position === 'top' ? (\n <>\n {tabList}\n {content}\n </>\n ) : (\n <>\n {content}\n {tabList}\n </>\n )}\n </div>\n )\n})\n\nfunction TabPanel({ children }: TabPanelProps) {\n // This component is only used for type checking and is not rendered directly\n // The actual rendering is done in TabsRoot\n return <>{children}</>\n}\n\nexport const Tabs = Object.assign(TabsRoot, {\n Panel: TabPanel,\n})\n"],"names":["dTabs","dTabsBox","dTabsBorder","dTabsLift","dTabsXs","dTabsSm","dTabsMd","dTabsLg","dTabsXl","dTab","dTabActive","dTabDisabled","variantClasses","sizeClasses","TabsRoot","forwardRef","children","items","activeKey","defaultActiveKey","onChange","variant","size","position","testId","className","rest","ref","componentSize","useConfig","effectiveSize","getTestId","suffix","panels","React","child","TabPanel","effectivePanels","item","internalActiveKey","setInternalActiveKey","useState","currentActiveKey","handleTabClick","key","classes","activePanel","panel","tabList","jsx","isActive","tabClasses","jsxs","content","Fragment","Tabs"],"mappings":"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"}
1
+ {"version":3,"file":"Tabs.js","sources":["../../src/components/Tabs.tsx"],"sourcesContent":["import React, { useState, forwardRef, useId } from 'react'\nimport { useConfig } from '../providers/ConfigProvider'\n\n// DaisyUI classes\nconst dTabs = 'tabs'\nconst dTabsBox = 'tabs-box'\nconst dTabsBorder = 'tabs-border'\nconst dTabsLift = 'tabs-lift'\nconst dTabsXs = 'tabs-xs'\nconst dTabsSm = 'tabs-sm'\nconst dTabsMd = 'tabs-md'\nconst dTabsLg = 'tabs-lg'\nconst dTabsXl = 'tabs-xl'\nconst dTab = 'tab'\nconst dTabActive = 'tab-active'\nconst dTabDisabled = 'tab-disabled'\n\nexport type TabsVariant = 'box' | 'border' | 'lift'\nexport type TabsSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'\nexport type TabsPosition = 'top' | 'bottom'\n\nexport interface TabItem {\n key: string\n label: React.ReactNode\n children?: React.ReactNode\n disabled?: boolean\n icon?: React.ReactNode\n}\n\nexport interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Tab panels (compound pattern) */\n children?: React.ReactNode\n /** Tab items (data-driven pattern) */\n items?: TabItem[]\n /** Current active tab key (controlled) */\n activeKey?: string\n /** Default active tab key (uncontrolled) */\n defaultActiveKey?: string\n /** Callback when tab changes */\n onChange?: (key: string) => void\n /** Visual style variant */\n variant?: TabsVariant\n /** Tab size */\n size?: TabsSize\n /** Tab position relative to content */\n position?: TabsPosition\n /** Test ID prefix for child elements */\n 'data-testid'?: string\n}\n\nexport interface TabPanelProps {\n /** Tab button label */\n tab: React.ReactNode\n /** Disable the tab */\n disabled?: boolean\n /** Tab panel content */\n children?: React.ReactNode\n /** Tab icon */\n icon?: React.ReactNode\n}\n\nconst variantClasses: Record<TabsVariant, string> = {\n box: dTabsBox,\n border: dTabsBorder,\n lift: dTabsLift,\n}\n\nconst sizeClasses: Record<TabsSize, string> = {\n xs: dTabsXs,\n sm: dTabsSm,\n md: dTabsMd,\n lg: dTabsLg,\n xl: dTabsXl,\n}\n\ninterface InternalPanelProps extends TabPanelProps {\n _key: string\n}\n\nconst TabsRoot = forwardRef<HTMLDivElement, TabsProps>(function TabsRoot(\n {\n children,\n items,\n activeKey,\n defaultActiveKey,\n onChange,\n variant,\n size,\n position = 'top',\n 'data-testid': testId,\n className = '',\n ...rest\n },\n ref\n) {\n const { componentSize } = useConfig()\n const effectiveSize = size ?? (componentSize as TabsSize | undefined)\n\n // Helper for test IDs\n const getTestId = (suffix: string) => (testId ? `${testId}-${suffix}` : undefined)\n // Get panels from children (compound pattern), extracting key from React element\n const panels = React.Children.toArray(children)\n .filter((child): child is React.ReactElement<TabPanelProps> =>\n React.isValidElement(child) && child.type === TabPanel\n )\n .map((child) => ({\n ...child.props,\n _key: child.key != null ? String(child.key) : '',\n }))\n\n // Convert items to panel-like structure if using data-driven pattern\n const effectivePanels: InternalPanelProps[] = items && items.length > 0\n ? items.map(item => ({\n _key: item.key,\n tab: item.label,\n children: item.children,\n disabled: item.disabled,\n icon: item.icon,\n }))\n : panels\n\n const [internalActiveKey, setInternalActiveKey] = useState(\n defaultActiveKey || effectivePanels[0]?._key || ''\n )\n const currentActiveKey = activeKey !== undefined ? activeKey : internalActiveKey\n\n const handleTabClick = (key: string) => {\n if (activeKey === undefined) {\n setInternalActiveKey(key)\n }\n onChange?.(key)\n }\n\n const classes = [\n dTabs,\n variant && variantClasses[variant],\n effectiveSize && sizeClasses[effectiveSize],\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const baseId = useId()\n const activePanel = effectivePanels.find((panel) => panel._key === currentActiveKey)\n\n const tabList = (\n <div role=\"tablist\" className={classes} data-testid={getTestId('tablist')}>\n {effectivePanels.map((panel) => {\n const isActive = currentActiveKey === panel._key\n const tabId = `${baseId}-tab-${panel._key}`\n const panelId = `${baseId}-panel-${panel._key}`\n const tabClasses = [\n dTab,\n isActive && dTabActive,\n panel.disabled && dTabDisabled,\n ]\n .filter(Boolean)\n .join(' ')\n\n return (\n <button\n key={panel._key}\n role=\"tab\"\n id={tabId}\n className={tabClasses}\n onClick={() => !panel.disabled && handleTabClick(panel._key)}\n disabled={panel.disabled}\n data-state={isActive ? 'active' : 'inactive'}\n data-testid={getTestId(`tab-${panel._key}`)}\n aria-selected={isActive}\n aria-controls={panelId}\n >\n {panel.icon && <span className=\"mr-1\">{panel.icon}</span>}\n {panel.tab}\n </button>\n )\n })}\n </div>\n )\n\n const content = activePanel && (\n <div\n className={position === 'top' ? 'mt-4' : 'mb-4'}\n role=\"tabpanel\"\n id={`${baseId}-panel-${activePanel._key}`}\n aria-labelledby={`${baseId}-tab-${activePanel._key}`}\n data-testid={getTestId('tabpanel')}\n >\n {activePanel.children}\n </div>\n )\n\n return (\n <div ref={ref} data-testid={testId} {...rest}>\n {position === 'top' ? (\n <>\n {tabList}\n {content}\n </>\n ) : (\n <>\n {content}\n {tabList}\n </>\n )}\n </div>\n )\n})\n\nfunction TabPanel({ children }: TabPanelProps) {\n // This component is only used for type checking and is not rendered directly\n // The actual rendering is done in TabsRoot\n return <>{children}</>\n}\n\nexport const Tabs = Object.assign(TabsRoot, {\n Panel: TabPanel,\n})\n"],"names":["dTabs","dTabsBox","dTabsBorder","dTabsLift","dTabsXs","dTabsSm","dTabsMd","dTabsLg","dTabsXl","dTab","dTabActive","dTabDisabled","variantClasses","sizeClasses","TabsRoot","forwardRef","children","items","activeKey","defaultActiveKey","onChange","variant","size","position","testId","className","rest","ref","componentSize","useConfig","effectiveSize","getTestId","suffix","panels","React","child","TabPanel","effectivePanels","item","internalActiveKey","setInternalActiveKey","useState","currentActiveKey","handleTabClick","key","classes","baseId","useId","activePanel","panel","tabList","jsx","isActive","tabId","panelId","tabClasses","jsxs","content","Fragment","Tabs"],"mappings":";;;AAIA,MAAMA,IAAQ,QACRC,IAAW,YACXC,IAAc,eACdC,IAAY,aACZC,IAAU,WACVC,IAAU,WACVC,IAAU,WACVC,IAAU,WACVC,IAAU,WACVC,IAAO,OACPC,IAAa,cACbC,IAAe,gBA8CfC,IAA8C;AAAA,EAClD,KAAKX;AAAA,EACL,QAAQC;AAAA,EACR,MAAMC;AACR,GAEMU,KAAwC;AAAA,EAC5C,IAAIT;AAAA,EACJ,IAAIC;AAAA,EACJ,IAAIC;AAAA,EACJ,IAAIC;AAAA,EACJ,IAAIC;AACN,GAMMM,KAAWC,EAAsC,SACrD;AAAA,EACE,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,eAAeC;AAAA,EACf,WAAAC,IAAY;AAAA,EACZ,GAAGC;AACL,GACAC,GACA;AACA,QAAM,EAAE,eAAAC,EAAA,IAAkBC,EAAA,GACpBC,IAAgBR,KAASM,GAGzBG,IAAY,CAACC,MAAoBR,IAAS,GAAGA,CAAM,IAAIQ,CAAM,KAAK,QAElEC,IAASC,EAAM,SAAS,QAAQlB,CAAQ,EAC3C;AAAA,IAAO,CAACmB,MACPD,EAAM,eAAeC,CAAK,KAAKA,EAAM,SAASC;AAAA,EAAA,EAE/C,IAAI,CAACD,OAAW;AAAA,IACf,GAAGA,EAAM;AAAA,IACT,MAAMA,EAAM,OAAO,OAAO,OAAOA,EAAM,GAAG,IAAI;AAAA,EAAA,EAC9C,GAGEE,IAAwCpB,KAASA,EAAM,SAAS,IAClEA,EAAM,IAAI,CAAAqB,OAAS;AAAA,IACjB,MAAMA,EAAK;AAAA,IACX,KAAKA,EAAK;AAAA,IACV,UAAUA,EAAK;AAAA,IACf,UAAUA,EAAK;AAAA,IACf,MAAMA,EAAK;AAAA,EAAA,EACX,IACFL,GAEE,CAACM,GAAmBC,CAAoB,IAAIC;AAAA,IAChDtB,KAAoBkB,EAAgB,CAAC,GAAG,QAAQ;AAAA,EAAA,GAE5CK,IAAmBxB,MAAc,SAAYA,IAAYqB,GAEzDI,IAAiB,CAACC,MAAgB;AACtC,IAAI1B,MAAc,UAChBsB,EAAqBI,CAAG,GAE1BxB,IAAWwB,CAAG;AAAA,EAChB,GAEMC,IAAU;AAAA,IACd7C;AAAA,IACAqB,KAAWT,EAAeS,CAAO;AAAA,IACjCS,KAAiBjB,GAAYiB,CAAa;AAAA,IAC1CL;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,GAELqB,IAASC,EAAA,GACTC,IAAcX,EAAgB,KAAK,CAACY,MAAUA,EAAM,SAASP,CAAgB,GAE7EQ,IACJ,gBAAAC,EAAC,OAAA,EAAI,MAAK,WAAU,WAAWN,GAAS,eAAad,EAAU,SAAS,GACrE,UAAAM,EAAgB,IAAI,CAACY,MAAU;AAC9B,UAAMG,IAAWV,MAAqBO,EAAM,MACtCI,IAAQ,GAAGP,CAAM,QAAQG,EAAM,IAAI,IACnCK,IAAU,GAAGR,CAAM,UAAUG,EAAM,IAAI,IACvCM,IAAa;AAAA,MACjB9C;AAAA,MACA2C,KAAY1C;AAAA,MACZuC,EAAM,YAAYtC;AAAA,IAAA,EAEjB,OAAO,OAAO,EACd,KAAK,GAAG;AAEX,WACE,gBAAA6C;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,IAAIH;AAAA,QACJ,WAAWE;AAAA,QACX,SAAS,MAAM,CAACN,EAAM,YAAYN,EAAeM,EAAM,IAAI;AAAA,QAC3D,UAAUA,EAAM;AAAA,QAChB,cAAYG,IAAW,WAAW;AAAA,QAClC,eAAarB,EAAU,OAAOkB,EAAM,IAAI,EAAE;AAAA,QAC1C,iBAAeG;AAAA,QACf,iBAAeE;AAAA,QAEd,UAAA;AAAA,UAAAL,EAAM,QAAQ,gBAAAE,EAAC,QAAA,EAAK,WAAU,QAAQ,YAAM,MAAK;AAAA,UACjDF,EAAM;AAAA,QAAA;AAAA,MAAA;AAAA,MAZFA,EAAM;AAAA,IAAA;AAAA,EAejB,CAAC,EAAA,CACH,GAGIQ,IAAUT,KACd,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW5B,MAAa,QAAQ,SAAS;AAAA,MACzC,MAAK;AAAA,MACL,IAAI,GAAGuB,CAAM,UAAUE,EAAY,IAAI;AAAA,MACvC,mBAAiB,GAAGF,CAAM,QAAQE,EAAY,IAAI;AAAA,MAClD,eAAajB,EAAU,UAAU;AAAA,MAEhC,UAAAiB,EAAY;AAAA,IAAA;AAAA,EAAA;AAIjB,SACE,gBAAAG,EAAC,SAAI,KAAAxB,GAAU,eAAaH,GAAS,GAAGE,GACrC,UAAAH,MAAa,QACZ,gBAAAiC,EAAAE,GAAA,EACG,UAAA;AAAA,IAAAR;AAAA,IACAO;AAAA,EAAA,EAAA,CACH,IAEA,gBAAAD,EAAAE,GAAA,EACG,UAAA;AAAA,IAAAD;AAAA,IACAP;AAAA,EAAA,EAAA,CACH,EAAA,CAEJ;AAEJ,CAAC;AAED,SAASd,EAAS,EAAE,UAAApB,KAA2B;AAG7C,gCAAU,UAAAA,GAAS;AACrB;AAEO,MAAM2C,KAAO,OAAO,OAAO7C,IAAU;AAAA,EAC1C,OAAOsB;AACT,CAAC;"}
@@ -1,43 +1,46 @@
1
- import { jsxs as m, jsx as f } from "react/jsx-runtime";
2
- import n, { useId as u } from "react";
3
- const y = "tooltip", g = "tooltip-top", h = "tooltip-bottom", b = "tooltip-left", j = "tooltip-right", x = "tooltip-neutral", E = "tooltip-primary", I = "tooltip-secondary", N = "tooltip-accent", v = "tooltip-info", w = "tooltip-success", A = "tooltip-warning", B = "tooltip-error", C = "tooltip-open", W = ({
1
+ import { jsxs as f, jsx as u } from "react/jsx-runtime";
2
+ import e, { useId as b } from "react";
3
+ const g = "tooltip", h = "tooltip-top", x = "tooltip-bottom", B = "tooltip-left", j = "tooltip-right", E = "tooltip-neutral", I = "tooltip-primary", N = "tooltip-secondary", v = "tooltip-accent", w = "tooltip-info", A = "tooltip-success", C = "tooltip-warning", D = "tooltip-error", R = "tooltip-open", $ = ({
4
4
  children: o,
5
- tip: t,
6
- className: p = "",
7
- position: c = "top",
8
- color: i,
9
- open: s = !1,
10
- ...e
5
+ tip: i,
6
+ className: c = "",
7
+ position: p = "top",
8
+ color: s,
9
+ open: l = !1,
10
+ ...r
11
11
  }) => {
12
- const l = u(), r = {
13
- top: g,
14
- bottom: h,
15
- left: b,
12
+ const t = b(), a = {
13
+ top: h,
14
+ bottom: x,
15
+ left: B,
16
16
  right: j
17
- }, a = i ? {
18
- neutral: x,
19
- primary: E,
20
- secondary: I,
21
- accent: N,
22
- info: v,
23
- success: w,
24
- warning: A,
25
- error: B
26
- }[i] : void 0, d = [
27
- y,
28
- r[c],
29
- a,
30
- s && C,
31
- p
32
- ].filter(Boolean).join(" "), T = n.isValidElement(o) ? n.cloneElement(o, {
33
- "aria-describedby": l
34
- }) : o;
35
- return /* @__PURE__ */ m("div", { className: d, "data-tip": t, "data-state": s ? "open" : "closed", ...e, children: [
36
- T,
37
- /* @__PURE__ */ f("span", { id: l, role: "tooltip", className: "sr-only", children: t })
17
+ }, d = s ? {
18
+ neutral: E,
19
+ primary: I,
20
+ secondary: N,
21
+ accent: v,
22
+ info: w,
23
+ success: A,
24
+ warning: C,
25
+ error: D
26
+ }[s] : void 0, T = [
27
+ g,
28
+ a[p],
29
+ d,
30
+ l && R,
31
+ c
32
+ ].filter(Boolean).join(" "), m = e.isValidElement(o) ? (() => {
33
+ const n = o.props["aria-describedby"], y = n ? `${n} ${t}` : t;
34
+ return e.cloneElement(o, {
35
+ "aria-describedby": y
36
+ });
37
+ })() : o;
38
+ return /* @__PURE__ */ f("div", { className: T, "data-tip": i, "data-state": l ? "open" : "closed", ...r, children: [
39
+ m,
40
+ /* @__PURE__ */ u("span", { id: t, role: "tooltip", className: "sr-only", children: i })
38
41
  ] });
39
42
  };
40
43
  export {
41
- W as Tooltip
44
+ $ as Tooltip
42
45
  };
43
46
  //# sourceMappingURL=Tooltip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useId } from 'react'\n\n// DaisyUI classes\nconst dTooltip = 'tooltip'\nconst dTooltipTop = 'tooltip-top'\nconst dTooltipBottom = 'tooltip-bottom'\nconst dTooltipLeft = 'tooltip-left'\nconst dTooltipRight = 'tooltip-right'\nconst dTooltipNeutral = 'tooltip-neutral'\nconst dTooltipPrimary = 'tooltip-primary'\nconst dTooltipSecondary = 'tooltip-secondary'\nconst dTooltipAccent = 'tooltip-accent'\nconst dTooltipInfo = 'tooltip-info'\nconst dTooltipSuccess = 'tooltip-success'\nconst dTooltipWarning = 'tooltip-warning'\nconst dTooltipError = 'tooltip-error'\nconst dTooltipOpen = 'tooltip-open'\n\nexport interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n tip: string\n position?: 'top' | 'bottom' | 'left' | 'right'\n color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\n open?: boolean\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport const Tooltip: React.FC<TooltipProps> = ({\n children,\n tip,\n className = '',\n position = 'top',\n color,\n open = false,\n ...rest\n}) => {\n const tooltipId = useId()\n\n const positionClasses = {\n top: dTooltipTop,\n bottom: dTooltipBottom,\n left: dTooltipLeft,\n right: dTooltipRight,\n }\n\n const colorClasses = color\n ? {\n neutral: dTooltipNeutral,\n primary: dTooltipPrimary,\n secondary: dTooltipSecondary,\n accent: dTooltipAccent,\n info: dTooltipInfo,\n success: dTooltipSuccess,\n warning: dTooltipWarning,\n error: dTooltipError,\n }[color]\n : undefined\n\n const classes = [\n dTooltip,\n positionClasses[position],\n colorClasses,\n open && dTooltipOpen,\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n // Clone children to add aria-describedby\n const childWithAria = React.isValidElement(children)\n ? React.cloneElement(children as React.ReactElement<{ 'aria-describedby'?: string }>, {\n 'aria-describedby': tooltipId,\n })\n : children\n\n return (\n <div className={classes} data-tip={tip} data-state={open ? 'open' : 'closed'} {...rest}>\n {childWithAria}\n {/* Screen reader accessible tooltip text */}\n <span id={tooltipId} role=\"tooltip\" className=\"sr-only\">\n {tip}\n </span>\n </div>\n )\n}\n"],"names":["dTooltip","dTooltipTop","dTooltipBottom","dTooltipLeft","dTooltipRight","dTooltipNeutral","dTooltipPrimary","dTooltipSecondary","dTooltipAccent","dTooltipInfo","dTooltipSuccess","dTooltipWarning","dTooltipError","dTooltipOpen","Tooltip","children","tip","className","position","color","open","rest","tooltipId","useId","positionClasses","colorClasses","classes","childWithAria","React","jsxs","jsx"],"mappings":";;AAGA,MAAMA,IAAW,WACXC,IAAc,eACdC,IAAiB,kBACjBC,IAAe,gBACfC,IAAgB,iBAChBC,IAAkB,mBAClBC,IAAkB,mBAClBC,IAAoB,qBACpBC,IAAiB,kBACjBC,IAAe,gBACfC,IAAkB,mBAClBC,IAAkB,mBAClBC,IAAgB,iBAChBC,IAAe,gBAYRC,IAAkC,CAAC;AAAA,EAC9C,UAAAC;AAAA,EACA,KAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAYC,EAAA,GAEZC,IAAkB;AAAA,IACtB,KAAKvB;AAAA,IACL,QAAQC;AAAA,IACR,MAAMC;AAAA,IACN,OAAOC;AAAA,EAAA,GAGHqB,IAAeN,IACjB;AAAA,IACE,SAASd;AAAA,IACT,SAASC;AAAA,IACT,WAAWC;AAAA,IACX,QAAQC;AAAA,IACR,MAAMC;AAAA,IACN,SAASC;AAAA,IACT,SAASC;AAAA,IACT,OAAOC;AAAA,EAAA,EACPO,CAAK,IACP,QAEEO,IAAU;AAAA,IACd1B;AAAA,IACAwB,EAAgBN,CAAQ;AAAA,IACxBO;AAAA,IACAL,KAAQP;AAAA,IACRI;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,GAGLU,IAAgBC,EAAM,eAAeb,CAAQ,IAC/Ca,EAAM,aAAab,GAAiE;AAAA,IAClF,oBAAoBO;AAAA,EAAA,CACrB,IACDP;AAEJ,SACE,gBAAAc,EAAC,OAAA,EAAI,WAAWH,GAAS,YAAUV,GAAK,cAAYI,IAAO,SAAS,UAAW,GAAGC,GAC/E,UAAA;AAAA,IAAAM;AAAA,IAED,gBAAAG,EAAC,UAAK,IAAIR,GAAW,MAAK,WAAU,WAAU,WAC3C,UAAAN,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}
1
+ {"version":3,"file":"Tooltip.js","sources":["../../src/components/Tooltip.tsx"],"sourcesContent":["import React, { useId } from 'react'\n\n// DaisyUI classes\nconst dTooltip = 'tooltip'\nconst dTooltipTop = 'tooltip-top'\nconst dTooltipBottom = 'tooltip-bottom'\nconst dTooltipLeft = 'tooltip-left'\nconst dTooltipRight = 'tooltip-right'\nconst dTooltipNeutral = 'tooltip-neutral'\nconst dTooltipPrimary = 'tooltip-primary'\nconst dTooltipSecondary = 'tooltip-secondary'\nconst dTooltipAccent = 'tooltip-accent'\nconst dTooltipInfo = 'tooltip-info'\nconst dTooltipSuccess = 'tooltip-success'\nconst dTooltipWarning = 'tooltip-warning'\nconst dTooltipError = 'tooltip-error'\nconst dTooltipOpen = 'tooltip-open'\n\nexport interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode\n tip: string\n position?: 'top' | 'bottom' | 'left' | 'right'\n color?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'\n open?: boolean\n /** Test ID for testing */\n 'data-testid'?: string\n}\n\nexport const Tooltip: React.FC<TooltipProps> = ({\n children,\n tip,\n className = '',\n position = 'top',\n color,\n open = false,\n ...rest\n}) => {\n const tooltipId = useId()\n\n const positionClasses = {\n top: dTooltipTop,\n bottom: dTooltipBottom,\n left: dTooltipLeft,\n right: dTooltipRight,\n }\n\n const colorClasses = color\n ? {\n neutral: dTooltipNeutral,\n primary: dTooltipPrimary,\n secondary: dTooltipSecondary,\n accent: dTooltipAccent,\n info: dTooltipInfo,\n success: dTooltipSuccess,\n warning: dTooltipWarning,\n error: dTooltipError,\n }[color]\n : undefined\n\n const classes = [\n dTooltip,\n positionClasses[position],\n colorClasses,\n open && dTooltipOpen,\n className,\n ]\n .filter(Boolean)\n .join(' ')\n\n // Clone children to add aria-describedby without clobbering existing values\n const childWithAria = React.isValidElement(children)\n ? (() => {\n const existingDescribedBy = (children.props as { 'aria-describedby'?: string })['aria-describedby']\n const mergedDescribedBy = existingDescribedBy ? `${existingDescribedBy} ${tooltipId}` : tooltipId\n return React.cloneElement(children as React.ReactElement<{ 'aria-describedby'?: string }>, {\n 'aria-describedby': mergedDescribedBy,\n })\n })()\n : children\n\n return (\n <div className={classes} data-tip={tip} data-state={open ? 'open' : 'closed'} {...rest}>\n {childWithAria}\n {/* Screen reader accessible tooltip text */}\n <span id={tooltipId} role=\"tooltip\" className=\"sr-only\">\n {tip}\n </span>\n </div>\n )\n}\n"],"names":["dTooltip","dTooltipTop","dTooltipBottom","dTooltipLeft","dTooltipRight","dTooltipNeutral","dTooltipPrimary","dTooltipSecondary","dTooltipAccent","dTooltipInfo","dTooltipSuccess","dTooltipWarning","dTooltipError","dTooltipOpen","Tooltip","children","tip","className","position","color","open","rest","tooltipId","useId","positionClasses","colorClasses","classes","childWithAria","React","existingDescribedBy","mergedDescribedBy","jsxs","jsx"],"mappings":";;AAGA,MAAMA,IAAW,WACXC,IAAc,eACdC,IAAiB,kBACjBC,IAAe,gBACfC,IAAgB,iBAChBC,IAAkB,mBAClBC,IAAkB,mBAClBC,IAAoB,qBACpBC,IAAiB,kBACjBC,IAAe,gBACfC,IAAkB,mBAClBC,IAAkB,mBAClBC,IAAgB,iBAChBC,IAAe,gBAYRC,IAAkC,CAAC;AAAA,EAC9C,UAAAC;AAAA,EACA,KAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAYC,EAAA,GAEZC,IAAkB;AAAA,IACtB,KAAKvB;AAAA,IACL,QAAQC;AAAA,IACR,MAAMC;AAAA,IACN,OAAOC;AAAA,EAAA,GAGHqB,IAAeN,IACjB;AAAA,IACE,SAASd;AAAA,IACT,SAASC;AAAA,IACT,WAAWC;AAAA,IACX,QAAQC;AAAA,IACR,MAAMC;AAAA,IACN,SAASC;AAAA,IACT,SAASC;AAAA,IACT,OAAOC;AAAA,EAAA,EACPO,CAAK,IACP,QAEEO,IAAU;AAAA,IACd1B;AAAA,IACAwB,EAAgBN,CAAQ;AAAA,IACxBO;AAAA,IACAL,KAAQP;AAAA,IACRI;AAAA,EAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,GAGLU,IAAgBC,EAAM,eAAeb,CAAQ,KAC9C,MAAM;AACL,UAAMc,IAAuBd,EAAS,MAA0C,kBAAkB,GAC5Fe,IAAoBD,IAAsB,GAAGA,CAAmB,IAAIP,CAAS,KAAKA;AACxF,WAAOM,EAAM,aAAab,GAAiE;AAAA,MACzF,oBAAoBe;AAAA,IAAA,CACrB;AAAA,EACH,OACAf;AAEJ,SACE,gBAAAgB,EAAC,OAAA,EAAI,WAAWL,GAAS,YAAUV,GAAK,cAAYI,IAAO,SAAS,UAAW,GAAGC,GAC/E,UAAA;AAAA,IAAAM;AAAA,IAED,gBAAAK,EAAC,UAAK,IAAIV,GAAW,MAAK,WAAU,WAAU,WAC3C,UAAAN,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;"}